티스토리 뷰
이전에는 xml의 구성만 살펴보았다면 오늘은 이클립스에서 xml 파일을 불러와 출력하는 것을 해보았다.
먼저 url을 통해 xml 을 불러 오기 위해 url 을 조립한다.
StringBuilder를 사용해 외부 api의 url을 조립했다.
이전에 보았던 변수들과 분류 코드들을 참고하여 특정 값만 볼 수 있도록 &변수명=값 과 같은 형태로 append해준다.
그럼 파라미터가 url에 추가된다.
StringBuilder urlBuilder = new StringBuilder("https://apis.data.go.kr/B551182/hospInfoServicev2/getHospBasisList");
urlBuilder.append("?ServiceKey=인증key");
urlBuilder.append("&numOfRows=10");
urlBuilder.append("&dgsbjtCd=05");
urlBuilder.append("&page=" + page);
//이후 원하는 값이 있으면 해당 변수에 대한 것을 작성
API를 호출한다. HttpURLConnection을 사용해 조립한 url로 api에 요청을 보낸다.
응답 코드를 확인한 후 응답 스트림을 SAXBuilider를 사용해 xml 문서로 파싱해준다.
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "application/xml");
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(conn.getInputStream());
Element root = document.getRootElement();
List xmlelement = root.getChildren();
Iterator it = xmlelement.iterator();
정상적으로 파일을 가지고온다면 위와 같이 200번 코드가 발생하여 출력된다.
다음으로 XML 파싱을 한다.
JDOM 라이브러리를 사용해 xml 문서를 파싱한다.
xml 구성이 <header> <body> <items> 로 이루어져 있었기 때문에 아래와 같이 엘리먼트를 가져온다.
List<Element> headerList = null;
List<Element> bodyList = null;
List<Element> itemsList = null;
while (it.hasNext()) {
Element e = (Element) it.next();
if ("header".equals(e.getName())) {
headerList = e.getChildren();
}
if ("body".equals(e.getName())) {
bodyList = e.getChildren();
}
if ("items".equals(e.getName())) {
itemsList = e.getChildren();
}
}
다음으로 데이터를 추출한다.
헤더와 바디의 데이터를 추출하고 태그 안에 여러개가 존재할 수 있으므로 iterator 를 사용하여 반복 작업을 한다.
System.out.println("<header>");
Iterator headerIt = headerList.iterator();
while(headerIt.hasNext()) {
Element e = (Element)headerIt.next();
System.out.println(e.getName()+" : "+e.getValue());
}
System.out.println("<body>");
Iterator bodyIt = bodyList.iterator();
while(bodyIt.hasNext()) {
Element e = (Element)bodyIt.next();
System.out.println(e.getName()+" : "+e.getValue());
if(e.getName()=="items") {
itemsList = e.getChildren();
}
}
<items> 아래 <item>에서 병원 정보를 추출하고 이것을 dataList에 저장했다.
<items>아래에는 여러개의 <item>이 존재하기 때문에
Map<String, String> dataMap = new HashMap<>();을 통해 각 각의 <item> 요소마다 새로운 Map을 생성하도록 작성했다.
List<Map<String, String>> dataList = new ArrayList<>();
System.out.println("<items>");
Iterator itemsIt = itemsList.iterator();
while (itemsIt.hasNext()) {
Element e = (Element) itemsIt.next();
System.out.println(e.getName() + " : " + e.getValue());
if ("item".equals(e.getName())) {
itemList = e.getChildren();
Map<String, String> dataMap = new HashMap<>(); // 각각의 <item> 요소마다 새로운 Map을 생성
for (Element itemElement : itemList) {
System.out.println(itemElement.getName() + " : " + itemElement.getValue());
dataMap.put(itemElement.getName(), itemElement.getValue());
}
dataList.add(dataMap);
}
}
이후 모델에 데이터를 전달하여 dataList를 model 객체에 저장하여 뷰로 전달했다.
int totalItemCount = Integer.parseInt(root.getChild("body")
.getChild("totalCount")
.getValue());
model.addAttribute("totalItemCount", totalItemCount);
model.addAttribute("dataList", dataList);
마지막으로 뷰 호출을 하여 이동했다.
return "/Hospital/index";
System.out.println으로 콘솔에 출력한 값들이다.
응답코드가 200으로 정상적으로 가지고 오는 것을 확인하고
Header 값과 body 값 그리고 items 값과 item 요소들을 출력한 것을 볼 수 있다.
뷰페이지는 아래와 같이 작성되었다.
dataMap에서 원하는 값들만 el을 사용하여 출력해주고 있는 코드이다.
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!-- form 사용을 위한 선언 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="<c:url value="/resources/css/bootstrap.min.css"/>"rel="stylesheet" />
<script src="${pageContext.request.contextPath }/resources/js/controllers.js"></script>
<!-- 스크립트 사용을 위해 선언 -->
<title>병원 정보</title>
</head>
<body>
<h1>Result Page</h1>
<c:forEach items="${dataList}" var="dataMap">
<div>
<p>-----------------------------------</p>
<!-- 필요한 내용 출력 -->
<p>병원명 : ${dataMap.yadmNm }
<p>주소 : ${dataMap.addr}</p>
<p>병원종류 : ${dataMap.clCdNm}</p>
<p>전화번호 : ${dataMap.telno}</p>
</div>
</c:forEach>
<div>
<!-- 페이지 전환을 위한 링크 -->
<c:if test="${page > 1}">
<a href="/sample?page=${page - 1}">이전 페이지</a>
</c:if>
<span>현재 페이지: ${page}</span>
<c:if test="${page > 1}">
<a href="${pageContext.request.contextPath}/sample?page=${page - 1}">이전 페이지</a>
</c:if>
<c:if test="${page * 10 < totalItemCount}">
<a href="${pageContext.request.contextPath}/sample?page=${page + 1}">다음 페이지</a>
</c:if>
</div>
</body>
</html>
뷰 페이지로 이동한 후 출력된 값이다.
다시 또 생각해봐야할 점
1. 병원의 수가 약 12240개로 너무 방대하다. 이것을 줄일 필요가 있음 (의논 후 얼마나,어떤 기준으로 줄일 것인지 결정)
2. 수가 많은 만큼 api가 페이지로 나누어져있는데 페이지 호출에대한 문제가 있다.
다음 누르면 2페이지의 정보들을 가져오도록 변경해주어야한다.
'코딩 > spring' 카테고리의 다른 글
[22주 2일차] 스프링 시작페이지 설정 (0) | 2024.03.05 |
---|---|
[22주 1일차] API 정보를 db에 저장 & 페이징 (0) | 2024.03.04 |
[21주 4일차] 공공데이터포털 API 사용하기 (0) | 2024.02.29 |
[21주 3일차] 회원가입시 카카오톡 주소 사용하기 (0) | 2024.02.28 |
[21주 2일차] 프로젝트 (1) | 2024.02.27 |
- Total
- Today
- Yesterday