`
jinnianshilongnian
  • 浏览: 21504495 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2418726
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3008884
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5639527
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:259944
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597372
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250234
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5859004
Group-logo
跟我学Nginx+Lua开...
浏览量:702030
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785237
社区版块
存档分类
最新评论

Spring3.1 对Bean Validation规范的新支持(方法级别验证)

阅读更多

 


上接
Spring提供的BeanPostProcessor的扩展点-1继续学习。

 

一、Bean Validation框架简介

 写道
Bean Validation standardizes constraint definition, declaration and validation for the Java platform.

大体意思是:Bean Validation 标准化了Java平台的约束定义、描述、和验证。

 

详细了解请参考:http://beanvalidation.org/

 

Bean Validation现在一个有两个规范:

 

1Bean Validation 1.0JSR-303

 写道
This JSR will define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.

定义了基于注解方式的JavaBean验证元数据模型和API,也可以通过XML进行元数据定义,但注解将覆盖XML的元数据定义。

 

详细了解请参考:http://jcp.org/en/jsr/detail?id=303

 

JSR-303主要是对JavaBean进行验证,如方法级别(方法参数/返回值)、依赖注入等的验证是没有指定的。因此又有了JSR-349规范的产生。

 

2Bean Validation 1.1JSR-349

 写道
Bean Validation standardizes constraint definition, declaration and validation for the Java platform.

Bean Validation 标准化了Java平台的约束定义、描述、和验证。

 

此规范目前处于草案状态,详细了解请参考:http://jcp.org/en/jsr/detail?id=349.

 

该草案现在主要内容:

方法级别验证支持(验证方法参数和和返回值);

依赖注入验证的支持。

  

Bean Validation的详细介绍可参考Bean Validation官网查看http://beanvalidation.org/


Spring3.1目前已经完全支持依赖注入验证和方法级别验证的支持,只是不是原生的(规范还是草案)。


Bean Validation 1.0的参考实现有Hibernate Validator(下载地址:http://www.hibernate.org/subprojects/validator.html);1.1还处于草案状态。

 

二、Bean Validation在开发中的位置


 


 

 

上图摘自hibernate validator 参考文档,从图中可以看出,我们可以在任何位置实施验证。

 

1、表现层验证:SpringMVC提供对JSR-303的表现层验证;

2、业务逻辑层验证:Spring3.1提供对业务逻辑层的方法验证(当然方法验证可以出现在其他层,但笔者觉得方法验证应该验证业务逻辑);

3DAO层验证:Hibernate提供DAO层的模型数据的验证(可参考hibernate validator参考文档的7.3. ORM集成)。

4、数据库端的验证:通过数据库约束来进行;

5、客户端验证支持:JSR-303也提供编程式验证支持。

 

对于DAO层和客户端验证支持不在我们示例范围,忽略,感兴趣的同学可以参考《hibernate validator reference》(有中文)。

  

在测试支持大家需要准备好如下jar包:

validation-api-1.0.0.GA.jar

hibernate-validator-4.2.0.Final.jar

 

四、Spring3.0支持表现层验证

可以参考我的《最新SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结》或《SpringMVC 使用JSR-303进行校验 @Valid》。

 

此处不再阐述。

 

五、Spring3.0支持依赖注入验证(Bean Validation 1.1草案)

Spring3.0开始支持对依赖注入的依赖进行验证。Spring对依赖注入验证支持请参考《Spring开闭原则的表现-BeanPostProcessor扩展点-2》中的BeanValidationPostProcessor

 

示例:

1Bean组件类定义

public class UserModel {
    @NotNull(message = "user.username.null")
    @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")
    private String username;
    @Size(min = 5, max=10, message = "password.length.illegal")
    private String password;
    //省略setter/getter
}

 2、开启依赖注入验证支持(spring-config-bean-validator.xml

<!--注册Bean验证后处理器-->
<bean class="org.springframework.validation.beanvalidation.BeanValidationPostProcessor"/>

 3BeanXML配置定义(spring-config-bean-validator.xml

<bean id="user" class="com.sishuok.validator.UserModel">
    <property name="username" value="@"/>
    <property name="password" value="#"/>
</bean>

 4、测试用例

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {"classpath:spring-config-bean-validator.xml"})
public class BeanValidatorTest {
    @Autowired
    UserModel user;
    @Test
    public void test() {
    }
}

 5、运行测试后,容器启动失败并将看到如下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
……
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'user' defined in class path resource [spring-config-bean-validator.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Bean state is invalid: password - password.length.illegal; username - user.username.illegal
……
Caused by: org.springframework.beans.factory.BeanInitializationException: Bean state is invalid: password - password.length.illegal; username - user.username.illegal

 我们可以看出 用户名验证失败。

 

六、Spring3.1支持方法级别验证(Bean Validation 1.1草案)

Spring3.1开始支持方法级别的验证。Spring对方法级别的验证支持请参考《Spring开闭原则的表现-BeanPostProcessor扩展点-2》中的MethodValidationPostProcessor

 

有了方法级别验证,我们就能够更加简单的在Java世界进行契约式设计了,关于契约式设计请参考《建造无错软件:契约式设计引论》。

 

没有MethodValidationPostProcessor之前我们可能这样验证:

public UserModel get(Integer uuid) {
    //前置条件
    Assert.notNull(uuid);
    Assert.isTrue(uuid > 0, "uuid must lt 0");

    //获取 User Model
    UserModel user = new UserModel(); //此处应该从数据库获取

    //后置条件
    Assert.notNull(user);
    return user;
}

前置条件和后置条件的书写是很烦人的工作。

 

有了MethodValidationPostProcessor之后我们可以这样验证:

public @NotNull UserModel get2(@NotNull @Size(min = 1) Integer uuid) {
    //获取 User Model
    UserModel user = new UserModel(); //此处应该从数据库获取
    return user;
}

 

前置条件的验证:在方法的参数上通过Bean Validation注解进行实施;

后置条件的验证:直接在返回值上通过Bean Validation注解进行实施。 

非常好,非常好,自此我们可以在Java世界进行更完美的契约式编程了。

 

示例:

1Service类定义

@Validated      //① 告诉MethodValidationPostProcessor此Bean需要开启方法级别验证支持
public class UserService {
    public @NotNull UserModel get2(@NotNull @Min(value = 1) Integer uuid) { //②声明前置条件/后置条件
        //获取 User Model
        UserModel user = new UserModel(); //此处应该从数据库获取
        if(uuid > 100) {//方便后置添加的判断(此处假设传入的uuid>100 则返回null)
            return null;
        }
        return user;
    }
}

 2、开启Spring3.1对方法级别验证支持(spring-config-method-validator.xml

<!--注册方法验证的后处理器-->
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

 3BeanXML配置定义(spring-config-method-validator.xml

<bean id="userService" class="com.sishuok.validator.UserService"/>

 4、测试用例

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {"classpath:spring-config-method-validator.xml"})
public class MethodValidatorTest {
    @Autowired
    UserService userService;
    @Test
    public void testConditionSuccess() {//① 正常流程 
        userService.get2(1);
    }
    @Test(expected = org.hibernate.validator.method.MethodConstraintViolationException.class)
    public void testPreCondtionFail() { //②错误的uuid(即前置条件不满足)
        userService.get2(0);
    }

    @Test(expected = org.hibernate.validator.method.MethodConstraintViolationException.class)
    public void testPostCondtionFail() { //③不满足后置条件的返回值
        userService.get2(10000);
    }
}

通过如上测试,我们可以看出Spring3.1已经非常好的支持契约式编程了。

 

注意,在使用方法级别验证时:

1、由于Bean Validation1.1正处于草案状态,Spring3.1无法支持原生的Bean Validation1.1,在未来的Bean Validation1.1发布时会直接使用原生的。

2Spring3.1需要使用Hibernate Validator 4.2及更高版本。

 

让我们期待Bean Validation 1.1的发布吧。

 

 

 

17
6
分享到:
评论
19 楼 javatozhang 2016-10-19  
dohongdayi 写道
jinnianshilongnian 写道
dohongdayi 写道
@Validated
@Transactional
public interface UserService {

	UserModel login(@NotBlank String account, @NotEmpty String password);

}


我在以下接口应用MethodValidationPostProcessor和Spring注解式事务后发现:

验证参数之前就先开启了事务(获得了DB连接),我认为应该先验证输入,验证失败后直接抛出异常,验证成功再开启事务,这样对业务层的性能才更好,不知道楼主怎么看,Spring这样设计的理由是什么?

这个可以修改它们的order来完成;不能使用<tx:ann……> 注册 ,手工注册相应的bean指定order即可


经过不懈努力,终于将验证切面放在了事务切面外:


<!-- 这个标签上可以写order,默认是Integer.MAX_VALUE -->
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="validator" class="com.gmail.dohongdayi.ssh.common.validation.ValidatorFactoryBean">
	<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
	<!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties
	<property name="validationMessageSource" ref="messageSource" /> -->
</bean>

<bean id="validationPointcut" class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut">
	<constructor-arg index="0" value="org.springframework.validation.annotation.Validated" />
	<constructor-arg index="1" value="true" />
</bean>


<bean id="validationAdvice" class="org.springframework.validation.beanvalidation.MethodValidationInterceptor">
	<constructor-arg index="0" ref="validator" />
</bean>

<!-- 替代MethodValidationPostProcessor,让验证切面的advisor加入到Spring AOP的AspectJAwareAdvisorAutoProxyCreator的advised -->
<aop:config>
	<!-- 通过order指定验证优先于事务(100 < Integer.MAX_VALUE) -->
	<aop:advisor pointcut-ref="validationPointcut" advice-ref="validationAdvice" order="100" />
</aop:config>

厉害超级赞
18 楼 javatozhang 2016-10-19  
yxb1990 写道
有一个大坑,在spring mvc post方法中,配置了@NotBlank username的注解后,如果前端不写username字段, 则不会进入这个post方法,搞了一天。

问题描述的不太清晰呀
17 楼 javatozhang 2016-10-19  
liveandevil 写道
help help!!!
为什么我这么写不起作用?
@Service
@Validated
public class BusinessServiceImpl implements BusinessService {
/** {@inheritDoc} */
@NotNull(message="Null returns are not permitted")
public String convertToUpperCase(@NotEmpty(message="Input must not be null or empty.")String input) {

if ("returnnull".equalsIgnoreCase(input)) {
return null;
}
return input.toUpperCase();
}

}
配置文件是:
<!-- 指定自己定义的validator --> 
    <mvc:annotation-driven validator="validator"/>
 
    <!-- 以下 validator  ConversionService 在使用 mvc:annotation-driven 会 自动注册--> 
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties --> 
        <property name="validationMessageSource" ref="messageSource"/> 
    </bean>
    <!--注册方法验证的后处理器--> 
    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

个人认为<!-- 指定自己定义的validator -->
    <mvc:annotation-driven validator="validator"/>
  是控制层代码, 而<!--注册方法验证的后处理器--> 
    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>是你业务逻辑层代码是不是配置文件配置问题。
16 楼 yxb1990 2015-03-24  
有一个大坑,在spring mvc post方法中,配置了@NotBlank username的注解后,如果前端不写username字段, 则不会进入这个post方法,搞了一天。
15 楼 liveandevil 2014-07-17  
help help!!!
为什么我这么写不起作用?
@Service
@Validated
public class BusinessServiceImpl implements BusinessService {
/** {@inheritDoc} */
@NotNull(message="Null returns are not permitted")
public String convertToUpperCase(@NotEmpty(message="Input must not be null or empty.")String input) {

if ("returnnull".equalsIgnoreCase(input)) {
return null;
}
return input.toUpperCase();
}

}
配置文件是:
<!-- 指定自己定义的validator --> 
    <mvc:annotation-driven validator="validator"/>
 
    <!-- 以下 validator  ConversionService 在使用 mvc:annotation-driven 会 自动注册--> 
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties --> 
        <property name="validationMessageSource" ref="messageSource"/> 
    </bean>
    <!--注册方法验证的后处理器--> 
    <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
14 楼 wenxiang_tune 2014-05-12  
loginuser.username.illegal=用户名长度必须在${min}到${max}之间
输出的错误是
message: "用户名长度必须在$min到$max之间"
没有对${}做处理,怎么解决呢?
13 楼 dohongdayi 2014-02-16  
jinnianshilongnian 写道
dohongdayi 写道
@Validated
@Transactional
public interface UserService {

	UserModel login(@NotBlank String account, @NotEmpty String password);

}


我在以下接口应用MethodValidationPostProcessor和Spring注解式事务后发现:

验证参数之前就先开启了事务(获得了DB连接),我认为应该先验证输入,验证失败后直接抛出异常,验证成功再开启事务,这样对业务层的性能才更好,不知道楼主怎么看,Spring这样设计的理由是什么?

这个可以修改它们的order来完成;不能使用<tx:ann……> 注册 ,手工注册相应的bean指定order即可


经过不懈努力,终于将验证切面放在了事务切面外:


<!-- 这个标签上可以写order,默认是Integer.MAX_VALUE -->
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="validator" class="com.gmail.dohongdayi.ssh.common.validation.ValidatorFactoryBean">
	<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
	<!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties
	<property name="validationMessageSource" ref="messageSource" /> -->
</bean>

<bean id="validationPointcut" class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut">
	<constructor-arg index="0" value="org.springframework.validation.annotation.Validated" />
	<constructor-arg index="1" value="true" />
</bean>


<bean id="validationAdvice" class="org.springframework.validation.beanvalidation.MethodValidationInterceptor">
	<constructor-arg index="0" ref="validator" />
</bean>

<!-- 替代MethodValidationPostProcessor,让验证切面的advisor加入到Spring AOP的AspectJAwareAdvisorAutoProxyCreator的advised -->
<aop:config>
	<!-- 通过order指定验证优先于事务(100 < Integer.MAX_VALUE) -->
	<aop:advisor pointcut-ref="validationPointcut" advice-ref="validationAdvice" order="100" />
</aop:config>
12 楼 jinnianshilongnian 2014-02-15  
dohongdayi 写道
@Validated
@Transactional
public interface UserService {

	UserModel login(@NotBlank String account, @NotEmpty String password);

}


我在以下接口应用MethodValidationPostProcessor和Spring注解式事务后发现:

验证参数之前就先开启了事务(获得了DB连接),我认为应该先验证输入,验证失败后直接抛出异常,验证成功再开启事务,这样对业务层的性能才更好,不知道楼主怎么看,Spring这样设计的理由是什么?

这个可以修改它们的order来完成;不能使用<tx:ann……> 注册 ,手工注册相应的bean指定order即可
11 楼 dohongdayi 2014-02-13  
@Validated
@Transactional
public interface UserService {

	UserModel login(@NotBlank String account, @NotEmpty String password);

}


我在以下接口应用MethodValidationPostProcessor和Spring注解式事务后发现:

验证参数之前就先开启了事务(获得了DB连接),我认为应该先验证输入,验证失败后直接抛出异常,验证成功再开启事务,这样对业务层的性能才更好,不知道楼主怎么看,Spring这样设计的理由是什么?
10 楼 hellostory 2013-09-13  
jinnianshilongnian 写道
osacar 写道
PTZhuf 写道
jinnianshilongnian 写道
osacar 写道
jinnianshilongnian 写道
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。


这样的话确实是个问题啊。因为通常做开发的时候一个实体会有一二十个属性是很平常的。就如上面说的那个user,还可能有email,city,qq,msn,ip,credit等属性,如果只更新其中的一部分属性,那也要单独收集?那这个校验不是用不上了?还得单独再校验,岂不是又回到了原来的老路上了?我想请教一下一般是怎么解决的。


1、最简单的方式 是把所有数据传到界面;
2、不开启自动验证,而是自己手工调用验证API进行验证。

这个问题是无法避免的


这个问题是不是考虑使用Constrain中的groups?通过validated传入不同的阶段,使得在bean的生命周期的不同阶段,采用不同的验证方案。

不过@Validated似乎无法使用在返回值的后置验证上,要做后置验证还是得用原生的注解@NotNull之类的,这样在返回bean的时候就没办法对内部属性(设置了group的)做验证了。spring 4.0 M1也出了,已经支持了JSR349,不知道是否有什么改善。



我还是用传统的那种验证方法。
注解验证还是不能解决上面的问题。
就是后端做验证太悲催了。。。

嗯 缺点很明显,要么全部,要么没有; 没有提供开关控制;。。。。


不是有个叫做VO的东西吗?


9 楼 jinnianshilongnian 2013-05-31  
osacar 写道
PTZhuf 写道
jinnianshilongnian 写道
osacar 写道
jinnianshilongnian 写道
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。


这样的话确实是个问题啊。因为通常做开发的时候一个实体会有一二十个属性是很平常的。就如上面说的那个user,还可能有email,city,qq,msn,ip,credit等属性,如果只更新其中的一部分属性,那也要单独收集?那这个校验不是用不上了?还得单独再校验,岂不是又回到了原来的老路上了?我想请教一下一般是怎么解决的。


1、最简单的方式 是把所有数据传到界面;
2、不开启自动验证,而是自己手工调用验证API进行验证。

这个问题是无法避免的


这个问题是不是考虑使用Constrain中的groups?通过validated传入不同的阶段,使得在bean的生命周期的不同阶段,采用不同的验证方案。

不过@Validated似乎无法使用在返回值的后置验证上,要做后置验证还是得用原生的注解@NotNull之类的,这样在返回bean的时候就没办法对内部属性(设置了group的)做验证了。spring 4.0 M1也出了,已经支持了JSR349,不知道是否有什么改善。



我还是用传统的那种验证方法。
注解验证还是不能解决上面的问题。
就是后端做验证太悲催了。。。

嗯 缺点很明显,要么全部,要么没有; 没有提供开关控制;。。。。
8 楼 osacar 2013-05-31  
PTZhuf 写道
jinnianshilongnian 写道
osacar 写道
jinnianshilongnian 写道
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。


这样的话确实是个问题啊。因为通常做开发的时候一个实体会有一二十个属性是很平常的。就如上面说的那个user,还可能有email,city,qq,msn,ip,credit等属性,如果只更新其中的一部分属性,那也要单独收集?那这个校验不是用不上了?还得单独再校验,岂不是又回到了原来的老路上了?我想请教一下一般是怎么解决的。


1、最简单的方式 是把所有数据传到界面;
2、不开启自动验证,而是自己手工调用验证API进行验证。

这个问题是无法避免的


这个问题是不是考虑使用Constrain中的groups?通过validated传入不同的阶段,使得在bean的生命周期的不同阶段,采用不同的验证方案。

不过@Validated似乎无法使用在返回值的后置验证上,要做后置验证还是得用原生的注解@NotNull之类的,这样在返回bean的时候就没办法对内部属性(设置了group的)做验证了。spring 4.0 M1也出了,已经支持了JSR349,不知道是否有什么改善。



我还是用传统的那种验证方法。
注解验证还是不能解决上面的问题。
就是后端做验证太悲催了。。。
7 楼 PTZhuf 2013-05-27  
jinnianshilongnian 写道
osacar 写道
jinnianshilongnian 写道
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。


这样的话确实是个问题啊。因为通常做开发的时候一个实体会有一二十个属性是很平常的。就如上面说的那个user,还可能有email,city,qq,msn,ip,credit等属性,如果只更新其中的一部分属性,那也要单独收集?那这个校验不是用不上了?还得单独再校验,岂不是又回到了原来的老路上了?我想请教一下一般是怎么解决的。


1、最简单的方式 是把所有数据传到界面;
2、不开启自动验证,而是自己手工调用验证API进行验证。

这个问题是无法避免的


这个问题是不是考虑使用Constrain中的groups?通过validated传入不同的阶段,使得在bean的生命周期的不同阶段,采用不同的验证方案。

不过@Validated似乎无法使用在返回值的后置验证上,要做后置验证还是得用原生的注解@NotNull之类的,这样在返回bean的时候就没办法对内部属性(设置了group的)做验证了。spring 4.0 M1也出了,已经支持了JSR349,不知道是否有什么改善。
6 楼 jinnianshilongnian 2012-07-27  
osacar 写道
jinnianshilongnian 写道
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。


这样的话确实是个问题啊。因为通常做开发的时候一个实体会有一二十个属性是很平常的。就如上面说的那个user,还可能有email,city,qq,msn,ip,credit等属性,如果只更新其中的一部分属性,那也要单独收集?那这个校验不是用不上了?还得单独再校验,岂不是又回到了原来的老路上了?我想请教一下一般是怎么解决的。


1、最简单的方式 是把所有数据传到界面;
2、不开启自动验证,而是自己手工调用验证API进行验证。

这个问题是无法避免的
5 楼 osacar 2012-07-27  
jinnianshilongnian 写道
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。


这样的话确实是个问题啊。因为通常做开发的时候一个实体会有一二十个属性是很平常的。就如上面说的那个user,还可能有email,city,qq,msn,ip,credit等属性,如果只更新其中的一部分属性,那也要单独收集?那这个校验不是用不上了?还得单独再校验,岂不是又回到了原来的老路上了?我想请教一下一般是怎么解决的。
4 楼 jinnianshilongnian 2012-07-27  
osacar 写道
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?



username无论如何 都得有值。
你说的这种情况会报错。

你说的这种修改密码的情况,可以通过只收集password完成。
3 楼 osacar 2012-07-27  
    public class UserModel {  
        @NotNull(message = "user.username.null")  
        @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
        private String username;  
        @Size(min = 5, max=10, message = "password.length.illegal")  
        private String password;  
        //省略setter/getter  
    }  

上面在username上定义了@NotNull注解,那么在添加user的时候是必须的,但是如果在修改这个user时,username就不用再校验了,也就是说,form不会把username给post到后台,只post了password这个属性。这样会不会报user.username.illegal?

2 楼 jinnianshilongnian 2012-05-30  
dzj2046 写道
{This JSR will define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.

定义了基于注解方式的JavaBean验证元数据模型和API,也可以通过XML进行元数据定义,但注解将覆盖XML的元数据定义。}
这句话对吗?是不是应该为:XML的元数据定义会覆盖注解定义的

你试一下 按照上边说的 是 注解将继承并覆盖xml方式的
1 楼 dzj2046 2012-05-30  
{This JSR will define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.

定义了基于注解方式的JavaBean验证元数据模型和API,也可以通过XML进行元数据定义,但注解将覆盖XML的元数据定义。}
这句话对吗?是不是应该为:XML的元数据定义会覆盖注解定义的

相关推荐

    Bean Validation 规范文档

    综上所述,《Bean Validation规范详解》不仅为开发者提供了全面的技术指南,也为Bean Validation的使用者和贡献者构建了一个坚实的知识基础,帮助他们在实际项目中更好地应用这一强大的验证框架。

    最新 spring3.1 完整jar包

    7. **JSR-303/JSR-349 Bean Validation集成**:Spring 3.1集成了JSR-303/JSR-349标准,为模型对象提供了内置的数据验证支持。 8. **异步方法调用**:Spring 3.1引入了异步方法调用,通过`@Async`注解,开发者可以在...

    spring 3.1中文文档

    5. **模型验证的声明式支持**:为了简化MVC应用中的数据验证,Spring 3.1提供了声明式的模型验证支持,开发者可以在控制器方法参数上使用注解来进行自动验证。 6. **Java EE 6的支持**:Spring 3.1预先支持了Java ...

    Struts2.3.1与Spring3.1整合时需要的jar包

    Struts2.3.1与Spring3.1的整合是Java Web开发中常见的技术结合,目的是为了实现MVC(Model-View-Controller)框架的高效管理和控制,以及依赖注入(Dependency Injection,DI)的便捷性。这两者的整合使得开发者能够...

    springmvc3.1+hibernate3环境搭建架包

    3.1版本引入了一些增强的功能,例如改进的类型安全的HandlerMapping,支持RESTful Web服务,以及对JSR 303/JSR 349 Bean Validation的支持。 首先,为了搭建Spring MVC 3.1环境,你需要以下核心库: 1. spring-web...

    spring-3.1.0中文版api帮助文档.pdf

    此外,Spring还提供了BeanValidation集成支持,便于进行数据验证。 #### 三、面向切面编程(AOP)在Spring 3.1中的应用 Spring AOP是Spring框架的一个关键组成部分,用于实现横切关注点的模块化。Spring 3.1对AOP的...

    spring-framework-reference.pdf

    - **Java-based Bean Metadata**:Spring 3.0引入了一种基于Java的新方法来定义bean元数据,这种方法使用注解来替代XML配置文件。 - **Declarative Model Validation**:Spring 3.0增强了模型验证功能,支持基于注解...

    spring杂谈

    7. **BeanValidation**:Spring 3.1开始支持Bean Validation规范,允许在方法级别进行验证,提高了验证的灵活性和粒度。 8. **事务管理发展历程**:Spring对事务管理的支持经历了从编程式到声明式的演变,包括JDBC...

    spring-3.1.0中文版api帮助文档

    - **验证机制**:整合JSR 303或JSR 349的Bean Validation API,进行数据校验。 **2.9 回调接口集合及触发顺序** - **回调机制**:列出Spring支持的各种回调接口,如BeanNameAware、BeanFactoryAware等,并解释其...

    spring3_mvc_lib_支持注解方式

    除了上述注解,Spring 3还引入了对JSR-303/JSR-349(Java Bean Validation)的支持,允许开发者通过注解进行数据验证,如`@NotNull`、`@Size`等。 在提供的文件列表中,我们可以看到Spring框架的核心库,例如`org....

    Spring3.0新特性

    9. Java EE 6 支持:Spring 3.0 提前支持了 Java EE 6 的一些新特性,如 CDI 和 EJB 3.1。 10. 嵌入式数据库支持:允许在开发和测试环境中使用如 H2 或 Derby 等轻量级嵌入式数据库。 三、针对 Java 5 的核心 API ...

    Spring jsr-303的帮助文档

    Spring 框架通过集成 Bean Validation 规范,为开发者提供了强大的验证功能支持。 #### 二、约束定义 ##### 2.1 约束注解 **约束注解** 是 Bean Validation 的基础构建块,用于标记需要进行验证的字段或属性。...

    spring3.0最新lib包

    6. **JSR-303/JSR-349 Bean Validation集成**:Spring 3.0集成了JSR-303(在3.1版升级为JSR-349),提供了一种标准的方式来验证Java Bean的属性,增强了数据校验的能力。 7. **WebSocket支持**:虽然Spring 3.0本身...

    Spring开发文档

    JSR303(Java Bean Validation)是Java标准,Spring MVC可以集成JSR303,实现对模型对象的校验。 总之,Spring MVC为开发者提供了一套完整的Web应用程序开发框架,通过其强大的特性和易用的API,帮助开发者构建高效...

    spring 杂谈,求扩散

    7. **BeanValidation**:Spring 3.1引入了对Bean Validation规范的支持,提供了方法级别的验证,能够对入参进行校验,提高了代码的健壮性。 8. **事务管理的发展历程**:Spring从早期的手动事务管理到现在的声明式...

    Spring 3.0 新特性

    Spring 3.0开始支持JSR-303 Bean Validation标准,允许开发者在服务层对输入数据进行校验,提高了业务逻辑的健壮性。 9. **国际化(i18n)** 提供了更强大的国际化支持,包括新的`MessageSource`接口和改进的`...

    dwr2.0整合Struts1.3+hibernate3.1+spring2.5的项目

    Spring 2.5版本加强了对JSR-303(Bean Validation)和AspectJ的支持,使得代码更加模块化,降低了耦合度。 **整合过程** 1. **Spring与Hibernate整合**:Spring可以通过其Hibernate Template或JdbcTemplate来管理...

    Spring_Framework_ API_5.0.5 (CHM格式)

    Bean Validation 1.1 与 Java 基准类似,许多其他框架的基准也有变化。例如: Hibernate 5 Jackson 2.6 EhCache 2.10 JUnit 5 Tiles 3 另外,请记下各种服务器最低支持版本。 Tomcat 8.5+ Jetty ...

Global site tag (gtag.js) - Google Analytics