2021-09-26
오늘은 오픈 API를 연동하는 과정을 알아보도록 하자. 예제는 https://open.assembly.go.kr/portal/openapi/main.do를 활용해서 진행할 예정이며, 가이드라인도 열린 국회 정보 API를 따른다.
- 예제
먼저 아래는 View를 구성하는 jsp 화면이다. api 연동으로 얻어진 정보를 openInfo라는 하나의 객체로 담아 간단히 나타낼 것이기 때문에 매우 간단하다.
<%@ 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="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>얻어온 Open API 정보</h3>
<p>${openInfo }</p>
<a href="/goods/goodsSearch"><button type="button">API화면</button></a>
</body>
</html>
아래는 api 정보를 받아올 dto 객체이다.
package com.test.test.dto;
public class ApiDto {
private String billId;
private String billNo;
private String billName;
private String committee;
private String proposeDt;
private String procResult;
private String age;
private String detailLink;
private String proposer;
private String memberList;
private String rstProposer;
private String publProposer;
private String committeeId;
public String getBillId() {
return billId;
}
public void setBillId(String billId) {
this.billId = billId;
}
public String getBillNo() {
return billNo;
}
public void setBillNo(String billNo) {
this.billNo = billNo;
}
public String getBillName() {
return billName;
}
public void setBillName(String billName) {
this.billName = billName;
}
public String getCommittee() {
return committee;
}
public void setCommittee(String committee) {
this.committee = committee;
}
public String getProposeDt() {
return proposeDt;
}
public void setProposeDt(String proposeDt) {
this.proposeDt = proposeDt;
}
public String getProcResult() {
return procResult;
}
public void setProcResult(String procResult) {
this.procResult = procResult;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getDetailLink() {
return detailLink;
}
public void setDetailLink(String detailLink) {
this.detailLink = detailLink;
}
public String getProposer() {
return proposer;
}
public void setProposer(String proposer) {
this.proposer = proposer;
}
public String getMemberList() {
return memberList;
}
public void setMemberList(String memberList) {
this.memberList = memberList;
}
public String getRstProposer() {
return rstProposer;
}
public void setRstProposer(String rstProposer) {
this.rstProposer = rstProposer;
}
public String getPublProposer() {
return publProposer;
}
public void setPublProposer(String publProposer) {
this.publProposer = publProposer;
}
public String getCommitteeId() {
return committeeId;
}
public void setCommitteeId(String committeeId) {
this.committeeId = committeeId;
}
@Override
public String toString() {
return "ApiDto [billId=" + billId + ", billNo=" + billNo + ", billName=" + billName + ", committee=" + committee
+ ", proposeDt=" + proposeDt + ", procResult=" + procResult + ", age=" + age + ", detailLink="
+ detailLink + ", proposer=" + proposer + ", memberList=" + memberList + ", rstProposer=" + rstProposer
+ ", publProposer=" + publProposer + ", committeeId=" + committeeId + "]";
}
}
다음은 openapi를 실제 연동하기 위한 controller 이다. outputstream으로 body에 파라미터를 정보를 보내려고 했으나 응답을 받아오지 않아 url에 직접 파라미터 정보를 넣어서 구현하였다.
일단은 API 연동은 https://open.assembly.go.kr/portal/data/service/selectAPIServicePage.do/OK7XM1000938DS17215
위의 국회의원 발의법률안 을 기준으로 진행하였다. 어떤 API를 사용하냐에 따라 DTO 및 url , 파라미터 정보가 달라질 수 있다.
package com.test.test.controller;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.test.test.dto.ApiDto;
@Controller
public class OpenApi {
// 로거 객체
private static final Logger logger = LoggerFactory.getLogger(OpenApi.class);
@GetMapping(value="/openApi/result")
public void openApiRes(HttpServletRequest request, Model model) {
String age = request.getParameter("age");
if(age == null) {
age = "10";
}
//자신이 선택한 API 종류에 따라 달라지는 부분
String strUrl = "https://open.assembly.go.kr/portal/openapi/자신이 선택한 API 주소"
+ "?Key=자신이 전달받은 키정보"
+ "&Type=json"
+ "&pIndex=1"
+ "&pSize=100"
+ "&AGE=" + age;
String line = "";
String data = "";
try {
URL url = new URL(strUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5000); //서버에 연결되는 Timeout 시간 설정
con.setReadTimeout(5000); // InputStream 읽어 오는 Timeout 시간 설정
con.setRequestMethod("POST");
con.setDefaultUseCaches(false);
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestProperty("content-type", "application/x-www-form-urlencoded");
StringBuilder sb = new StringBuilder();
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("--공용 API 사이트 연결 성공 --");
BufferedReader br = new BufferedReader(
new InputStreamReader(con.getInputStream(), "utf-8"));
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
br.close();
data = sb.toString(); // 최종 데이터 저장
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(data);
JSONArray allList = (JSONArray) jsonObject.get("nzmimeepazxkubdpn");
JSONObject jsonObject2 = (JSONObject) allList.get(1);
for(int i =0; i < allList.size(); i++) {
System.out.println("json all 정보 -> " + allList.get(i));
}
System.out.println();
System.out.println("json Object2 정보 : " + jsonObject2);
JSONArray rowList = (JSONArray) jsonObject2.get("row");
for(int i =0; i < rowList.size(); i++) {
ApiDto apiDto = new ApiDto();
JSONObject tempJson = (JSONObject) rowList.get(i);
apiDto.setBillName((String)tempJson.get("BILL_NAME"));
apiDto.setAge((String)tempJson.get("AGE"));
apiDto.setBillId((String)tempJson.get("BILL_ID"));
apiDto.setBillNo((String)tempJson.get("BILL_No"));
System.out.println(apiDto);
}
System.out.println();
System.out.println("저장된 데이터 -> " + sb.toString());
} else {
System.out.println("응답메시지 -> "+con.getResponseMessage());
}
} catch (Exception e){
System.err.println("예외발생 -> "+e.toString());
}
System.out.println("받은 정보 : " + data);
model.addAttribute("openInfo", data);
}
}
기본적으로 XML 형태와 json 형태의 리턴 값을 지원하는데, 보통은 json 빠르고 데이터 효율이 좋기 때문에 json을 많이 사용한다.
메인 이미지 출처 :Photo by eberhard 🖐 grossgasteiger on Unsplash