json-simple 사용해 Json response 파싱하기

o_z·2024년 3월 18일
post-thumbnail

저번 'WebClient 사용해 외부 API 호출하기'의 연장선이다. WebClient로 외부 API를 호출하고 Json 형태의 response를 받았다.

String url = "https://pixabay.com/api/";
		String searchKeyword = country.toString().concat(" ").concat(city.toString());

		WebClient webClient = WebClient.create(url);
		String response = webClient.get()
			.uri(uriBuilder -> uriBuilder
				.queryParam("q", searchKeyword)
				.queryParam("lang","ko")
				.queryParam("key", apiKey)
				.build())
			.retrieve()
			.bodyToMono(String.class)
			.block();

API 호출 시 결과는 아래처럼 나타난다.

{
    "total": 193,
    "totalHits": 193,
    "hits": [
        {
            "id": 2014618,
            "pageURL": "https://pixabay.com/photos/japan-street-night-osaka-asia-2014618/",
            "type": "photo",
            "tags": "japan, street, night",
            "previewURL": "https://cdn.pixabay.com/photo/2017/01/28/02/24/japan-2014618_150.jpg",
            "previewWidth": 150,
            "previewHeight": 99,
            "webformatURL": "https://pixabay.com/get/g128b7c43a03a139f86f88720b1531d28b306c82c885a09347fb4b650ac4227f73432a6fd59baeb41f98bb6828b4de784dafe69ec2ddbd4fa7625172ec081fb43_640.jpg",
            "webformatWidth": 640,
            "webformatHeight": 425,
            "largeImageURL": "https://pixabay.com/get/g45643b083f9740acb8780c1e7fb82e0d794e23009b09e211c5eadb74cd1da808c144afeddecd6cf4b3636fc868dae778f6d0676da651b4ab552de7fa477c441d_1280.jpg",
            "imageWidth": 2048,
            "imageHeight": 1362,
            "imageSize": 752538,
            "views": 862521,
            "downloads": 665922,
            "collections": 1865,
            "likes": 1432,
            "comments": 168,
            "user_id": 4385858,
            "user": "MasashiWakui",
            "userImageURL": "https://cdn.pixabay.com/user/2017/01/28/02-10-45-719_250x250.jpg"
        },
        ...

위 response에서 필요한 필드는 결과 중 첫 번째 사진의 'largeImageUrl' 하나이다.

원래 json 형태의 response를 받아서 사용하는 방법으로는 애초에 받을 때부터 response 필드들에 맞는 DTO class를 생성해서 매핑된 결과를 받는 것이 있다. 하지만 난 저 모든 결과가 필요한 것도 아니고 딱 하나의 필드만 사용하기 때문에 class를 만드는 것은 손해라고 생각했다.

그래서 라이브러리 추가만 하면 쉽게 사용할 수 있는 json-simple 라이브러리를 사용하여 파싱했다.


json-simple 사용해 json 파싱하기

json-simple

json 형태의 데이터를 쉽게 다룰 수 있도록 파싱하는 메서드를 제공한다.
먼저 build.gradle에 json-simple 라이브러리 의존성을 추가해주자.

//json-simple
	implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'

JSONParser 객체를 생성하고 json 형태의 response를 parse()에 넣어 파싱한다. 파싱에 실패한 경우, ParserException이 터지므로 try-catch로 묶었다. object가 파싱한 결과가 들어갈 JSONObject 객체이다.

JSONParser parser = new JSONParser();
JSONObject object;
try {
	object = (JSONObject)parser.parse(response);
} catch (ParseException e) {
	throw new RuntimeException(e);
}

이제 내가 원하는 첫 번째 결과의 largeImageURL만 뽑아내면 된다!

JSONArray hits = (JSONArray)object.get("hits"); // "hits" 키의 결과들
JSONObject hitBody = (JSONObject)hits.get(0); // "hits"의 첫 번째 사진
String result = (String)hitBody.get("largeImageURL"); // hitBody의 largeImageURL 결과 

내가 사용하는 Stock Image API를 테스트 해보니까 사진 데이터가 좀 다양하지 않아서 그런지 몇몇 검색어에 대해서는 hits 결과가 하나도 없는 경우가 있었다. 그래서 검색 결과가 없을 땐 null을 return해 프론트쪽에서 대체 이미지를 넣기로 했다.
전체 코드는 아래와 같다.

private static String parseResponseToImageUrl(String response) {
		JSONParser parser = new JSONParser();
		JSONObject object;
		try {
			object = (JSONObject)parser.parse(response);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		try{
			JSONArray hits = (JSONArray)object.get("hits");
			JSONObject hitBody = (JSONObject)hits.get(0);
			return (String)hitBody.get("largeImageURL");
       } catch (RuntimeException e) {
       		return null;
       }
	}

나는 위에 WebClient로 외부 API 호출한 곳에서 parseResponseToImageUrl() 메서드를 호출하여 결과를 사용했다. json-simple 라이브러리 사용하니까 적은 수의 결과를 사용하고자 할 땐 아주 유용하게 쓸만 할 것 같다!


profile
트러블슈팅과 구현기를 위주로 기록합니다-

0개의 댓글