본문 바로가기

[Spring 기능구현] 공공 API 적용- 도로명주소 조회 서비스

인포꿀팁 발행일 : 2020-12-15

 

공공데이터 포털

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

www.data.go.kr

 

위 공공데이터 홈페이지에서는 다양한 데이터를 제공하는데 그중 개발에서 사용할 수 있는 API도 제공하고 있다.

 

API 사용법

1) 공공데이터 포털에서 KEY를 발급받는다.

발급받게되면 아래와 같이 일반 인증키와 END POINT 주소를 받게 된다.

이때 아래 참고 문서도 함께 다운받는다.

2) API에서 전송되는 데이터 JSON/ XML 형식을 STRING으로 변환/ XML형태의 문서를 JSON으로 변환하는 메소드 작성

 

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
@Service("common.apiSerializer")
public class APISerializer {
    private final Logger logger=LoggerFactory.getLogger(getClass());
    
    // 공공 API 등의 데이터를 XML,JSON 문서를 String 형태로 받기
    public String receiveToString(String spec) throws Exception {
        String result=null;
        
        HttpURLConnection conn=null;
        
        try {
            conn=(HttpURLConnection)new URL(spec).openConnection();
            BufferedReader br=new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), "UTF-8"));
            StringBuilder sb=new StringBuilder();
            String s;
            while((s=br.readLine())!=null) {
                sb.append(s);
            }
            result=sb.toString();
        } catch (Exception e) {
            logger.error(e.toString());
            
            throw e;
        } finally {
            if(conn!=null) {
                try {
                    conn.disconnect();
                } catch (Exception e2) {
                }
            }
        }
        
        return result;
    }
    
    // 공공 API등의 XML 데이터를 String 형태의 JSON으로 변환하여 받기
    public String receiveXmlToJson(String spec) throws Exception {
        String result=null;
        
        try {
            String s = receiveToString(spec);
/*
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180813</version>
        </dependency>
 
*/
            //xml을 json으로 변경해주는 객체 존재(json)
            JSONObject job=XML.toJSONObject(s);
            result = job.toString();
 
        } catch (Exception e) {
            // logger.error(e.toString());
            throw e;            
        }
        
        return result;
    }
}
cs

 

3) 도로명 주소 조회 서비스는 데이터를 XML 형식으로 넘겨주기 때문에 XML를 넘겨받는 controller를 만든다.

여기서 공공데이터 포털에서 받은 일반 인증키와 url 주소를 받아서 처리한다.

spec 같은 경우에는 주소 뒤에 get방식으로 키값과 검색값을 넘겨줘야한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    @RequestMapping(value = "zipXML", method = RequestMethod.GET, produces = "application/xml; charset=utf-8;")
    @ResponseBody
    public String zipXML(@RequestParam String search) throws Exception{
        String resultXML = null;
 
        search = URLDecoder.decode(search,"utf-8");
        
        //servicekey : 일반 인증키
        String serviceKey="t%2FyVdVHahD3Lz92DaRm5UVeFOoJJFzxof6rE4Vw4ZIT3yECiqffSS47Ee8AMNFZsDnjtZ1Dd7xSjLg%2Bljnf9NQ%3D%3D";
        String spec ="http://openapi.epost.go.kr/postal/retrieveNewAdressAreaCdService/retrieveNewAdressAreaCdService/getNewAddressListAreaCd?";
        spec+=    "ServiceKey="+serviceKey
                + "&searchSe=road&srchwrd="+URLEncoder.encode(search,"utf-8");
        resultXML = apiSerializer.receiveToString(spec);
        
        return resultXML;
    }
cs

 

4)view단에 스크립트를 작성해준다.

데이터 파싱은 아래와 같이

xml의 데이터를 가져오는 방식으로 해당 데이터의 태그명을 이용하여 가져온다.

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
$(function(){
    //우편번호-xml로 받아 오기
    $("#btnXmlOk2").click(function(){
        var url="${pageContext.request.contextPath}/nguest/zipXML";
        var search="양평로30길 4-1";
        search = encodeURIComponent(search);
        var query = "search="+search;
        
        var fn = function(data){
            console.log(data);
            printZip(data);
        };
        ajaxFun(url, "get""xml", query, fn);
});
    function printZip(data){
        var out="<p>우편번호</p>";
        
        $(data).find("newAddressListAreaCd").each(function(){
            var item=$(this);
            var zipNo=item.find("zipNo").text();
            var lnmAdres=item.find("lnmAdres").text();
            var rnAdres=item.find("rnAdres").text();
            
            out+="우편번호:"+zipNo+"<br>";
            out+="도로명주소:"+lnmAdres+"<br>";
            out+="지번:"+rnAdres+"<br><hr>";
        });
        $("#resultLayout").html(out);
    }
});
cs

 

***********

만일 XML을 JSON으로 변환하여 반환한다면

1)넘어온 XML을 JSON으로 변환시키는 메소드 적용후 반환

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    //ajax-json 응답
    @RequestMapping(value = "jsonList1", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    @ResponseBody
    public String jsonList1(HttpServletRequest req) throws Exception{
        String result = null;
        
        String cp = req.getContextPath();
        String spec = req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+cp;
        spec+="/xml/guestXML.xml";
        
        //XML을 JSON으로 변환하여 반환
        result = apiSerializer.receiveXmlToJson(spec);
        
        return result;
    }
cs

 

2)넘어온 데이터는 AJAX의 속성중 DATATYPE을 JSON으로 변환하고 파싱할때 속성값에 맞는 태그명으로 값을 불러온다.

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
$(function(){
    $("#btnJsonOk1").click(function(){
        //json으로 받기
        var url="${pageContext.request.contextPath}/nguest/jsonList1";
        var query="tmp="+new Date().getTime();        
        var fn = function(data){
            console.log(data);
            printJSON(data)
        };
        ajaxFun(url,"get","json",query, fn);
    });
    function printJSON(data){
        var out="<p>JSON으로 받아오기-1</p>";
        var dataCount=data.root.dataCount;
        out = "개수 : "+dataCount+"<br>";
        
        $.each(data.root.record, function(index,item){
            var num = item.num;
            var name = item.name;
            var content = item.content;
            var created = item.created;
            
            out+=num+":"+name+":"+content+":"+created+"<br><hr>";
        });
        
        $("#resultLayout").html(out);
        
    }
    
});
cs

 

댓글