공공데이터 포털 : https://www.data.go.kr/
파싱(parsing) : 문자열데이터를 분석하고 분해하여 목적한 패턴에 맞게 문자열의 구조를 결정하는 것
기본적으로 xml파일은 html태그와 비슷함
html 태그는 시작태그만 존재하는것도 있지만(ex-input태그) xml은 무조건 끝 태그가 함께 있음
html 태그는 정해져있는 태그만 써야되지만 xml은 사용자가 태그의 종류를 정할 수 있음.
활용가이드 참고
xml 파싱으로 위해서는 build.gradle에 라이브러리 추가해줘야함
// java에서 xml 파일을 파싱하기 위해서 사용하는 라이브러리
// https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3'
// https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl
implementation 'com.sun.xml.bind:jaxb-impl:2.3.3'
다운받은 xml 파일의 태그 양식대로 Dto 파일을 만들어 주어야 함
controller 패키지 내부에 PharmacyController.java 파일 생성
package com.bitc.xmltest.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class PharmacyController {
@RequestMapping("/")
public String index() throws Exception {
return "index";
}
}
templates 패키지 내부에 index.html 파일 생성 (정상적으로 서버 통신이 되는지 테스트용)
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/css/bootstrap.css" th:href="@{/css/bootstrap.css}">
<script src="/js/jquery-3.6.1.js" th:src="@{/js/jquery-3.6.1.js}"></script>
<script src="/js/bootstrap.bundle.js" th:src="@{/js/bootstrap.bundle.js}"></script>
</head>
<body>
<h1>xml 파싱 테스트</h1>
</body>
</html>
Dto 파일 생성 후 Service 인터페이스 및 클래스 생성
html파일 생성 후 테스트
<p th:text="${pharmacyDatas}"></p>
컨트롤러의 fullData -> fullDataFile로 변경
컨트롤러 코드 추가
@RequestMapping(value = "/pharmacy/fullDataUrl", method = RequestMethod.GET)
public String viewFullData() throws Exception {
return "pharmacy/fullDataUrl";
}
@RequestMapping(value = "/pharmacy/fullDataUrl", method = RequestMethod.POST)
public Object getFullDataAjax() throws Exception {
return "";
}
fullDataUrl.html 생성(pharmacy 폴더)
html파일도 이름 변경
PharmacyController.java
jaxb
: 자바에서 xml 데이터 파싱을 도와주는 라이브러리
Marshal(마샬)
: 자바 클래스를 xml 데이터로 변환
UnMarshal(언마샬)
: xml 데이터를 자바 클래스 타입의 객체(Object)로 변환
@ XmlRootElement
: xml 데이터에서 부모가 되는 태그를 뜻함
@ XmlElement
: xml 데이터에서 실제 데이터가 들어있는 태그를 뜻함
@ XmlAttribute
: xml 데이터에서 지정한 태그의 속성을 뜻함
PharmacyFullDataDto.java
@ XmlRootElement(name = "태그 A")
: name="" 속의 태그를 부모 태그로 정하겠다는 의미@XmlElement(name = "태그 A-1")
:@ XmlRootElement(name = "태그 A")
에 선언된 부모태그(A
)에@XmlElement
로 선언된태그 A-1
을 연결하겠다는 의미
PharmacyFullDataServiceImpl.java
- JAXB 라이브러리 사용 선언 : 싱글톤 방식으로 동작됨, PharmacyFullDataDto 클래스 타입으로 xml 데이터를 파싱
JAXBContext jc = JAXBContext.newInstance(PharmacyFullDataDto.class);
- UnMarshal(언마샬) : xml 데이터를 자바 클래스 타입의 객체(Object)로 변환.
JAXB 라이브러리를 사용하여 XML 데이터를 자바 클래스 타입의 객체로 변환하는 언마샬 객체를 생성Unmarshaller um = jc.createUnmarshaller();
- 기존에 제공된 xml 데이터를 기반으로 PharmacyFullDataDto 클래스의 객체를 생성하므로 xml 데이터를 파싱하여 가져온 데이터를 PharmacyFullDataDto 클래스 타입의 객체 fullData 에 형변환 하여 저장
PharmacyFullDataDto fullData = (PharmacyFullDataDto) um.unmarshal(new File("C://java505//pharmacy.xml")); PharmacyFullDataHeaderDto header = fullData.getHeader(); PharmacyFullDataBodyDto body = fullData.getBody(); PharmacyFullDataItemsDto items = body.getItems();
fullDataUrl.html
원하는 데이터 가져오기 : input 태그의 id를 컨트롤러에서 @RequestParam 으로 받는다
fullDataUrl.html<label for="pageNo">페이지 번호</label> <input type="text" id="pageNo" placeholder="페이지번호">
PharmacyController.java
@ResponseBody @RequestMapping(value = "/pharmacy/fullDataUrl", method = RequestMethod.POST) public Object getFullDataAjax(@RequestParam("pageNo") int pageNo, @RequestParam("itemQty") int itemQty) throws Exception { ... }
BoxOfficeServiceImpl.java
StringBuilder
: 문자열을 효과적으로 사용하기 위한 클래스이다.
문자열은 연결 연산자 사용시str1 = "문자열"
,str2 = "만들기"
→str1 + str2
→
str2의 데이터
가str1
로 들어가서 합쳐지는게 아니라 새로운 문자열(새로운 메모리 영역)이 생성되는 것이다
→ 신규 문자열에 "문자열 만들기"가 들어가고, 신규 문자열이 출력되는것임
하지만StringBuilder
로 선언된sb
는 한번 만들어지면 해당 변수에append
를 통해 원본 그대로에 계속 문자열을 붙여서 사용하는것임. 좀 더 효율이 높다!StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); }
- Gson 객체 사용
Gson gson = new Gson();
- Gson을 통해서 가져온 데이터를 BoxOffice 클래스 타입으로 변환
여러 문자열들이 append를 통해 추가된 sb를 toString()을 통해 실제 문자열로 바꿔줌BoxOffice boxOffice = gson.fromJson(sb.toString(), BoxOffice.class);