WebSphere 上使用 Spring (MVC) 的 JSR 303 验证
JSR 303 Validation with Spring (MVC) on WebSphere
我正在尝试使用 WAS 8.5.5.12 完整配置文件中的 Spring MVC 控制器进行 JSR 303 bean 验证。
我只验证一个@RequestParam,而不是一个完整的 bean:
@RequestMapping(method=RequestMethod.GET)
public String initializeCheckIn(
@Valid @Pattern(regexp = "^[\p{Alnum}]*$")
@RequestParam("officeid") String officeId, HttpSession session, Model model) {
在我添加一些 Spring-specific configuration 之前,没有验证发生,但也没有任何错误。据推测,根本没有尝试验证。
现在我已经添加了必要的@Validated class 注释和 bean 定义:
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
我收到以下错误:
[8/9/17 10:33:40:588 CDT] 000000a7 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause Spring MVC Dispatcher: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org.hibernate.validator.method.MethodConstraintViolationException
...
Caused by: java.lang.NoClassDefFoundError: org.hibernate.validator.method.MethodConstraintViolationException
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at my.package.web.CheckInController$$EnhancerBySpringCGLIB$$d385737c.initializeCheckIn(<generated>)
基于
Spring 应该自动检测可用的 JSR-303 提供程序,this version of WebSphere (8.5.5.12 full profile) should have。它似乎无法找到该 JSR-303 提供程序,因此它正在回退到默认值。
那么关于为什么找不到 WebSphere 版本或如何找到它的任何想法?
首先,您必须强制使用随附的 Hibernate Validator 5 而不是 WebLogic。只需添加 WEB-INF/validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration http://www.jboss.org/xml/ns/javax/validation/configuration/validation-configuration-1.0.xsd">
<default-provider>org.hibernate.validator.HibernateValidator</default-provider>
</validation-config>
很可能,您需要在 deployment.xml 中将 classloaderMode 设置为 PARENT_LAST 。如果是 EAR,它应该看起来像
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1" deploymentId="0" startingWeight="1">
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1" deploymentId="1" startingWeight="10000" uri="foureyes-ri.war" classloaderMode="PARENT_LAST"/>
</deployedObject>
</appdeployment:Deployment>
我不确定,但我将 validation-api 1.1.0 打包到 WAR,它对我有用。
我想我终于找到了可行的解决方案。看来我需要明确地告诉 Spring MethodValidationPostProcessor
bean 使用容器提供的 javax.validation.ValidatorFactory
,显然我可以从 JNDI lookup of "java:comp/ValidatorFactory".
<jee:jndi-lookup id="validatorFactory" jndi-name="java:comp/ValidatorFactory" resource-ref="false"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>
(顺便说一句,基于this simple JNDI lookup JSP,在这个版本的WebSphere中,实现class是org.apache.bval.jsr303.ApacheValidatorFactory
)
编辑:我在博客条目中写下了整个过程:https://dougbreaux.github.io/2018/05/23/springmvc-jsr303-websphere.html
我正在尝试使用 WAS 8.5.5.12 完整配置文件中的 Spring MVC 控制器进行 JSR 303 bean 验证。
我只验证一个@RequestParam,而不是一个完整的 bean:
@RequestMapping(method=RequestMethod.GET)
public String initializeCheckIn(
@Valid @Pattern(regexp = "^[\p{Alnum}]*$")
@RequestParam("officeid") String officeId, HttpSession session, Model model) {
在我添加一些 Spring-specific configuration 之前,没有验证发生,但也没有任何错误。据推测,根本没有尝试验证。
现在我已经添加了必要的@Validated class 注释和 bean 定义:
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
我收到以下错误:
[8/9/17 10:33:40:588 CDT] 000000a7 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause Spring MVC Dispatcher: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org.hibernate.validator.method.MethodConstraintViolationException
...
Caused by: java.lang.NoClassDefFoundError: org.hibernate.validator.method.MethodConstraintViolationException
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at my.package.web.CheckInController$$EnhancerBySpringCGLIB$$d385737c.initializeCheckIn(<generated>)
基于
Spring 应该自动检测可用的 JSR-303 提供程序,this version of WebSphere (8.5.5.12 full profile) should have。它似乎无法找到该 JSR-303 提供程序,因此它正在回退到默认值。
那么关于为什么找不到 WebSphere 版本或如何找到它的任何想法?
首先,您必须强制使用随附的 Hibernate Validator 5 而不是 WebLogic。只需添加 WEB-INF/validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration http://www.jboss.org/xml/ns/javax/validation/configuration/validation-configuration-1.0.xsd">
<default-provider>org.hibernate.validator.HibernateValidator</default-provider>
</validation-config>
很可能,您需要在 deployment.xml 中将 classloaderMode 设置为 PARENT_LAST 。如果是 EAR,它应该看起来像
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1" deploymentId="0" startingWeight="1">
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1" deploymentId="1" startingWeight="10000" uri="foureyes-ri.war" classloaderMode="PARENT_LAST"/>
</deployedObject>
</appdeployment:Deployment>
我不确定,但我将 validation-api 1.1.0 打包到 WAR,它对我有用。
我想我终于找到了可行的解决方案。看来我需要明确地告诉 Spring MethodValidationPostProcessor
bean 使用容器提供的 javax.validation.ValidatorFactory
,显然我可以从 JNDI lookup of "java:comp/ValidatorFactory".
<jee:jndi-lookup id="validatorFactory" jndi-name="java:comp/ValidatorFactory" resource-ref="false"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>
(顺便说一句,基于this simple JNDI lookup JSP,在这个版本的WebSphere中,实现class是org.apache.bval.jsr303.ApacheValidatorFactory
)
编辑:我在博客条目中写下了整个过程:https://dougbreaux.github.io/2018/05/23/springmvc-jsr303-websphere.html