この記事は、Spring Framework(非Boot)のREST API開発で以下のようなリクエストパラメータ(@RequestParam
)に対する入力チェックを行いたい場合の設定方法に関するメモです。
Java
@RequestMapping(value = "/text",method = RequestMethod.GET,produces="text/plain;charset=utf-8")
public ResponseEntity<Object> aaa(
@Valid @Size(max=5,message ="{E001}") @RequestParam(name = "name", required = false) String name,
@Valid @Max(5) @RequestParam(name = "age", required = false)Integer age) {
///処理
}
servlet-context.xml
に以下を追加する。
まず、以下の設定が必須です。未設定の場合、@Valid @Size(max=5)
などと記述してコンパイルが成功していても、実行時にバリデーションが効きません。
<annotation-driven />
<!-- バリデーションに使用するメッセージファイルの指定 -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:messages" />
<beans:property name="cacheSeconds" value="0" />
<beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>
<!-- Bean Validationを使うための設定 -->
<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<beans:property name="validationMessageSource" ref="messageSource" />
</beans:bean>
<!-- @RequestParamでバリデーションするために必要な設定 -->
<beans:bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<beans:property name="validator" ref="validator" />
</beans:bean>
pom.xml
に以下を追加する。
Bean Validation APIは、Jakarta Bean Validation APIに移行になった模様。
しかし今回はjakarta版ではなく、従来のjavax版を使う。
hibernate-validator
のバージョンが7.0.4.Final
以降の場合、jakarta版しか使えない。
6.2.0.Final
にしておくとjavax版が使えるようになる。
今回はjavax版を使うのでhibernate-validator
のバージョンは6.2.0.Final
にする。
<!-- 入力チェック(Validation)を有効にするための設定 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.0.Final</version>
</dependency>
<!-- @SizeなどのValidation用アノテーションを有効にするための設定 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
jakarta版を使用するとエラー
javax版ではなくjakarta版の以下を追加してもバリデーションは効かない。
この場合、hibernate-validator
のバージョンも7.0.4.Final
以降にしておく必要がある。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.4.Final</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.2</version>
</dependency>
だがしかし上記設定で実行すると、以下のようなエラーが出る。
Java
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.validation.beanvalidation.MethodValidationPostProcessor] from ClassLoader [WebappClassLoader
context: restapp
delegate: false
----------> Parent Classloader:
java.net.URLClassLoader@27716f4
]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485)
at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:267)
... 32 more
Caused by: java.lang.NoClassDefFoundError: javax/validation/Validator
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.getDeclaredMethods(Class.java:1975)
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467)
... 34 more
Caused by: java.lang.ClassNotFoundException: javax.validation.Validator
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1166)
... 38 more
つまり、必要なのはjavax版であって、jakarta版ではないということ。
import文も注意
javax版が必要だということは、impot文も以下のようにjavax.validation
を読み込む必要がある。
Java
// 以下を読み込む必要がある。
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Size;
jakarta版の以下はバリデーションが効かない。
Java
// これだとバリデーションが効かない
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Size;
健闘を祈る
以上で記事の解説はお終い!
もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!