2023.03.27 ObjectMapper, JSON 다루기
JSON을 자바 객체로(DTO)
자바 객체(DTO)를 JSON으로 변환.
그 과정을 AOP를 적용해서 확인해보자.
DebuggingAspect의 적용범위 변경.
service에서 api로 변경
@Pointcut("execution(* com.example.firstproject.api.*.*(..))")
api안에 컨트롤러들의 모든 메소드들에게 적용됨.
Talend API로 댓글생성 요청을 보내보면
log로 확인할 수 있다.
Talend API의 응답을 보면 JSON데이터를 확인할 수 있다.
ObjectMapper가 자동으로 DTO를 JSON으로 변환하여 응답해준것이다.
이제 이 과정을 더 자세히 살펴보자.
objectmapper 패키지 생성.
연습용 클래스 생성.
package com.example.firstproject.objectmapper;
@AllArgsConstructor
@ToString
public class Burger {
private String name;
private int price;
private List<String> ingredients;
}
Test 클래스 생성.
package com.example.firstproject.objectmapper;
class BurgerTest {
@Test
public void 자바_객체를_JSON으로_변환() throws JsonProcessingException {
// 준비
ObjectMapper objectMapper = new ObjectMapper();
List<String> ingredients = Arrays.asList("통새우 패티", "순쇠고기 패티", "토마토", "소스");
Burger burger = new Burger("맥도날드 빅맥", 5500, ingredients);
// 수행
// writeValueAsString(자바객체)를 사용하면 문자열의 json을 반환해준다.
String json = objectMapper.writeValueAsString(burger); // 예외 발생 -> throws 처리
// 예상
String expected = "";
// 검증
assertEquals(expected, json);
System.out.println(json);
}
}
코드 작성하고 Test해보면
writeValueAsString에서 에러가 발생한다.
No serializer found for class ...
에러를 잡기 위해 추가해야할 코드가 있다.
Burger 클래스에 @Getter 추가..
값을 가져다가 JSON으로 만들려면
값을 가져올 수 있는 Getter가 필요한게 당연한거 같은뎅... 굳이 이제와서 추가를..??
😊 하이튼 @Getter 추가!!
다시 Test 진행.
exepected에 빈문자열이라서 테스트는 실패했지만
JSON이 만들어진것을 확인할 수 있다.
JSON을 복사해서 exepected에 넣으면 Test 성공.
(귀찮아서 그냥 복사해서 넣기)
JSON 확인가능.
위에 나온 JSON을 예쁘게 출력하기.
JsonNode jsonNode = objectMapper.readTree(json);
System.out.println(jsonNode.toPrettyString());
@Test
public void JSON을_자바_객체로_변환() throws JsonProcessingException {
// 준비
ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"name\":\"맥도날드 빅맥\",\"price\":5500,\"ingredients\":[\"통새우 패티\",\"순쇠고기 패티\",\"토마토\",\"소스\"]}";
// 수행
// readValue(JSON, JSON으로 만들 클래스 타입)
Burger burger = objectMapper.readValue(json, Burger.class); // 예외 발생 -> throws 처리
// 예상
List<String> ingredients = Arrays.asList("통새우 패티", "순쇠고기 패티", "토마토", "소스");
Burger expected = new Burger("맥도날드 빅맥", 5500, ingredients);
// 검증
assertEquals(expected.toString(), burger.toString());
System.out.println(objectMapper.readTree(json).toPrettyString());
System.out.println(burger.toString());
}
no Creators, like default constructor, exist.. 에러발생.
Burger 클래스에 default 생성자 추가(@NoArgsConstructor)
😊 성공 😊
현재 JSON을 작성할때는 아래처럼 하드코딩을 해야하는데 제공되는 도구들을 이용해서 편하게 JSON을 만들어보자.
String json = "{\"name\":\"맥도날드 빅맥\",\"price\":5500,\"ingredients\":[\"통새우 패티\",\"순쇠고기 패티\",\"토마토\",\"소스\"]}";
@Test
public void JSON을_자바_객체로_변환() throws JsonProcessingException {
// 준비
ObjectMapper objectMapper = new ObjectMapper();
/*
{
"name" : "맥도날드 빅맥",
"price" : 5500,
"ingredients" : [ "통새우 패티", "순쇠고기 패티", "토마토", "소스" ]
}
*/
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("name", "맥도날드 빅맥");
objectNode.put("price", 5500);
// ingredients 배열 생성
ArrayNode arrayNode = objectMapper.createArrayNode();
arrayNode.add("통새우 패티");
arrayNode.add("순쇠고기 패티");
arrayNode.add("토마토");
arrayNode.add("소스");
// ingredients 배열 objectNode에 추가
objectNode.put("ingredients", arrayNode);
// objectNode을 toString으로 변환하면 원하는 JSON 결과가 나온다.
String json = objectNode.toString();
}
✨ objectNode.put("", Node) 를 할때
나는 안그러는데 강의에서는 put이 deprecated가 됐다고 나온다.
이럴때는 set을 사용하는게 좋다고 한다.
objectNode.set("ingredients", arrayNode);
package com.example.firstproject.objectmapper;
class BurgerTest {
@Test
public void 자바_객체를_JSON으로_변환() throws JsonProcessingException {
// 준비
ObjectMapper objectMapper = new ObjectMapper();
List<String> ingredients = Arrays.asList("통새우 패티", "순쇠고기 패티", "토마토", "소스");
Burger burger = new Burger("맥도날드 빅맥", 5500, ingredients);
// 수행
// writeValueAsString(자바객체)를 사용하면 문자열의 json을 반환해준다.
String json = objectMapper.writeValueAsString(burger); // 예외 발생 -> throws 처리
// 예상
String expected = "{\"name\":\"맥도날드 빅맥\",\"price\":5500,\"ingredients\":[\"통새우 패티\",\"순쇠고기 패티\",\"토마토\",\"소스\"]}";
// 검증
assertEquals(expected, json);
JsonNode jsonNode = objectMapper.readTree(json);
System.out.println(jsonNode.toPrettyString());
}
@Test
public void JSON을_자바_객체로_변환() throws JsonProcessingException {
// 준비
ObjectMapper objectMapper = new ObjectMapper();
// String json = "{\"name\":\"맥도날드 빅맥\",\"price\":5500,\"ingredients\":[\"통새우 패티\",\"순쇠고기 패티\",\"토마토\",\"소스\"]}";
/*
{
"name" : "맥도날드 빅맥",
"price" : 5500,
"ingredients" : [ "통새우 패티", "순쇠고기 패티", "토마토", "소스" ]
}
*/
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("name", "맥도날드 빅맥");
objectNode.put("price", 5500);
// ingredients 배열 생성
ArrayNode arrayNode = objectMapper.createArrayNode();
arrayNode.add("통새우 패티");
arrayNode.add("순쇠고기 패티");
arrayNode.add("토마토");
arrayNode.add("소스");
// ingredients 배열 objectNode에 추가
objectNode.set("ingredients", arrayNode);
// objectNode을 toString으로 변환하면 원하는 JSON 결과가 나온다.
String json = objectNode.toString();
// 수행
// readValue(JSON, JSON으로 만들 클래스 타입)
Burger burger = objectMapper.readValue(json, Burger.class); // 예외 발생 -> throws 처리
// 예상
List<String> ingredients = Arrays.asList("통새우 패티", "순쇠고기 패티", "토마토", "소스");
Burger expected = new Burger("맥도날드 빅맥", 5500, ingredients);
// 검증
assertEquals(expected.toString(), burger.toString());
System.out.println(objectMapper.readTree(json).toPrettyString());
System.out.println(burger.toString());
}
}