TIL 2021.03.25

Kyu·2021년 3월 25일
0

TIL

목록 보기
74/322

Json, Jackson

미션에서 ajax를 이용하여 답변을 리팩토링하는 과정 중에 Json 데이터를 넘겨주는 방법에 대해서 배웠다. 무작정 필드에 @JsonProperty, @JsonIgonore 을 붙이고 넘기는 부분이 궁금증이 생겨 좀 더 자히 알아보았다.

스프링에서 컨트롤러를 이용해서 html 를 리다이렉트 해주는 형식이 아니라 데이터 전달 목적으로 사용할 수 가 있다. 이때, 그 데이터의 형식을 그냥 문자열로 보내도 상관이 없다. 보통은 XML이나 JSON 형태로 많이 보낸다. 데이터 구조를 표현하는 이유는 데이터 사용을 편리하게 하기 위함이다.

JSON 데이터 구조를 표현하면 아래와 같다.

{
  "name":"Kyu",
  "age":20,
  "isDeveloper":true,
  "equipment":["Laptop", "Brain"],
  "etc":{
    "favoriteFood":'Water'
  }
}

Jackson은 Json의 데이터를 처리해주는 라이브러리이다.
스프링에서 데이터를 저장하기 위해서 데이터를 담는 클래스를 만들어 준다. 단순히 name, age라는 필드가 있고 생성자 그리고 게터가 들어있는 클래스가 있다고 치자.
이때 Jackson 라이브러리를 이용하지 않으면

String JSON = "\"{"+
    "\"name\": \"" + person.getName() + "\","+
    "\"job\": \"" + person.getJob() + "\""+ 
"}\"";

GSON, SimpleJSON

이런식으로 노가다해서 Json 데이터를 만들어줘야한다. 매번 이렇게 작성할 수 없으니 자동으로 저렇게 변환해주는 api가 있는데 그게 GSON이나 SimpleJSON이다. 참고로 SimpleJSON을 이용해서 코드로 표현하면 다음과 같다.

JSONObject jsonObject = new JSONObject();
jsonObject.put("name", person.getName());
jsonObject.put("job", person.getJob());
String JSON = jsonObject.toString();

스프링에서 이렇게 코딩해서 리턴해도 데이터를 넘겨줄수있다고 한다.

Jackson

Jackson도 GSON이나 SimpleJSON처럼 작동한다고 하는데 다른점은 스프링3.0부터 Jackson과 관련된 api를 제공해서 SimpleJSON처럼 jsonObject.put("name", person.getName()); 이런식으로 키와 밸류를 입력해주는 식이아니라 자동으로 어노테이션만 달아주면 바로 가져올 수 있도록 자동화했다고 한다.

그래서 아까전에 처음에 name과 job만 있던 그 인스턴스를 그냥

@RequestMapping("/json")
@ResponseBody()
public Object printJSON() {
    Person person = new Person("Kyu", 20);
    return person;
}

라고 해주면 바로 데이터를 반환해줄 수 있다.

자바는 프로퍼티를 제공하는 문법이없고 보통 Getter와 Setter의 이름명명규칙에 의해서 정해진다. 그래서 굳이 필드의 변수이름을 개똥이라고 지어도 getter에 명명규칙에 의한 이름으로 프로퍼티를 제대로 네이밍했다면 상관이없다. 그래서 아래와 같이 코딩해도 문제가 없다.

public class Person {
   public String getName() {
       return "Kyu";
  }
   
   public int getAge() {
       return 20;
  }
}

@RequestMapping("/json")
@ResponseBody()
public Object printJSON() {
   return new Person();
}

@JsonProperty

그런데 Jackson의 데이터매핑을 Getter가 아닌 필드로 하고 싶다면 어떨까?
이때 @JsonProperty 어노테이션을 사용할 수 있다.

public class Person {
    @JsonProperty("name")
    private String myName = "Kyu";
}

이 때 Json 데이터는 {"name":"Kyu"}로 출력된다. 그냥 @JsonProperty 라고 적으면 필드의 이름인 myName이 프로퍼티가 된다.

그런데 미션하면서 모든필드에 JsonProperty를 일일이 다 붙여줬는데 이것도 @JsonAudoDetect 라는 어노테이션으로 해결할수있다.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Person {
    private String name = "Kyu";
    private int age = 20;
    private String job = "Developer";
}

이렇게하면 모든 필드가 @JsonProperty가 붙은 효과를 낸다.
@JsonAutoDetect는 필드뿐만아니라 Getter,Setter에도 자동으로 데이터매핑이 되는데 이것은 @JsonIgnore로 해결할 수 있다.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Person {
    private String myName = "Kyu";
    
    @JsonIgnore
    public String getJob() {
        return "Developer";
    }
}

하지만 또 일일이 JsonIgnore을 해줘야하는 상황이라면 JsonAutoDetect의 정책을 바꿔서 해결할수있따.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NON_PRIVATE)
public class Person {
    private String myName = "Kyu";
    
    public String getJob() {
        return "Developer";
    }
}

그외에 @JsonInclude(JsonInclude.Include.NON_NULL) 라고 붙이면 필드에 NULL이 못들어오도록 할 수도 있다.

출처: https://mommoo.tistory.com/83

profile
TIL 남기는 공간입니다

0개의 댓글