ObjectMapper

OneTwoThree·2022년 10월 29일
0

유튜브 홍팍님 강의

클라이언트가 서버에게 JSON 데이터 전송 -> 서버는 DTO로 변환해서 받음
서버가 클라이언트에게 DTO 전송 -> 클라리언트는 JSON으로 변환해서 받음

ObjectMapper로 이게 가능하다
ObejctMapper는 JSON과 자바 객체간 변환을 제공하는 객체다.


JSON을 자바 객체로 변환, 자바 객체를 JSON으로 변환해보자

//대상 메소드 선택 : api 패키지의 모든 메소드 
    @Pointcut("execution(* com.example.firstproject.api.*.*(..))")
    private void cut(){ }

먼저 로깅할 수 있게 설정해줌
DebuggingAspect에서 AOP 적용 범위를 api 패키지의 모든 메소드로 바꿔준다.

이렇게 하고 Talend API로 JSON을 담아 request를 보내보자

JSON 데이터를 보냈지만 로깅된 결과를 보면 CommentDto 객체가 입력된것으로 나옴
즉 내가 작성한 JSON 데이터가 CommentDto로 바뀐것


그리고 반환값으로는 DTO가 던져진다. 이 DTO가 ObjectMapper에 의해 변환되어서 클라이언트에게 전달된다.

기본 패키지에 objectmapper 패키지를 만들고 Burger 클래스를 만들어서 객체와 JSON간의 변환을 연습해보자.

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

Burger 클래스. 만들고 나서 테스트코드를 만들어줘야한다

class BurgerTest {



    @Test
    public void 자바_객체를_JSON으로_변환() throws JsonProcessingException {
        //준비
        ObjectMapper objectMapper = new ObjectMapper();
        List<String> ingredients = Arrays.asList("통새우 패티","순쇠고기 패티","토마토","스파이시 어니언 소스");
        Burger burger = new Burger("맥도날드 슈비버거", 5500,ingredients);

        //수행
        String json = objectMapper.writeValueAsString(burger);

        //예상
        String expected = "";

        //검증
        assertEquals(expected,json);
        System.out.println(json);
    }

먼저 위와 같이 만들어준다.
버거 객체를 만들고 objectMapper의 writeValueAsString으로 String 형태의 JSON 객체로 burger 객체를 변환할 수 있다.
일단 예상 문자열은 그냥 ""로 지정했다.

참고로 writeValueAsString에 빨간 밑줄로 오류가 표시되는데 마우스 올리고 add exception to method signature를 클릭하면 throws JsonProcessingException이 메소드 뒤에 추가되면서 예외처리를 해주게 된다.

테스트를 해보면 버거를 시리얼라이즈 할 수 없다. 라고 에러메세지가 뜬다
writeValueAsString에서 에러가 발생한 것인데, 이것을 해결하기 위해서는 Burger 클래스에 게터를 만들어줘야 한다.

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

Getter 어노테이션을 추가해준다.
버거 객체에서 JSON으로 변환하기 위해서는 게터가 필요하다.

이렇게 하고 테스트를 진행해 보면 테스트 결과는 실패지만 (expected=""로 했으므로)
실제 실행 결과가 표시된다. 실제 실행 결과는 JSON 객체인 것을 확인할 수 있다.

    @Test
    public void 자바_객체를_JSON으로_변환() throws JsonProcessingException {
        //준비
        ObjectMapper objectMapper = new ObjectMapper();
        List<String> ingredients = Arrays.asList("통새우 패티","순쇠고기 패티","토마토","스파이시 어니언 소스");
        Burger burger = new Burger("맥도날드 슈비버거", 5500,ingredients);

        //수행
        String json = objectMapper.writeValueAsString(burger);

        //예상
        String expected = "{\"name\":\"맥도날드 슈비버거\",\"price\":5500,\"ingredients\":[\"통새우 패티\",\"순쇠고기 패티\",\"토마토\",\"스파이시 어니언 소스\"]}";

        //검증
        assertEquals(expected,json);
        System.out.println(json);
    }

expected를 위에서 나온 결과로 바꿔주고 테스트를 하면 통과

중요한것은 ObjectMapper의 writeValueAsString 메소드를 통해 burger 객체가 JSON으로 변환되었다는 것이다.

//검증
        assertEquals(expected,json);
        JsonNode jsonNode = objectMapper.readTree(json);
        System.out.println(jsonNode.toPrettyString());

검증 부분에 JsonNode 객체를 이용해서 이렇게 출력해주면 JSON 객체가 더 이쁘게 표시된다.


 @Test
    public void JSON을_자바_객체로_변환() throws JsonProcessingException {
        //준비
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"name\":\"맥도날드 슈비버거\",\"price\":5500,\"ingredients\":[\"통새우 패티\",\"순쇠고기 패티\",\"토마토\",\"스파이시 어니언 소스\"]}";

        //수행, reavalue(JSON객체, 바꾸려는 클래스타입)
        Burger burger = objectMapper.readValue(json,Burger.class); //readValue는 예외처리 해줘야함

        //예상
        List<String> ingredients = Arrays.asList("통새우 패티","순쇠고기 패티","토마토","스파이시 어니언 소스");
        Burger expected = new Burger("맥도날드 슈비버거", 5500,ingredients);
        //검증
        assertEquals(expected.toString(),burger.toString());
        System.out.println(json);
        System.out.println(burger.toString());
    }

이번에는 JSON 객체를 자바 객체로 만들어보자.
objectMapper.readValue(JSON객체, 바꾸려는 자바 클래스타입) 으로 해줄 수 있다.
그런데 이렇게 해놓고 테스트하면 에러 발생

readValue를 통해 Burger 객체를 만들 때 디폴트 생성자가 필요하다.

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

Burger 클래스에 @NoArgsConstructor 추가

JSON과 JSON으로 만든 자바 객체가 출력된다.

//검증
        assertEquals(expected.toString(),burger.toString());
        JsonNode jsonNode = objectMapper.readTree(json);
        System.out.println(jsonNode.toPrettyString());
        System.out.println(burger.toString());

마찬가지로 JsonNode를 이용해서 예쁘게 출력해줄 수 있다.


JSON 객체를 직접 만들 수 있다.

 // 준비
        ObjectMapper objectMapper = new ObjectMapper();
        /*
        {
          "name" : "맥도날드 슈비버거",
          "price" : 5500,
          "ingredients" : [ "통새우 패티", "순쇠고기 패티", "토마토", "스파이시 어니언 소스" ]
        }
        */
        ObjectNode objectNode = objectMapper.createObjectNode();
        objectNode.put("name", "맥도날드 슈비버거");
        objectNode.put("price", 5500);

        ArrayNode arrayNode = objectMapper.createArrayNode();
        arrayNode.add("통새우 패티");
        arrayNode.add("순쇠고기 패티");
        arrayNode.add("토마토");
        arrayNode.add("스파이시 어니언 소스");

        //두번째 인자가 Node인 경우에는 put보다 set메소드를 사용하는것이 좋다
        objectNode.set("ingredients", arrayNode);
        //Json을 object노드로 만든다
        String json = objectNode.toString();

objectMapper의 createObjectNode를 이용해 ObejctNode 객체를 만들고,
put(key값,value값)으로 JSON 객체를 만든다.
그리고 배열을 JSON 객체에 넣기 위해서는 ArrayNode를 만들고 add로 배열 원소를 하나씩 넣은 후 set으로 ObjectNode에 넣어주면 된다.
그리고 마지막에는 objectNode 대상으로 toString을 이용해서 json으로 바꿔준다.

요약

  • 자바 객체를 JSON으로 변환 : ObjectMapper의 writeValueAsString(자바객체)
  • JSON을 자바 객체로 변환 : ObjectMapper의 readValue(JSON, 자바 객체 클래스타입);
  • ObjectNode랑 ArrayNode로 JSON 을 만들 수 있다.

0개의 댓글