-
Spring boot 스프링 부트에서 request Validation 요청값 검증하기프로그래밍/서버 프로그래밍 2019. 2. 18. 14:22
Spring boot 스프링 부트에서 request Validation 요청값 검증하기 @Valid이용
안녕하세요. 오늘은 Spring boot 에서 request에 들어오는 요청값을 검증하는 법을 알아보겠습니다.
현재 제가 공부로 진행중인 프로젝트에서 소스를 조금 가져오겠습니다.먼저
AccountController
에 있는createAccount
메소드를 가져오겠습니다.@PostMapping public ResponseEntity createAccount(@RequestBody @Valid AccountDto dto, Errors errors) { if (errors.hasErrors()) { return ResponseEntity.badRequest().build(); } Account account = accountService.save(dto); return ResponseEntity.ok( AccountDto.builder() .displayName(account.getDisplayName()) .email(account.getEmail()) .build() ); }
현재 소스코드에서 보면
@RequestBody
와@Valid
어노테이션이AccountDto
요청값에 붙어있는데,@RequestBody
어노테이션은@RequestMapping
에 의해 POST 방식으로 전송된 HTTP 요청 데이터를 제가 지정해준AccouontDto
에 맞춰서 변환해주는 역할을 합니다.@Valid
어노테이션이 바로 요청데이터를 검증하는 어노테이션입니다.여기서 그냥
@Valid
어노테이션을 붙인다고해서 바로 검증을 할 수 있는 것은 아니고 실제AccountDto
에도 필드별로 검증하기 위해 다양한 어노테이션을 붙여줍니다.@Getter @Setter @Builder @AllArgsConstructor public class AccountDto { @NotEmpty @NotBlank private String displayName; @NotEmpty @NotBlank @Email private String email; @NotEmpty @NotBlank @JsonIgnore private String password; public Account toEntity(){ return Account.builder() .displayName(this.displayName) .password(this.password) .email(this.email) .build(); } }
각 필드마다 위에
@NotEmpty
,@Email
,@NotBlank
등 다양한 어노테이션이 보입니다.
실제로@javax.validation.constraints.
까지 입력하시고,Ctrl + Space
키를 눌러보시면 하단에이렇게 많은 어노테이션이 존재합니다.
각 어노테이션은 이름에서도 대충 유추를 할 수 있지만, 더 자세히 알고 싶으시면 여기를 더 참고하시면 좋을 것 같습니다.
이제 이런식으로 각 요청값을
@Valid
어노테이션을 이용하여서 걸러낼 수 있다는 것을 알아봤는데 , 만약 요청값이@Email
인데 이메일 형식이 아닌값이 들어오는 등, 요청값이 검증에 실패할 경우엔 어떻게 될까요?위의 컨트롤러 소스코드를 다시보시면
createAccount
의 두번째 인자로Errors
를 받고 있는 것을 보실 수 있습니다.Validation 과정에서 실패하거나 에러가 발생하면 이
Errors
에 에러들이 담기기 때문에 저같은 경우는errors.hasErrors()
를 이용해서 에러 발생시 예외처리를 해주고 있습니다.하지만 위에
javax.validation.constraints.*
에 제가 필요한 검증이 어노테이션으로 존재하지 않는 경우에는 어떤 방식으로 검증을 해야할까요?최근
백기선님의 REST API
강의를 하면서 배웠던 방식을 한번 보겠습니다. 예를 들기 위해 임의로Event
라는 객체를 아주 간단히 만들어 보겠습니다.@Builder @NoArgsConstructor @AllArgsConstructor @Getter @Setter @Entity public class Event { @Id @GeneratedValue private Long id; private String name; private String description; private LocalDate startDate; private LocalDate endDate; }
이를 요청값으로 받을 때는
Entity
클래스가 DTO클래스를 따로 생성하는게 좋기 때문에 이번에는EventDto
클래스를 만들어 보겠습니다.@Getter @Setter @Builder @NoArgsConstructor @AllArgsConstructor public class EventDto { @NotEmpty private String name; @NotEmpty private String description; @NotNull private LocalDate startDate; @NotNull private LocalDate endDate;
현재는 위에 방식과 마찬가지로
@Valid
를 사용한 방식만을 사용하고 있습니다.
하지만 현재 만일 startDate 보다 endDate가 더 이른 날짜가 들어온다면 이를 검증할 수 없다는 문제가 있습니다.( startDate = 20190218, endDate = 20190201)이를 해결하기 위하여 저희는
EventValidator
라는 클래스를 생성할 것입니다.@Component public class EventValidator { public void validate(EventDto eventDto, Errors errors){ if(endDate.isBefore(startDate)){ errors.rejectValue("endDate", "wrongValue", "endDate is wrong"); } }
이런식으로
EventValidator
를@Component
로 등록해준 뒤,EventController
에서 불러와 사용할 수 있습니다.@Autowired private EventValidator eventValidator; @PostMapping public ResponseEntity createEvent(@RequestBody @Valid EventDto eventDto, Errors errors) { if(errors.hasErrors()) { return ResponseEntity.badRequest().body(errors); } eventValidator.validate(eventDto, errors); if(errors.hasErrors()){ return ResponseEntity.badRequest().body(errors); } ...이벤트 생성코드 작성... return ResponseEntity.ok().build();
현재는
startDate
와endDate
만 검증을 해봤는데, 실제로 필요한 검증을 직접 추가하시고 소스코드도 더 리팩토링하셔서 사용을 하시면 될 것 같습니다!이상으로 오늘은 스프링 부트에서 요청값을 검증하는 방법에 대하여 알아봤습니다!
아직 모르는게 많아 게시글에 잘못된 정보가 있을 수 있습니다. 혹시 잘못된 정보가 있다면, 댓글 혹은 메일로 알려주시면 최대한 빨리 수정하겠습니다!
'프로그래밍 > 서버 프로그래밍' 카테고리의 다른 글
@Valid 에서 받은 Errors를 Serialize해서 ResponseEntity에 담자! (0) 2019.02.19 스프링 시큐리티 요청 URI별 권한 처리할 때 문제상황 해결! (0) 2019.02.19 DTO란 (0) 2019.02.15 Spring Boot JPA 사용법 (0) 2018.12.20 Spring 스프링 MyBatis 와 JPA-Hibernate (0) 2018.12.18