엄범

 

[Java] 객체를 key:value 형태로 json String으로 serialize하고 싶다면?  

 

 

  • 주의해야 할 점?
    • `` @Size``같은건, controller에서 `` @Valid``매핑할 때 동작하지, 직접 `` new``로 객체를 생성할 때는 동작하지 않는다
    • 그래서 이런 제약을 걸기위해 setter를 써야 하는 상황도 있고, annotation을 써야 하는 상황도 있다.

 

@Builder
  • 빌더를 사용하면서, 필수값은 필수로 받고, 옵셔널 값은 없으면 기본값으로 초기화 하고 싶다면!?
    • 필드에 `` =``으로 기본값으로 초기화하려면, 대상 필드에 ``java @Builder.Default``를 사용해야 하는데...
      • 이 방식은 @Builder.Default는 쓰지 않는 것이 좋다 라는 얘기도 있고, ``java f1 = f2.getName()`` 요런 식으로 다른 필드의 속성을 이용해서 또 다른 필드를 초기화하는건 불가능하다. (빌더가 static이라, static context에서 non-static 필드를 참조할 수가 없당)
    • 그래서 필수값만 받고 옵셔널 값은 기본값으로 초기화하려면! `` builderMethodName``을 지정해주면 된다.
  • 직접 정의한다면... item2/builder/NutritionFacts.java  
  • @Builder 애너테이션을 사용하면서, @NoArgsConstructor가 필요한 경우 이 것만 붙이면 에러가 발생하므로 @AllArgsConstructor도 같이 붙여주어야 한다 . + @Data 까지 4개 붙여주는게 일반적

 

Null, 빈값 관련

애너테이션이 어떤 제약조건을 가지고 있는지 확인하려면 그냥 애너테이션 소스 확인해보면 된다.

  • `` @NotBlank``
    • @NotNull + "" 및 " " 허용하지 않음
  • `` @NonNull``의 전체 적용?
  • Controller에서 @RequestBody로 바로 객체로 매핑하는 경우 애초에 input json에 포함이 안되어 있는 필드는 setter 거치지 않고 바로 null을 할당한다.
    • @NonNull이 붙어 있는 필드라면 에러가 발생할 것 같지만, 그냥 null이 들어가버린다.
    • 이 때문에 @NonNull 대신 @NotNull을 사용하는 것을 권장
  • int같은 primitive type에는 @NonNull 계열의 애너테이션이 의미가 없으므로(warning뜬다.) 대신 @Min(1)을 쓴다.

 

@Size, @Past, @Min(1) 같은 다양한 @Valid constraint 애너테이션

 

 


 

 

Lombok  간단한 usage 

설치 방법

1. IntelliJ에서 `` Preferences -> Build, Execution, Deployment -> Compiler, Annotation Processors. Click Enable Annotation Processing`` 반드시 해준다. 이걸 안하면 cannot fine symbol 에러 또는 무슨 길이가 다르다느니 하는 빌드 에러가 발생함.

 

2. (생략가능)IntelliJ Perference에서 lombok 플러그인 검색해서 설치한다. 이걸 설치 안하면 컴파일은 가능하지만, lombok에서 만들어준 getter,setter,constructor 등에 접근하려 할 때 IDE가 이를 resolve하지 못해 빨간색으로 뜬다. 다시 말하지만 컴파일은 가능함.

 

3. 여기서 The Lombok Gradle Plugin 부분을 따라하면 된다.  2번을 생략했다면 Gradle without a plugin 부분을 따라하면 된다.

그리고 뭔가 수정했다면 꼭 그냥 빌드가 아니라 Rebuild를 해보기 바란다.

 

lombok 주의 사항
  • 보통 `` Getter, Setter, NoArgsConstructor`` 정도를 많이 사용한다.
  • `` RequiredArgsConstructor``는 final 이거나 @NonNull인 필드에 대해서 생성자를 만들어 준다.
    • Spring에서 생성자DI를 위한 생성자를 만들 때 자주 쓴다.
  • `` AllArgsConstructor``는 사용하지 않기를 권장한다. setter를 안거치고 바로 this.a = a로 할당하기 때문에...
  • 어떤 data class의 경우 생성자를 작성할 필요가 없을 수도 있다.
    • Controller에서 `` @RequestBody``로 바로 객체로 매핑하는 경우, Spring은 생성자를 호출하는게 아니라 각각의 필드에 대해 setter를 호출해서 넣어준다!!! 그래서 이런 경우 생성자가 필요 없다.
  • 사용자 정의 Setter가 있다면, 파라미터가 같든 다르든, @Setter, @Data를 붙여도 기본 타입 세터가 만들어지지 않는다.
    • 즉, 사용자 정의 Setter를 사용하게 된다.

```java

// @Setter 소용 없다.

private int code

 

public void setCode(ResponseCode code) { } // 이게 있으면, @Setter를 붙여도 아래 함수가 자동으로 생성되지 않기 때문에 

public void setCode(int code) { }    // 이렇게 직접 적어주어야만 한다.

```