ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @RequiredArgsConstructor, @NotNull, @Valid ,@NotBlank
    Java&Spring/Spring 2023. 2. 15. 17:42

    어노테이션들을 항상 정리하고 외우지만, 기억 보다는  기억을 이라는 말이 있다. 정리를 한번 하고 가자.

     

    1. 생성자의 활용

    Class 의 기본 전제는 객체를 사용하는데 있어 생성자가 필연적이다 라는 것을 전제로 하자.

     

    생성자라는 것은 클라스당 하나 라는 편견은 버리자.

    다음과 같이 객체를 넘겨서 생성 하는 방식과 모든 인자값 을 넘겨 받는 방식이 존재한다.

    이러한 방식을 생성자 오버로딩이라 한다.

    public static class PrivateTodoResponse{
        private Long private_todo_id ;
        private String task;
        private LocalDate date;
        private String imageUrl;
        private Boolean complete;
        private String name;
        
        public PrivateTodoResponse(PrivateTodo privateTodo)
        {
            this(privateTodo.getId(),privateTodo.getTask(),privateTodo.getDate(),privateTodo.getImageUrl(),privateTodo.getComplete(),privateTodo.getMember().getName());
        }
        
        public PrivateTodoResponse(Long id , String task, LocalDate date, String imageUrl, Boolean complete,String name) 
        {
            this.name = name;
            this.private_todo_id =id;
            this.task = task;
            this.date = date;
            this.imageUrl = imageUrl;
            this.complete = complete;
        }
    }

    위의 코드를 변경하기전 먼저 롬북의 @Data 를 보자.

     

    /**
     * Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
     * all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
     * <p>
     * Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
     * <p>
     * Complete documentation is found at the project lombok features page for @Data.
     * 
     * @see Getter
     * @see Setter
     * @see RequiredArgsConstructor
     * @see ToString
     * @see EqualsAndHashCode
     * @see lombok.Value
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Data {
       /**
        * If you specify a static constructor name, then the generated constructor will be private, and
        * instead a static factory method is created that other classes can use to create instances.
        * We suggest the name: "of", like so:
        * 
        * <pre>
        *     public @Data(staticConstructor = "of") class Point { final int x, y; }
        * </pre>
        * 
        * Default: No static constructor, instead the normal constructor is public.
        * 
        * @return Name of static 'constructor' method to generate (blank = generate a normal constructor).
        */
       String staticConstructor() default "";

     

    Getter, Setter 를 기본으로 RequiredArgsConstructor 를 전부 지원한다.

     

     

    @RequiredArgsConstructor :

    final 이 들어간 필드이거나,  @NonNull. 이 붙은 필드의 Argument 들의 생성자를 만든다. 즉 다음과 같다.

    코드는 DTO 를 목적으로 만든 코드이다.   (추가로 @NonNull 이랑 @NotNull 은 서로 다르다 )

    -> 참고 : https://whitepro.tistory.com/279

     

    @Getter
        public static class PrivateTodoPostRequestDto
        {
            final private String task;
            final private LocalDate date;
            public PrivateTodoPostRequestDto(String task , LocalDate date){
                this.task =task;
                this.date = date;
            }
        }

     

    ->생성자를 없에고 @RequiredArgsConstructor  를 붙여 준다.

    @Getter
    @RequiredArgsConstructor
    public static class PrivateTodoPostRequestDto
    {
        final private String task;
        final private LocalDate date;
    }

    이때  다음 처럼 task 의 값이 없이 request 를 보낼 수 있으며, task 의 값은 null 이 들어간다.

    {
    "date":"2021-12-17"
    }

     

    위의 코드에  Not Null 을 붙여보자

    @Getter
    @RequiredArgsConstructor
    @NotNull
    public static class PrivateTodoPostRequestDto
    {
        final private String task;
        final private LocalDate date;
    }

    -> task 값에 null 이 들어간상태로 에러가 나지 않는다.

     

     

    NotNull 어노테이션을 DTO 필드에 붙여두어도, 해당 DTO를 받아내는 메서드 파라미터 위치에 @Valid 어노테이션을 추가하지 않으면 검증이 동작하지 않는다.

     

    1. @Valid 를 추가 해준후 ,

    public ApiResponse addPrivateTodo(@RequestHeader("Authorization") String firebaseToken,
                                      @Valid @RequestBody PrivateTodoPostRequestDto request) {
        Member member = memberService.findOneByToken(firebaseToken);
        PrivateTodo privateTodo = privateTodoService.saveTodo(member,request.getTask(),request.getDate());

     

    2. NotNull 을 필드 바로 상단으로 넣어준다. (class 의 밖에 선언을 하면 error 가 걸리지 않는다.)

    @Getter
    @RequiredArgsConstructor
    public static class PrivateTodoPostRequestDto
    {   @NotNull
        final private String task;
        final private LocalDate date;
    }

    request 를 다음과 같이 보내면

    {
    "date":"2021-12-17"
    }
     
     
    "org.springframework.web.bind.MethodArgumentNotValidException "  을 만날 수 있다.
     
     
     
    NotNull 의 경우는 null 이 아닌 경우 즉 , "" 와  " " 둘다 받을 수 잇다.
    Sting 의 경우는 @NotEmpty 를 적어주자! 
     
     
     
    -> 최종 코드는 다음과 같다.
    @Getter
    @RequiredArgsConstructor
    public static class PrivateTodoPostRequestDto
    {   @NotBlank
        final private String task;
        @NotNull
        final private LocalDate date;
    }
     
     
     
Designed by Tistory.