-
@RequiredArgsConstructor, @NotNull, @Valid ,@NotBlankJava&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; }
'Java&Spring > Spring' 카테고리의 다른 글
Q . SpringBoot 에서 경로를 어떻게 인식을 하는 것인가 ? part 1 (0) 2023.08.05 @RequiredArgsConsructor ,@NoArgsConstructor , @AllArgsConstructor (0) 2023.02.15 em.persist 이후 get$ObjsectId() 가 가능 한가? (0) 2023.02.04 스프링부트 GCS 연동 part2 (0) 2023.01.26 스프링부트 GCS 연동 part1 (0) 2023.01.25