티스토리 뷰
[spring] 전자정부프레임워크 @Valid 적용법 및 에러(HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.String'.)
첸첸 2022. 10. 13. 13:48@Valid는 객체 단계에서 프러퍼티의 유효성을 검사 할 수 있어서 로직이 지저분해지는걸 막을 수 있다.
1️⃣ maven
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
2️⃣ bean 설정
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- Integration Apache Commons Validator by Spring Modules -->
<bean id="beanValidator" class="org.springmodules.validation.commons.DefaultBeanValidator">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>
<bean id="validatorFactory" class="org.springmodules.validation.commons.DefaultValidatorFactory">
<property name="validationConfigLocations">
<list>
<!-- 경량환경 템플릿 밸리데이터 설정 -->
<value>classpath:/egovframework/validator/validator-rules-let.xml</value>
<value>classpath:/egovframework/validator/let/**/*.xml</value>
</list>
</property>
</bean>
<!-- Invokes Spring MVC @Controller methods -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<!-- Configures Spring MVC DataBinder instances -->
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator" />
</bean>
</property>
</bean>
<!-- Creates the JSR-303 Validator -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
</beans>
3️⃣
1. vo
- ⭐import를 주의하자! (import org.hibernate.validator.constraints.NotBlank;)
- @NotBlank는 String에 붙이는 것으로 null과 공백을 제거한 문자열의 길이가 0이면 안된다.
- message를 붙여주면 메세지를 커스터마이징 할 수 있다. 붙이지 않는 경우 기본 메세지
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
@Data
public class ShareImageVO {
@NotBlank(message = "roomUuid는 필수값 입니다.")
private String roomUuid;
@NotBlank(message = "이미지 url은 필수값 입니다.")
private String imageUrl;
private String imageName;
}
2. controller
- 객체에 @Valid 어노테이션을 붙여주면, 컨트롤러 로직을 타기 전에 유효성 검사를 실시한다.
@RestController
@RequestMapping("api/v1/")
public class ApiController {
@RequestMapping(value ="share/image", method = RequestMethod.POST)
public ApiResponse shareImage(@RequestBody @Valid ShareImageVO shareImage) {
ApiResponse apiResponse = new ApiResponse();
apiResponse.setCode(HttpStatus.OK.value());
apiResponse.setMessage(HttpStatus.OK.name());
websocketController.shareImage(shareImage);
return apiResponse;
}
}
📌Error
-@Valid를 적용한 경우 유효성 검사에 실패하면 발생 하는 에러는 MethodArgumentNotValidException 이다.
그런데 나는...계속 UnexpectedTypeException가 났다..심지어 roomUuid와 imageUrl에 값을 넣었는데도 UnexpectedTypeException 에러가 났다...why..
HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.String'.
검색을 해보니 보통 String 타입이 아닌 다른 타입에 String 타입에만 사용해야하는 @notEmpty, @notBlank를 사용해서 나는 것 같았다. 그렇지만 나는 String 타입에 사용했는데..?
문제는 import를 잘못해서 생긴 발생했다.
org.hibernate.validator.constraints.NotBlank;를 임포트 해야하는데 아래와 같이 javax.validation.constraints.NotBlank를 임포트 했다.import를 변경 해주니 제대로 정상 작동 했다.
import의 중요성...블로거들이 대부분 import를 작성 안하는데, 작성해주면 좋겠다.😂
@ControllerAdvice
@ResponseBody
public class ApiExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String errorMessage = e.getBindingResult()
.getAllErrors()
.get(0)
.getDefaultMessage(); //vo에서 설정한 메세지를 가져온다.
ApiResponse apiResponse = new ApiResponse();
apiResponse.setCode(HttpStatus.BAD_REQUEST.value());
apiResponse.setMessage(errorMessage);
return ResponseEntity.badRequest().body(apiResponse);
}
}
'백엔드 > spring' 카테고리의 다른 글
전자정부프레임워크 프로파일 분리하기 | 스프링 프로파일 분리하기 | properties 분리 (0) | 2022.11.28 |
---|---|
세션 만료 전 알림 및 로그아웃 기능 구현하기 (0) | 2022.11.09 |
No default constructor found; nested exception is java.lang.NoSuchMethodException (0) | 2022.09.28 |
illegal character in query at index (0) | 2022.09.16 |
controller에서 @value 사용하기 (0) | 2022.08.10 |
- Total
- Today
- Yesterday
- Kubernetes
- springboot
- 코딩테스트
- Spring
- 스프링
- 자바
- 전자정부프레임워크
- 아파치카프카
- 코테
- 도커
- 쿠버네티스
- java 코테
- 리액트
- 현대코테
- softeer
- centos
- 자바코테
- javascript
- tomcat
- 톰캣
- 현대오토에버
- java
- Linux
- softeer java
- mysql
- 자바스크립트
- react
- Docker
- 오토에버코테
- 현대
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |