본문 바로가기
Spring

공공데이터포탈 Open API 사용방법!!

by GoodDayDeveloper 2021. 6. 16.
반응형

 

안녕하세요. 오늘은 공공데이터 OPEN API 사용하는 방법에 대해 이야기해보겠습니다.

 

 

공공데이터포털이란 

공공데이터포털은 행정안전부에서 운영하는 공공데이터 통합제공 시스템이다. 대한민국 정부가 보유한 다양한 공공데이터를 개방하여 누구나 편리하고 손쉽게 활용할 수 있게 하는 것을 목적으로 한다. 행정안전부 공공데이터정책과에서 관련 정책을 추진하고 있다.

즉 나라에서 보유한 데이터를 여러 형태로 사용할 수 있는 친절한 서비스인거죠!

 

 

 

그럼 API는 무엇일까요?

API(Application Programming Interface 애플리케이션 프로그래밍 인터페이스, 응용 프로그램 프로그래밍 인터페이스)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

쉽게 설명하면 누군가가 만든 프로그램을 사용하는 것을 말하죠..

즉 공공데이터API란 나라에서 보유한 데이터 프로그램을 허가를 받아 각자의 인증키로 사용할 수 있는 것을 뜻합니다!

 

 

 

 

실무에서도 굉장히 많이 사용되고 있고, 회사 면접 시에도 공공데이터 사용여부에 대해 많이들 물어본다고 하네요.

개발자라면 반드시 알아야할 사항 중 하나가 아닐까 생각됩니다! 

차근차근 확인해보도록 하죠!

 

 


 

 

 

 

우선 공공데이터포털사이트로 접속합니다.

https://data.go.kr/

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

 

 

 

 

 

 

사이트를 이용하려면 당연히 회원가입을 하고 로그인이 필요합니다. 두개 다 해주도록 합니다.

 

 

 

 

 

저는 주소코드를 통한 개별공시지가를 얻으려합니다.

"국토교통부_개별공시지가정보서비스" 라고 검색창에 검색하고 오픈 API 창을 클릭해줍니다.

 

 

 

 

 

빨간줄이 쳐져있는 녀석을 이용할 예정입니다.

 

 

 

 

 

 

클릭해서 들어가게되면 해당 API에 관한 정보들이 나오게 됩니다.

여기서 이용하려면 활용신청을 누르면 됩니다.

 

 

 

 

 

 

활용목적을 간단히 써주시고 이용허락범위에 동의한 다음 활용신청을 누릅니다.

 

 

 

 

 

 

그럼 신청과 1~2시간 후 호출이 가능하다는 메세지가 나옵니다.

실제 테스트를 하려면 1~2시간은 아니더라도 30분정도 후에 테스트가 가능합니다.

 

 

 

 

 

 

 

마이페이지에 가보게 되면 신청한 건에 대한 리스트를 볼 수 있습니다.

 

 

 

 

 

 

 

 

해당 신청한 API를 누르게 되면 개발계정 상세보기 화면이 나타납니다.

여기서 일반 인증키를 사용하면 됩니다.

그리고 활용신청 상세기능 정보에서 미리보기를 통해 테스트를 해보실 수 있습니다.

 

 

 

 

 

 

확인을 누르게 되면 요청변수를 입력하는 창이 열리게 됩니다.

여기서 각 필요로 하는 파라미터 값을 넣어준 다음 미리보기를 눌러 값을 확인합니다.

URL을 보시면 주소에서 URL + 서비스키 + 각각의 파라미터가 붙는것을 알 수 있습니다.

그리고 거기에 대한 값을 XML 형식으로 보여주게 됩니다.

즉 URL은 : http://apis.data.go.kr/1611000/nsdi/IndvdLandPriceService/attr/getIndvdLandPriceAttr

service키는 일반인증키가 되겠네요!

 

 

 

 

 

 

 

 

상세내용은 개발계정 상세보기에서 참고문서 압축파일을 풀면 자세하게 가이드가 나옵니다.

 

 

 

 

 

 

 

 

 

요청메세지 항목을 저렇게 넣어주면

 

 

 

 

 

 

 

아래와 같이 응답이 온다는 내용입니다.

 

 

 

 

 

 

값을 넣어주면 url과 서비스 인증키와 파라미터를 타고 아래와 같이 응답메세지가 나오게 됩니다.

 

 

반응형

 

 

 

Controller

 

그리고 사용할 컨트롤러 밑에 아래의 소스를 붙여줍니다.

위에 두번째 줄까지는 저의 상황에 맡게 사용되었지만 인증키입력부터는 일반적으로 사용되니

입맛에 맛게 값을 넣어주시면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//리스트의 첫번째 인덱스 row만 가져와서
tbl_individualVO plist2 =  plist.get(0);
 
//변수pnu_code에 넣어줍니다.
String pnu_code = plist2.getPnu_code();
    
 
//변수 serviceKey에 인증키를 넣어주고
String serviceKey = "인증키입력";
 
//각각의 정보를 넣어줍니다.
StringBuilder urlBuilder = new StringBuilder("url주소 입력"); /* URL */
urlBuilder.append("?" + URLEncoder.encode("ServiceKey""UTF-8"+ "=" + serviceKey); /* Service Key */
urlBuilder.append("&" + URLEncoder.encode("pnu""UTF-8"+ "=" + URLEncoder.encode(pnu_code, "UTF-8")); /* pnu_code */
urlBuilder.append("&" + URLEncoder.encode("stdrYear""UTF-8"+ "=" + URLEncoder.encode("2020""UTF-8")); /* year */
urlBuilder.append("&" + URLEncoder.encode("format""UTF-8"+ "=" + URLEncoder.encode("xml""UTF-8")); /* 요청자료형식(XML/JSON)Default: XML */
urlBuilder.append("&" + URLEncoder.encode("numOfRows""UTF-8"+ "=" + URLEncoder.encode("5""UTF-8")); /* page 출력 수 */
urlBuilder.append("&" + URLEncoder.encode("pageNo""UTF-8"+ "=" + URLEncoder.encode("1""UTF-8")); /* 페이지 번호 */
 
//나중에 사용할 map을 선언해줍니다.
Map<String, Object> map = new HashMap<String, Object>();
 
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type""application/json");
System.out.println("Response code: " + conn.getResponseCode());
BufferedReader rd;
 
//getResponseCode가 200이상 300이하일때는 정상적으로 작동합니다.
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
else {
    rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
 
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
rd.close();
conn.disconnect();
url =null;
//StringBuilder로 위에 파라미터 더 한값을 toString으로 불러옵니다.
//그리고 println으로 확인을 하면 xml형식이 나오게됩니다.
System.out.println(sb.toString());
cs

 

 

 

 

 

 

그럼 아래와 같은 xml형식의 값이 나오게 됩니다.

 

 

 

 

 

 

그리고 결과값을 뽑아주는 getResultMap이라는 함수를 만들어줍니다.

xml을Xpath를 이용하여 데이터를 취득하는 방법입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static List<HashMap<StringString>> getResultMap(String data) throws Exception {
 
//결과값을 넣어줄 map을 선언해줍니다.
List<HashMap<StringString>> resultMap = new LinkedList<HashMap<StringString>>();
        
InputSource is = new InputSource(new StringReader(data));
 
//Document 클래스로 xml데이터를 취득합니다.
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
 
//xPath 팩토리로 객체를 만듭니다.
XPath xpath = XPathFactory.newInstance().newXPath();
 
//xPath를 컴파일한 후에 node단위로 데이터를 수집합니다.
NodeList nodeList = (NodeList) xpath.compile("/response/fields/field").evaluate(document, XPathConstants.NODESET);
int nodeListCount = nodeList.getLength();
for (int i = 0; i < nodeListCount; i++) {
    NodeList childNode = nodeList.item(i).getChildNodes();
    HashMap<StringString> nodeMap = new HashMap<StringString>();
    int childNodeCount = childNode.getLength();
    for (int j = 0; j < childNodeCount; j++) {
        nodeMap.put(childNode.item(j).getNodeName(), childNode.item(j).getTextContent());
    }
    resultMap.add(nodeMap);
}
cs

 

 

 

 

 

 

여기서 중요한 것은 xpath에서 compile 위치가 왜 "/response/fields/field" 인가 입니다.

xml데이터를 잘 보시면 태그별로 나눠져 있는것을 알 수 있습니다.

뽑아낼 데이터를 찾기 위해 위치를 찾아내는 겁니다.

 

예를 들어 저는 가격 부분인 pblntfPclnd를 뽑고 싶다면,

가장 위에 태그인 response,

그 다음 태그인 fields,

그 다음 태그인 field 

즉, pblntfPclnd를 찾기 위해 /response/fields/field 위치를 찾아주는 겁니다.

 

 

 

 

 

그리고 url를 선언했던 컨트롤러로 돌아와서 url 선언 밑에 추가로 코드를 작성해줍니다.

 

getResultMap에 값을 집어 넣고

for문을 통해서 결과값을 map에 넣어주는데 우리가 찾고자 했던 pblntfPclnd을 price라는 객체에 넣어줍니다.

그리고 model를 통해서 price라는 값으로 view로 내보내면 됩니다.

1
2
3
4
5
6
7
List<HashMap<StringString>> list = getResultMap(sb.toString());
 
for(Map<String,String> tmpMap : list) {
    map.put("price", tmpMap.get("pblntfPclnd"));
}
 
model.addAttribute("price", map.get("price"));
cs

 

 

 

 

 

 

자바 전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//리스트의 첫번째 인덱스 row만 가져와서
tbl_individualVO plist2 =  plist.get(0);
 
//변수pnu_code에 넣어줍니다.
String pnu_code = plist2.getPnu_code();
    
 
//변수 serviceKey에 인증키를 넣어주고
String serviceKey = "인증키입력";
 
//각각의 정보를 넣어줍니다.
StringBuilder urlBuilder = new StringBuilder("url주소 입력"); /* URL */
urlBuilder.append("?" + URLEncoder.encode("ServiceKey""UTF-8"+ "=" + serviceKey); /* Service Key */
urlBuilder.append("&" + URLEncoder.encode("pnu""UTF-8"+ "=" + URLEncoder.encode(pnu_code, "UTF-8")); /* pnu_code */
urlBuilder.append("&" + URLEncoder.encode("stdrYear""UTF-8"+ "=" + URLEncoder.encode("2020""UTF-8")); /* year */
urlBuilder.append("&" + URLEncoder.encode("format""UTF-8"+ "=" + URLEncoder.encode("xml""UTF-8")); /* 요청자료형식(XML/JSON)Default: XML */
urlBuilder.append("&" + URLEncoder.encode("numOfRows""UTF-8"+ "=" + URLEncoder.encode("5""UTF-8")); /* page 출력 수 */
urlBuilder.append("&" + URLEncoder.encode("pageNo""UTF-8"+ "=" + URLEncoder.encode("1""UTF-8")); /* 페이지 번호 */
 
//나중에 사용할 map을 선언해줍니다.
Map<String, Object> map = new HashMap<String, Object>();
 
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type""application/json");
System.out.println("Response code: " + conn.getResponseCode());
BufferedReader rd;
 
//getResponseCode가 200이상 300이하일때는 정상적으로 작동합니다.
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
else {
    rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
 
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
rd.close();
conn.disconnect();
url =null;
//StringBuilder로 위에 파라미터 더 한값을 toString으로 불러옵니다.
//그리고 println으로 확인을 하면 xml형식이 나오게됩니다.
System.out.println(sb.toString());
 
 
 
List<HashMap<StringString>> list = getResultMap(sb.toString());
 
for(Map<String,String> tmpMap : list) {
    map.put("price", tmpMap.get("pblntfPclnd"));
}
 
model.addAttribute("price", map.get("price"));
 
 
 
 
 
 
public static List<HashMap<StringString>> getResultMap(String data) throws Exception {
 
//결과값을 넣어줄 map을 선언해줍니다.
List<HashMap<StringString>> resultMap = new LinkedList<HashMap<StringString>>();
        
InputSource is = new InputSource(new StringReader(data));
 
//Document 클래스로 xml데이터를 취득합니다.
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
 
//xPath 팩토리로 객체를 만듭니다.
XPath xpath = XPathFactory.newInstance().newXPath();
 
//xPath를 컴파일한 후에 node단위로 데이터를 수집합니다.
NodeList nodeList = (NodeList) xpath.compile("/response/fields/field").evaluate(document, XPathConstants.NODESET);
int nodeListCount = nodeList.getLength();
for (int i = 0; i < nodeListCount; i++) {
    NodeList childNode = nodeList.item(i).getChildNodes();
    HashMap<StringString> nodeMap = new HashMap<StringString>();
    int childNodeCount = childNode.getLength();
    for (int j = 0; j < childNodeCount; j++) {
        nodeMap.put(childNode.item(j).getNodeName(), childNode.item(j).getTextContent());
    }
    resultMap.add(nodeMap);
}
 
return resultMap;
}
 
 
 
cs

 

 

 

 

 

JSP

 

그리고 jsp에서 number 타입으로 빼주면 완료됩니다.

1
<li>개별공시지가 : <fmt:formatNumber value="${price}" type="number" /></li>
cs

 

 

반응형

댓글