Categories: JavaSpring Framework

【Spring Framework】REST API開発でRequestParamの項目に入力チェックを行う(Method Validation)

この記事は、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がオススメ!同僚に差をつけよう!

issiki_wp