자바에서 API 호출하기
1. URL 생성자로 URL 객채 만들기
java.net.URL은 자바에서 url을 다루는 클래스이다.
URL 클래스의 주요 생성자는 다음과 같다.
- URL(String spec) : 문자열 spec이 지정하는 자원에 대한 URL 객체 생성
- URL(String protocol, String host, int port, String file) : 프로토콜 식별자 protocol, 호스트 주소 host, 포트 번호 port, 파일 이름 file이 지정하는 자원에 대한 URL 객체 생성
URL url = new URL("https://yts.mx/api/v2/list_movies.json");
2. HTTP Connection 구하기 - URLConnection openConnection()
java.net.HttpURLConnection은 URLConnection을 구현한 추상 클래스이다. URLConnection은 웹을 통해 데이터를 주고 받는데 사용된다.
openConnection() 메서드는 URL을 참조하는 객체를 URLConnection 객체로 반환한다.
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3. Request 방식 설정하기 - void setRequestMethod(String method)
기본 설정은 GET 요청이다. GET/ POST/ HEAD/ OPTIONS/ PUT/ DELETE/ TRACE 중 한 개를 골라서 요청이 가능하다.
conn.setRequestMethod("GET");
4. Request 속성 값 설정하기 - void setRequestProperty(String key, String value)
JSON형식의 데이터를 받으려면 Content-type의 값을 "application/json"으로 설정해야 한다. 또한 X-Auth-Token이나 Authorization값 설정이 필요하다면 해당 메서드를 사용하여 값을 설정해주면 된다.
con.setRequestProperty("X-Auth-Token", AUTH_TOKEN);
con.setRequestProperty("Content-type", "application/json");
5. 출력 가능 상태로 설정하기 - void setDoOutput(boolean dooutput)
받아온 Json 데이터를 출력 가능한 상태(True)로 변경해줘야 한다. 기본값은 false이다.
con.setDoOutput(true);
6. 입력 스트림으로 데이터 읽기
인코딩방식은 InputStreamReader 생성자 두번째 인자값(charsetName)에 "UTF-8"로 설정해주면 된다.
try{
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
while(br.ready()) {
sb.append(br.readLine());
}
}catch(Exception e) {
e.printStackTrace();
}
이대로 값을 출력하면 다음과 같이 출력된다. 이렇게 하면 데이터를 구분하기도 어렵고 어떻게 뽑아써야할지도 복잡하다. 그래서 이 데이터를 Java에서는 JSON 파싱하는 org.json이나 Gson 라이브러리를 사용하여 데이터를 가독성이 좋게 가공하여 사용해야 한다.
POST 요청 Parameter 전송하기
// JSON 데이터
JSONObject jsonData = new JSONObject();
jsonData.put("problem", problem);
// 파라미터 데이터 출력 스트림에 입력
OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
osw.write(parameters.toString());
osw.flush();
osw.close();
자바에서 JSON Parsing하기
1. JSON 라이브러리 설치하기
[Eclipse/ IntelliJ] Java 프로젝트에 JSON 러이브러리(org.json) 설치하기
→ Java에서 JSON Parsing을 하기 위해서느 외부 라이브러리를 등록해줘야 한다.
2. Object 데이터가 있는 JSON 파싱하기
Object 데이터는 "{", "}"(curly brace)로 감싸져 있는 데이터를 나타낸다.
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class ApiTest2 {
public static void main(String[] args) throws ParseException {
// JSONParser로 JSONObject 객체
JSONObject objData = (JSONObject)new JSONParser().parse(jsonData);
// 첫 번째 JSONObject
JSONObject movieData1 = (JSONObject)objData.get("movie1");
// 두 번째 JSONObject
JSONObject movieData2 = (JSONObject)objData.get("movie2");
// 데이터 출력하기
StringBuilder sb = new StringBuilder();
sb.append("movie1----\n");
sb.append("title: " + movieData1.get("title")+"\n");
sb.append("url: " + movieData1.get("url")+"\n");
sb.append("movie2----\n");
sb.append("title: " + movieData2.get("title")+"\n");
sb.append("url: " + movieData2.get("url")+"\n");
System.out.println(sb.toString());
}
// jsonData
static String jsonData=
"{"
+ "\"movie1\": {"
+ "\"title\": \"Blame\","
+ "\"url\": \"https://yts.mx/movies/blame-2021\","
+ "},"
+ "\"movie2\": {"
+ "\"title\": \"Tethered\","
+ "\"url\": \"https://yts.mx/movies/tethered-2021\","
+ "},"
+ "}";
}
출력 결과
3. Array 데이터가 있는 JSON 파싱하기
JSON 데이터안에 있는 "[", "]"로 감싸진 배열 데이터를 파싱하기 위해서는 JSONArray가 추가적으로 필요하다.
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class ApiTest2 {
public static void main(String[] args) throws ParseException {
// JSONParser에 JSON데이터를 넣어 파싱한 다음 JSONObject로 반환한다.
JSONObject objData = (JSONObject)new JSONParser().parse(jsonData);
// JSONObject에서 Array데이터를 get하여 JSONArray에 저장한다.
JSONArray arrData = (JSONArray)objData.get("movies");
// 배열 데이터 출력하기
JSONObject tmp;
JSONArray tmpArr;
StringBuilder sb= new StringBuilder();
for(int i=0; i<arrData.size(); i++){
tmp = (JSONObject)arrData.get(i);
sb.append("title("+i+"): " + tmp.get("title")+"\n");
sb.append("url("+i+"): " + tmp.get("url")+"\n");
// Array데이터 안에 Array 데이터 꺼내기
tmpArr = (JSONArray)tmp.get("genres");
sb.append("genres("+i+"): ");
for(int j=0; j<tmpArr.size(); j++){
sb.append(j+"." + tmpArr.get(j));
if(j!=tmpArr.size()-1) sb.append(", ");
}
sb.append("\n");
}
System.out.println(sb.toString());
}
// jsonData
static String jsonData=
"{"
+ "\"movies\": ["
+ "{"
+ "\"title\": \"Blame\","
+ "\"url\": \"https://yts.mx/movies/blame-2021\","
+ "\"genres\": ["
+ "\"Crime\",\"Thriller\""
+ "]"
+ "},"
+ "{"
+ "\"title\": \"Tethered\","
+ "\"url\": \"https://yts.mx/movies/tethered-2021\","
+ "\"genres\": ["
+ "\"Drama\",\"Mystery\",\"Sci-Fi\""
+ "]"
+ "},"
+ "{"
+ "\"title\": \"The Resonator: Miskatonic U\","
+ "\"url\": \"https://yts.mx/movies/the-resonator-miskatonic-u-2021\","
+ "\"genres\": ["
+ "\"Fantasy\""
+ "]"
+ "}"
+ "]"
+"}";
}
출력 결과
자바에서 API 호출하여 JSON 데이터 파싱하기
위에서 다룬 URL, URLConnection, HttpURLConnection 클래스들의 메서드와 JSON 파싱 예제를 활용하여 REST API로 받아오는 JSON 데이터를 파싱할 수 있다.
OPEN API에서 제공하는 JSON 데이터 URL 예시
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class ApiTest {
static final String BASE_URL = "https://yts.mx/api/v2/list_movies.json";
static final String AUTH_TOKEN = "AUTH_TOKEN 값";
static String AUTH_KEY = "Bearer " + "AUTH_KEY 값";
public static void main(String[] args) throws ParseException {
/**
* REST API 호출하기
*/
URL url = null;
HttpURLConnection con= null;
JSONObject result = null;
StringBuilder sb = new StringBuilder();
try {
// URL 객채 생성 (BASE_URL)
url = new URL(BASE_URL);
// URL을 참조하는 객체를 URLConnection 객체로 변환
con = (HttpURLConnection) url.openConnection();
// 커넥션 request 방식 "GET"으로 설정
con.setRequestMethod("GET");
// 커넥션 request 값 설정(key,value)
con.setRequestProperty("Content-type", "application/json");
// void setRequestProperty (key,value) 다른 예시
// con.setRequestProperty("Authorization", AUTH_KEY);
// con.setRequestProperty("X-Auth-Token", AUTH_TOKEN);
// 받아온 JSON 데이터 출력 가능 상태로 변경 (default : false)
con.setDoOutput(true);
// 데이터 입력 스트림에 담기
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
while(br.ready()) {
sb.append(br.readLine());
}
con.disconnect();
}catch(Exception e) {
e.printStackTrace();
}
/**
* JSON 데이터 파싱하기
*/
// JSONParser에 입력 스트림에 담은 JSON데이터(sb.toString())를 넣어 파싱한 다음 JSONObject로 반환한다.
result = (JSONObject) new JSONParser().parse(sb.toString());
// REST API 호출 상태 출력하기
StringBuilder out = new StringBuilder();
out.append(result.get("status") +" : " + result.get("status_message") +"\n");
// JSON데이터에서 "data"라는 JSONObject를 가져온다.
JSONObject data = (JSONObject) result.get("data");
// JSONObject에서 Array데이터를 get하여 JSONArray에 저장한다.
JSONArray array = (JSONArray) data.get("movies");
// 데이터 출력하기 (뮤비 제목, 장르)
JSONObject tmp;
out.append("데이터 출력하기 \n");
for(int i=0; i<array.size(); i++) {
tmp = (JSONObject) array.get(i);
out.append("title("+i+") :"+ tmp.get("title") +"\n");
// movies[] 배열 안에 있는 genres[] 데이터 꺼내기
JSONArray array2 = (JSONArray) tmp.get("genres");
out.append("genres("+i+"): ");
for(int j=0; j<array2.size(); j++) {
out.append(array2.get(j));
if(j!=array2.size()-1) {
out.append(",");
}
}
out.append("\n");
out.append("\n");
}
System.out.println(out.toString());
}
}
출력 결과
ok : Query was successful
데이터 출력하기
title(0) :Blame
genres(0): Crime,Thriller
title(1) :Tethered
genres(1): Drama,Mystery,Sci-Fi
title(2) :The Resonator: Miskatonic U
genres(2): Fantasy
title(3) :Verbindung
genres(3): Drama
title(4) :Bloodbath at the House of Death
genres(4): Comedy,Horror
title(5) :The Alpines
genres(5): Mystery,Thriller
title(6) :This Is the Night
genres(6): Drama
title(7) :Shock Troops
genres(7): Action,Drama,History
title(8) :Moments Without Proper Names
genres(8): Action
title(9) :Potato Salad
genres(9): Comedy,Horror
title(10) :The Big Steal
genres(10): Comedy
title(11) :The Division
genres(11): Action,Crime,Thriller
title(12) :Second Origin
genres(12): Adventure,Horror,Sci-Fi
title(13) :Elisa's Day
genres(13): Crime,Drama
title(14) :15 Years and One Day
genres(14): Drama
title(15) :Most Dangerous Game
genres(15): Action,Thriller
title(16) :Night of the Animated Dead
genres(16): Animation,Horror
title(17) :Devil's Five
genres(17): Horror
title(18) :The Secret Lives of Dorks
genres(18): Comedy
title(19) :When I Get Home, My Wife Always Pretends to Be Dead.
genres(19): Comedy,Drama
'Dot Programming > Java' 카테고리의 다른 글
[Java] 메서드 오버라이딩과 하이딩에 대해 (Overriding and Hiding Methods) (0) | 2022.01.31 |
---|---|
[Java] 추상 클래스 vs 인터페이스 (추상 클래스와 인터페이스의 차이는 결합력) (0) | 2022.01.31 |
2022년 자바 개발자 로드맵 (The 2022 Java Programmer RoadMap) (0) | 2022.01.17 |
[Java] 자바가 언제나 Call By Value인 이유 (Call By Reference X) (0) | 2021.09.29 |
자바컬렉션프레임워크(JCF)로 자료구조 알아보기 (0) | 2021.04.06 |