SpringBoot(홍팍) - ObjectMapper, JSON 다루기

정원·2023년 3월 27일
0

SpringBoot

목록 보기
34/34

2023.03.27 ObjectMapper, JSON 다루기


JSON을 자바 객체로(DTO)
자바 객체(DTO)를 JSON으로 변환.

그 과정을 AOP를 적용해서 확인해보자.

디버깅 AOP적용

DebuggingAspect의 적용범위 변경.
service에서 api로 변경

@Pointcut("execution(* com.example.firstproject.api.*.*(..))")

api안에 컨트롤러들의 모든 메소드들에게 적용됨.

Talend API로 댓글생성 요청을 보내보면
log로 확인할 수 있다.

JSON -> DTO

DTO -> JSON

Talend API의 응답을 보면 JSON데이터를 확인할 수 있다.
ObjectMapper가 자동으로 DTO를 JSON으로 변환하여 응답해준것이다.

이제 이 과정을 더 자세히 살펴보자.

객체를 JSON으로

objectmapper 패키지 생성.

burger

연습용 클래스 생성.

package com.example.firstproject.objectmapper;

@AllArgsConstructor
@ToString
public class Burger {
    private String name;
    private int price;
    private List<String> ingredients;
}

BurgerTest

Test 클래스 생성.

자바객체를_JSON으로변환

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 NODE 활용하기

위에 나온 JSON을 예쁘게 출력하기.

JsonNode jsonNode = objectMapper.readTree(json);
System.out.println(jsonNode.toPrettyString());        

JSON을 객체로

BurgerTest

JSON을자바객체로_변환()

@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을 작성할때는 아래처럼 하드코딩을 해야하는데 제공되는 도구들을 이용해서 편하게 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);

BurgerTest 전체코드

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());
    }
}

0개의 댓글