[Spring] @Valid

2021. 4. 11. 18:43Spring

Spring @Valid 메세지 커스텀하기

개요

  • React + SpringBoot 개발하고 있었기 때문에 프론트에서 회원가입이나 로그인할 때 데이터 값을 넘겨받을 때 유효성 검사를 하고 에러가 있으면 그 에러가 있는 필드에 대한 message를 넘겨주는 부분이다.

문제

  • 만약 유효성 검사가 맞지 않는다면

    {
      time": "2021-04-05 06:25:21",
        "status": 400,
        "errorMessage": "비밀번호가 일치하지 않습니다."
    }

    JSON 형태로 프론트 개발자분들에게 넘겨주어야 한다. 혼자 개발할 때는 타임리프를 사용해서 Model에 담아서 사용했으면 되었지만 이부분을 JSON형태로 만들고 시간과 status, message를 어떻게 넘겨야할지가 고민이었다.

해결방법

  • Controller.java
 //위에 로그인 메서드와 마찬가지로 하려고합니다.
    @PostMapping("/api/signup")
    public Object usersignup(@Valid @RequestBody UserSignupRequestDto requestDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            String errorMessage = allErrors.get(0).getDefaultMessage();
            return new CreateError().error(errorMessage);
        }

        boolean flag = userService.checkPassword(requestDto);
        if (!flag) {
            return new CreateError().error("비밀번호가 일치하지 않습니다.");
        }
        User saveUser = userService.save(requestDto);
        return saveUser;

    }
  • UserSignupRequestDto.java
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserSignupRequestDto {
    @NotBlank(message = "이름은 필수 입력입니다.")
    @Pattern(regexp = "[a-zA-Z0-9]*",message = "username은 숫자 또는 문자만 가능합니다.")
    private String username;

    @NotBlank(message = "비밀번호는 필수 입력입니다.")
    @Pattern(regexp = "^.*(?=^.{4,15}$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$", message = "비밀번호는 4~15자리의 숫자,문자,특수문자로 이루어져야합니다.")
    private String password;

    @NotBlank(message = "이메일은 필수 입력입니다.")
    @Email(message = "email 형식을 지켜주세요.")
    private String email;

    @NotBlank(message = "비밀번호 확인은 필수입니다.")
    private String pwcheck;

}
  • CreateError.java
public class CreateError {
    public ResponseEntity error(String errorMessage) {
        HttpStatus status = HttpStatus.BAD_REQUEST;
        CustomErrorResponse errors = new CustomErrorResponse(errorMessage,status.value());
        return ResponseEntity
                .status(status)
                .body(errors);
    }

}
  • Controller와 Dto가 있다. 첫번째로 Controller에서 @RequestBody UserSignupRequestDto requestDto 이 부분에서 프론트에서 보낸 회원가입 데이터를 받습니다. 그리고 Dto에서의 Vaild속성을 체크하게 됩니다. 만약 여기서 Valid에 적합하지 않다면 BindingResult bindingResult 에 error로 담아집니다. 그리고 에러메세지를 allErrors.get(0).getDefaultMessage(); 이렇게 받아옵니다. (여기서 에러메세지가 여러개이면 여러개 받을 수 있게 해야합니다.. ㅠㅠㅠ)
  • CreateError.java를 보면 HttpStatus를 400에러를 내어 프론트에서 에러가 났다고 인식하게끔합니다. 그리고 CustomErrorResponse 객체를 보면
@Getter
@Setter
public class CustomErrorResponse {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private LocalDateTime time;
    private int status;
    private String errorMessage;

    public CustomErrorResponse(String errorMessage, int status)
    {
        this.time = LocalDateTime.now();
        this.errorMessage = errorMessage;
        this.status = status;
    }


}
  • 이렇게 JSON형태로 메세지를 만들어내는 객체입니다. 그리고 CreateError.java에서 ResponseEntity를 return합니다.

마무리

  • 이제 ARC나 Talented API Tester로 API에 데이터를 넣어서 확인해보면

    {
      time": "2021-04-05 06:25:21",
        "status": 400,
        "errorMessage": "비밀번호가 일치하지 않습니다."
    }

    이렇게 나오게 됩니다.

추가

  • 이 부분을 조금 더 깔끔하게 코딩한 결과물을 업데이트 하겠습니다.!

'Spring' 카테고리의 다른 글

[Spring Boot]S3 버킷 생성  (0) 2021.06.02
[Spring boot] stomp를 활용해서 1:1 채팅 만들기  (3) 2021.04.25
[Spring] Bcrypt로 암호화하기  (0) 2021.04.11
Spring으로 Token 받기  (0) 2021.04.11
spring jpa localtime between  (0) 2021.03.23