定递归验证关联的对象可以用于继承对象吗 spring validate

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定递归验证关联的对象可以用于继承对象吗 spring validate相关的知识,希望对你有一定的参考价值。

参考技术A Spring数据校验

spring拥有自己独立的数据校验框架,同时支持JSR303标注校验。springDataBinder在进行数据绑定时,可同时调用校验框架完成数据校验工作。在spring mvc中则可直接通过注解驱动的方式进行数据校验

Validator校验接口

boolean supports(Class<?> clazz):该校验器能够对clazz类型的对象进行校验

void validate(Object target,Errors errors):对目标对象进行校验,并将校验错误记录到errors

LocalValidatorFactoryBean

LocalValidatorFactoryBean既实现了spring的validator接口,也实现了JSR303的Validator接
口。只要在spring 容器中定义一个LocalValidatorFactoryBean,即可将其注入到需要校验的Bean中。

<bean id="validator"

class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

Spring mvc数据校验

<mvc:annotation-driven>会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解即可让spring mvc执行数据校验工作。

public String handle91(@Valid @ModelAttribute(“user”)Useruser,BindingResult bindingResult)

if(bingingResult.hasErrors)

return“/user/register”;



return “/user/showUser”



将入参对象添加@Valid注解,同时紧跟其后声明一个BindingResult的入参,根据BingingResult即可判断是否存在错误。绑定接口既可以是BindingResult也可以Errors类型

在页面显示错误

spring
mvc除了会将表单/命令对象的校验结果保存在对应的BindingResult或Errors中,还会将所有校验结果保存到隐含模型中,也就是说即使处
理方法的签名没有对应于表单/命令对象的校验结果入参,校验结果也不会丢失,它们始终可以在隐含模型中获取。隐含模型中所有数据最终通过
HttpServletRequest的属性列表暴露给JSP视图对象。

通过国际化资源显示错误信息

每个属性在数据绑定和数据校验发生错误时,都会产生一个对应的FieldError对象,FieldError实现了
org.springframework.context.MessageSourceResolvable接口。
MessageSourceResolvable是可用国际化资源进行解析对象。

MessageSourceResolvable提供3个接口

Object getArguments():返回一组参数对象

String[] getCodes():返回一组消息代码,每个代码对应一个资源属性,可以使用getArguments()返回的参数对资源属性进行参数替换

String getDefaultMessage():默认消息

当一个属性校验失败后,校验框架会为该属性生成4个消息代码,这些代码以校验注解类名为前缀,结合类名、属性名、属性类型名生成多个消息代码

如User类的password属性标注了一个@Pattern的注解,当校验失败后会产生如下4个错误代码

Parttern.user.password

Parttern.password

Parttern.java.lang.String

Parttern

当使用Sprng mvc标签显示错误信息时,Spring mvc查看web上下文是否装配了对应国际化消息,如果没有,则显示默认的错误消息,否则使用国际化消息对错误代码进行翻译。

如果在数据类型转换或数据类型格式时发生错误,或者该有的参数不存在,或者调用处理方法时发生错误,都会在隐含模型中创建错误消息,其错误代码前缀说明如下:

required:必要的参数不存在,如@RequestParam(“param1”)标注了一个入参,当请求参数不存在时

typeMismatch:在数据绑定时发生数据类型不匹配

methodInvocation:spring mvc在调用方法时发生错误

示例

如果”aaa”非数字参数传递给User的salary属性,将发生数据转换的错误,Spring将为该错误生成如下错误代码

typeMismatch.user.salary

typeMismatch.salary

typeMismatch.long

typMismatch

装配国际化资源

<bean id="messageSource"

class="org.springframework.context.support.ResourceBundleMessageSource">

<propertyname="basename">

<value>conf/i18n/messages</value>

</property>

</bean>

也可以通过basenames属性指定多个国际化资源

在conf/i18n下添加基名为messages的国际化资源,一个默认的messages.properties,另一个对应messages_zh_CN.properties

自定义校验规则

通过@InitBinder注解的initBinder方法中装配自定义MyValidator

@InitBinder

public void initBinder(WebDataBinder binder)

binder.setValidtor(newXXX());//在进行数据绑定时使用的校验器



也可以借助请求处理方法的签名传递一个Errors或BindingResult对象进来,然后在处理方法中直接校验。

public String handle92(@ModelAttribute(“user”Useruser,BindingResult bindingResult))

ValidationUtils.rejectIfEmptyOrWritespace(bindingResult,”username”,”required”);

//产生的错误信息对象错误代码包括

//required.user.username

// required.username

// required.java.lang.String

// required

if(“aaa”.equalsIgnoreCase(user.getUsername()))

bindingResult.rejectValue(“username”,”reserved”);

//产生的错误代码如下

//reserved.user.username

// reserved.username

// reserved.java.lang.String

// reserved



if(bindingResult.hasErrors())

return “/user/register4”;

else

return “/user/showUser”;





binder.setValidator()方法设置自定义的Validtor后,spring mvc将使用它对入参进行校验,将不在使用spring mvc框架装配的Validator对入参对象进行校验,即使入参标注了@Valid注解也不会校验本回答被提问者采纳

封装继承多态

封装是面向对象的三大特性之一

封装指的是隐藏对象中的一些不希望被外部所访问的属性或方法

如果隐藏一个对象中的属性?

将对象的属性名,修改为一个外部不知道的名字

如何获取(修改)对象中的属性?

  • 需要提供一个getter和setter方法使外部可以访问到属性

  • getter 获取对象中指定属性(getter_属性名)

  • setter 用来设置对象中指定属性(setter_属性名)

使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全性

  1. 隐藏了属性名,使用调用者无法随意的修改对象的属性确保了数据的安全性

  2. 增加了getter和setter方法,很好的控制了属性是否是只读的

    1. 如果希望属性是只读的,则可以直接去掉setter方法

    2. 如果希望属性不能被外部访问,则可以直接去掉getter方法

  3. 使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的。

  4. 使用getter方法获取属性,使用setter方法设置属性

    1. 可以在读取属性和修改属性的同时做一些其他的处理

  5. 使用getter方法可以表示一些计算的属性

class Dog:
‘‘‘
表示狗的类
‘‘‘
def __init__(self,name):
self.hidden_name = name
def say_hello(self):
print(‘大家好,我是%s‘%hidden_name)
def get_name(self):
‘‘‘
get_name()用来获取对象的name属性
‘‘‘
return self.hidden_name
def set_name(self,name)
self.hidden_name = name
d = Dog(‘旺财‘)
d.say_hello()

可以为对象的属性使用双下划线开头,__xxx

双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部进行访问,无法通过对象进行访问

其实隐藏属性只不过是python自动为属性改了一个名字

实际上将名字修改为,_类名__属性名

class person:
def __init__(self,name):
self.__name = name
def get_name(self)
return self.__name
def set_name(self,name)
self.__name = name
p = person(‘孙悟空‘)
#print(p.__name)__开头的属性是隐藏属性,无法通过对象访问
#p.__name = ‘猪八戒‘
print(p.set_name())
?

继承是面向对象三大特性之一

  • 通过继承我们可以使一个类获取到其他类中的属性和方法

  • 在定义类时,可以在类名后的括号中指定当前类的父类(超类,基类,supper)

    • 子类(衍生类)可以直接继承父类中的所有的属性和方法

 

通过继承可以直接让子类获取到父类的方法或属性,避免编写重复性的代码,并且也符合opc原则

所有我们经常需要通过继承来对一个类进行扩展

class Dog(Animal):
def bark(self):
print(‘汪汪汪····‘)
d = Dog()
print(d)

在创建类时,如果省略了父类,则默认父类为object。object是所有类的父类,所有类都继承自object

class Person(object):

pass

issubclass()检查一个类是否是类一个类的子类

isinstance()检查一个对象是否是一个类的实例,如果这个类时这个对象的父类,也会返回True,所有的对象都是object的子类

多态是面向对象的三大特征之一

多态从字面上理解是多种形态

一个对象可以以不同的形态去呈现

定义一个函数,只要对象中含有name属性,他就可以作为参数传递

这个函数并不会考虑对象的类型,只要name属性即可

def say_hello(obj):
print(‘你好%s‘%obj.name)

def say_hello_2(obj):
#做类型检查
if isinstance(obj,A):
print(‘你好%s‘%obj.name)
#say_hello(b)

鸭子类型

如果一个东西,走路像鸭子,叫声像鸭子,那么他就是鸭子

len()

之所以一个对象能通过len()来获取长度,是因为对象中具有一个特殊方法——len—— 换句或说,只要对象中具有len特殊方法,就可以通len()来获取它的长度

面向对象的三大特征:

封装

确保了对象中的数据安全

继承

保证了对象的可扩展性

多态

保证了程序的灵活性

 

以上是关于定递归验证关联的对象可以用于继承对象吗 spring validate的主要内容,如果未能解决你的问题,请参考以下文章

将两个对象与继承和聚合相关联是不好的编程习惯吗?

递归python函数中的持久对象

java面向对象与设计模式

面向对象——对继承关联聚合组合依赖的理解

封装继承多态

验证一个对象是不是有一个或多个关联对象