본문 바로가기
개발/Spring

[Spring] Validation 적용해보기

by devhooney 2022. 8. 18.
728x90

프론트에서만 유효성 검사를 했었는데, 

언제든지 우회할 수 있다고 듣고, 서버쪽에서도 유효성 검사하는 로직을 추가하려했다.

근데 스프링에서는 validation이라는 프레임워크로 편하게 할 수 있었다.

 

그 과정을 남기려고 한다.

 

- 라이브러리 설치(build.gradle)

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.5.2'

 

- 먼저 회원가입을 한다고 하면 User 엔티티가 필요하다.

@Entity
@Getter
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String email;

    @Enumerated(EnumType.STRING)
    @Column
    private Role role;

    @Builder
    public User(Long id, String name, String email) {
        this.name = name;
        this.email = email;
    }
}

 

- 화면에서 받을 DTO를 만들어줬다.

@NoArgsConstructor
@Getter
public class UserRequestDto {
    @NotBlank(message = "이름은 필수 입력값입니다.")
    private String name;

    @NotBlank(message = "이메일은 필수 입력값입니다.")
    @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.")
    private String email;

    public User toEntity(){
        return User.builder()
                .name(name)
                .email(email)
                .build();
    }
}

 

- 여기에서 @NotBlank가 유효성 검사를 해주는 어노테이션이다.

- 종류는 매우 많다.

어노테이션 특징 특이사항
@Size 문자 길이 측정 Int Type 불가
@NotNull Null 불가  
@NotEmpty Null 불가, "" 불가  
@NotBlank Null 불가, "" 불가," " 불가  
@Past 과거날짜만  
@PastOnPresent 오늘이거나 과거 날짜  
@Future 미래 날짜  
@FutureOnPresent 오늘이거나 미래날짜  
@Pattern 정규식 적용  
@Max 최대값  
@Min 최솟값  
@Email 이메일 형식으로  
@AssertTrue/False 별도 Logic 적용  
@Valid 해당 Object Validation 실행  

 

- 컨트롤러는 이렇게 작성했다.

@RestController
@RequestMapping("/api")
public class UserController {
    @Autowired
    UserService userService;

    @GetMapping("/login")
    public String login(@RequestBody Map<String, String> data) {
        System.out.println("data = " + data);
        return "login";
    }

    @PostMapping("/join")
    public Long join(@RequestBody @Valid UserRequestDto userRequestDto, Errors erros) {
        System.out.println("userRequestDto = " + userRequestDto.getEmail());
        if (erros.hasErrors()) {
            System.out.println(" 에러 ");
            return 0L;
        }
        return userService.save(userRequestDto);
    }

    @GetMapping("/users")
    public List<UserResponseDto> findAll() {
        return userService.findAll();
    }


}

 

- 받으려는 DTO앞에 @Valid 또는 @Validation을 붙여준다.

- @Valid, @Validated 차이

1. @Valid는 Java에서 지원해주는 어노테이션이고, @Validated는 스프링에서 지원해준는 어노테이션이다.

2. @Validated는 @Valid의 기능을 포함하기 때문에 @Valid를 적용한 곳이면 @Validated로 변경할 수 있다.

3. @Validated는 유효성을 검토할 그룹을 지정할 수 있는 기능을 추가로 가지고 있다.

 

이러한 특징을 갖고 있다.

 

- Error는반드시 Request 객체 바로 뒤에 위치해야한다.

- 두 개의 객체에 validation 검사를 한다면, 각각의 객체 뒤에 errors를 받는다.

 

- 유효성 검사를 통과하지 못할 경우 0을 리턴해줬다.

 

- 지난번에 사용했던 Swagger UI로 테스트해봤다.

https://devhooney.tistory.com/93

 

[Spring] 스웨거(Swagger) 라이브러리

기존에는 api 테스트를 위해서 포스트맨을 사용했는데, 스웨거는 서버로 요청되는 api 리스트를 html 화면으로 문서화해서 테스트할 수 있는 라이브러리이다. @RestController를 읽어서 api를 분석해서h

devhooney.tistory.com

 

 

- 이렇게 보내면

 

 

- 에러가 뜬다.

- 나는 에러라는 문자를 그대로 찍었지만, Errors 객체에 메시지들이 들어있다. 

 

s = Field error in object 'userRequestDto' on field 'email': rejected value []; 
codes [Pattern.userRequestDto.email,Pattern.email,Pattern.java.lang.String,Pattern]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: 
	codes [userRequestDto.email,email]; 
    arguments []; 
    default message [email],
        [Ljavax.validation.constraints.Pattern$Flag;@332a8d87,
        ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$]; 
    default message [이메일 형식에 맞지 않습니다.]
s = Field error in object 'userRequestDto' on field 'name': rejected value []; 
codes [NotBlank.userRequestDto.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: 
	codes [userRequestDto.name,name]; 
    arguments []; 
    default message [name]]; 
    default message [이름은 필수 입력값입니다.]
s = Field error in object 'userRequestDto' on field 'email': rejected value []; 
codes [NotBlank.userRequestDto.email,NotBlank.email,NotBlank.java.lang.String,NotBlank]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: 
	codes [userRequestDto.email,email]; 
    arguments []; 
    default message [email]]; 
    default message [이메일은 필수 입력값입니다.]

 

- Body에는

 

 

- 0이 담겨있다.

- 유효성검사를 통과할 경우 해당 id가 리턴된다.

 

 

- 제대로 넣으면 쿼리가 나가고, 리턴이 잘된다.

 

 

- 현재 회사에 개발되어 있는 모든 코드를 손봐야겠다.

 

참고 사이트

https://velog.io/@yyong3519/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-validation#valid-validated-%EC%B0%A8%EC%9D%B4

 

스프링부트 Validation

클라이언트로 부터 들어온 데이터를 DB에 저장해야 할 때, 개인정보나 중요한 정보들은 항상 DB에 넣기 전에 올바른 포맷으로 들어왔는지 검증을 해야한다.이메일 데이터에서 @가 없으면 그 데이

velog.io

 

728x90