#스프링부트에서 스프링 밸리데이션 @Valid 어노테이션으로 유효성 검사(Validation) 하는 방법
-클라이언트뿐만 아니라 서버에서도 유효성검사가 필요합니다.
-스프링에서는 @Valid 어노테이션을 사용해서 각 필드에 대한 유효성 검사를 할 수 있습니다.
-다양한 어노테이션을 사용하여 유효성 검사를 할 수 있습니다.
#Spring Validation을 사용하려면 pom.xml에 Maven 의존성을 추가해줘야 합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.5.6</version>
</dependency>
#Controller
-메서드 파라미터 제일 앞에 @Valid 어노테이션을 사용해 줘야지 유효성검사를 할 수 있습니다.
package com.org.test.controller;
import javax.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.org.test.dto.MemberDto;
import com.org.test.dto.Message;
@RestController
public class MemberController {
@PostMapping("/insert")
public ResponseEntity<Message> insertMember(@Valid @RequestBody MemberDto memberDto) {
Message message = new Message();
message.setMessage("성공");
message.setData(memberDto);
return new ResponseEntity<>(message, HttpStatus.OK);
}
}
#Message
package com.org.test.dto;
import lombok.Data;
@Data
public class Message {
private String message;
private Object data;
public Message() {
this.data = null;
this.message = null;
}
}
#MemberDto
-주로 사용하는 @Valid 어노테이션 관련 어노테이션 종류입니다.
* @Null: null만 허용합니다.
* @NotNull: null을 허용하지 않습니다. "", " "는 허용합니다.
* @NotEmpty: null, ""을 허용하지 않습니다. " "는 허용합니다.
* @NotBlank: null, "", " " 모두 허용하지 않습니다.
* @Max(value = ): value 이하의 값을 받을 때 사용됩니다.
* @Min(value = ): value 이상의 값을 받을 때 사용됩니다.
* @Size(min=, max=): 길이를 제한할 때 사용됩니다.
* @Email: 이메일 형식을 검사합니다. 다만 ""의 경우를 통과시킵니다
package com.org.test.dto;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import lombok.Data;
@Data
public class MemberDto {
@NotEmpty
private String name;
@NotEmpty
@Size(min = 4, max = 8)
private String password;
@NotEmpty
private String email;
}
#파라미터 값들이 정상적으로 넘어왔을 경우 반환값입니다.
-정상적으로 통신이 됐다는 200 코드와 함께 데이터들을 반환받았습니다.
#파라미터값들이 유효성검사에서 실패한 경우 반환값입니다.
-실패를 의미하는 400 코드와 함께 에러 메시지를 반환받았습니다.
-password는 4자 이상 8자 이하로만 유효하게 설정해 놨는데 password 값을 3자리로만 보냈을 경우 아래와 같이 password가 벨리데이션에 실패했다는 것을 의미하는 데이터들을 반환되게 됩니다.
{
"timestamp": "2023-04-02T14:41:54.208+00:00",
"status": 400,
"error": "Bad Request",
"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.org.test.dto.Message> com.org.test.controller.MemberController.insertMember(com.org.test.dto.MemberDto): [Field error in object 'memberDto' on field 'password': rejected value [123]; codes [Size.memberDto.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [memberDto.password,password]; arguments []; default message [password],8,4]; default message [크기가 4에서 8 사이여야 합니다]] \r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:141)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:528)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:596)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:833)\r\n",
"message": "Validation failed for object='memberDto'. Error count: 1",
"errors": [
{
"codes": [
"Size.memberDto.password",
"Size.password",
"Size.java.lang.String",
"Size"
],
"arguments": [
{
"codes": [
"memberDto.password",
"password"
],
"arguments": null,
"defaultMessage": "password",
"code": "password"
},
8,
4
],
"defaultMessage": "크기가 4에서 8 사이여야 합니다",
"objectName": "memberDto",
"field": "password",
"rejectedValue": "123",
"bindingFailure": false,
"code": "Size"
}
],
"path": "/insert"
}
댓글