1.了解下资源文件加载

  MessageSource   需要国际化处理时使用这个类 (在需要处理国际化的地方使用messageSource.getMessage(this.getResponseCode(),this.getArgs(),"", locale))

    ResourceBundleMessageSource        不能定时刷新资源文件

    ReloadableResourceBundleMessageSource  可以定时刷新资源文件

PropertyPlaceholderConfigurer   应用程序内部占位符替换(将占位符替换为具体的值)

2.spring  BeanPropertyBindingResult 的用法,

        HelloParams params=new HelloParams();
Errors errors=new BeanPropertyBindingResult(params,HelloParams.class.getName());
errors.rejectValue("clientId", "NOTNULL", null);
System.out.println(errors);

3.了解一下springmvc处理流程

dispatcherServlet--->

handlerMappings-->根据request---》HandlerExecutionChain (包括了拦截器和 handler)
[org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@1effc30a,
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@1a544088,
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@463d761b,
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping@19b6e142,
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@793186ed,
org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping@41d9c943]
---》根据handler 获取对应的handlerAdapter-->
[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@150afe2,
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@6cf9e2cd,
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@426bb2e1]
--->handlerAdapter调用handler处理request
--->handler 调用 HandlerMethodArgumentResolver
[org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@5acedd4b,
org.springframework.web.method.annotation.RequestParamMapMethodArgumentResolver@4c91253d,
org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver@76da1b10,
org.springframework.web.servlet.mvc.method.annotation.PathVariableMapMethodArgumentResolver@24bc9d2a,
org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMethodArgumentResolver@8342873,
org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMapMethodArgumentResolver@4d495c85,
org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@6beddca7,
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor@4412d4dd,
org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver@2bf8493d,
org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver@2268b81,
org.springframework.web.method.annotation.RequestHeaderMapMethodArgumentResolver@50c4234,
org.springframework.web.servlet.mvc.method.annotation.ServletCookieValueMethodArgumentResolver@1aed6,
org.springframework.web.method.annotation.ExpressionValueMethodArgumentResolver@6959be4a,
org.springframework.web.servlet.mvc.method.annotation.SessionAttributeMethodArgumentResolver@5f955a63,
org.springframework.web.servlet.mvc.method.annotation.RequestAttributeMethodArgumentResolver@38efae47,
org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver@3595c092,
org.springframework.web.servlet.mvc.method.annotation.ServletResponseMethodArgumentResolver@111a8384,
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor@64a98586,
org.springframework.web.servlet.mvc.method.annotation.RedirectAttributesMethodArgumentResolver@217192c2,
org.springframework.web.method.annotation.ModelMethodProcessor@3a7b472e,
org.springframework.web.method.annotation.MapMethodProcessor@7fb8e546,
org.springframework.web.method.annotation.ErrorsMethodArgumentResolver@5795ca82,
org.springframework.web.method.annotation.SessionStatusMethodArgumentResolver@7a5fa530,
org.springframework.web.servlet.mvc.method.annotation.UriComponentsBuilderMethodArgumentResolver@1afddf62,
org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@22578bae,
org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@5b6f84bc]
--->HttpMessageConverter

普通的读取form里的参数
ServletModelAttributeMethodProcessor

没有convert

有@requestbody
RequestResponseBodyMethodProcessor
[org.springframework.http.converter.ByteArrayHttpMessageConverter@3d37203b,
org.springframework.http.converter.StringHttpMessageConverter@45bb2aa1,
org.springframework.http.converter.StringHttpMessageConverter@7fd26ad8,
org.springframework.http.converter.ResourceHttpMessageConverter@1894593a,
org.springframework.http.converter.ResourceRegionHttpMessageConverter@14b0e127,
org.springframework.http.converter.xml.SourceHttpMessageConverter@10823d72,
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@7cea0110,
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@3e84111a,
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@468dda3e,
org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@5527b211]

一、HandlerMethodArgumentResolver

RequestResponseBodyMethodProcessor

bject arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
String name = Conventions.getVariableNameForParameter(parameter); if (binderFactory != null) {
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
if (mavContainer != null) {
mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
}
}

ServletModelAttributeMethodProcessor
//主要操作,绑定参数和校验参数

                        bindRequestParameters(binder, webRequest);
}
validateIfApplicable(binder, parameter);

读取form里的参数

public static Map<String, Object> getParametersStartingWith(ServletRequest request, @Nullable String prefix) {
Assert.notNull(request, "Request must not be null");
Enumeration<String> paramNames = request.getParameterNames();
Map<String, Object> params = new TreeMap<>();
if (prefix == null) {
prefix = "";
}
while (paramNames != null && paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
if ("".equals(prefix) || paramName.startsWith(prefix)) {
String unprefixed = paramName.substring(prefix.length());
String[] values = request.getParameterValues(paramName);
if (values == null || values.length == 0) {
// Do nothing, no values found at all.
}
else if (values.length > 1) {
params.put(unprefixed, values);
}
else {
params.put(unprefixed, values[0]);
}
}
}
return params;
}

二 、HandlerMethodReturnValueHandler

RequestResponseBodyMethodProcessor

三、介绍HttpMessageConverter
@requestbody 和 @responsebody
Jaxb2RootElementHttpMessageConverter

@requestbody 和 @responsebody 加上的同时,要在类上加@XmlRootElement 同时使用application/xml contentType和accept
MappingJackson2HttpMessageConverter

//hibernate 使用那些文件的国际化配置
1.使用jsr303对应的国际化文件 default "ValidationMessages.properties"
Validation.byDefaultProvider().configure()
.getDefaultMessageInterpolator()
2.使用spring对应的国际化文件
public void setValidationMessageSource(MessageSource messageSource) {
this.messageInterpolator = HibernateValidatorDelegate.buildMessageInterpolator(messageSource);
}

//获取local

@Override
public String interpolate(String message, Context context) {
return this.targetInterpolator.interpolate(message, context, LocaleContextHolder.getLocale());
}

3.使用校验注解标注在属性上(dto)

4.使用方法

参照: https://www.cnblogs.com/mr-yang-localhost/p/7812038.html

@GroupSequence也可以定义在po类上,定义找个类那些组先执行,那些组后执行。

          

5.自定义校验:

  1.解析对象,缓存对线的校验对象

    public void checkConfigLoaded(Class<?> dtoClass){
Boolean isloaded=annotationFlag.get(dtoClass);
if(isloaded==null){
synchronized(annotationFlag){
checkAnotation(dtoClass);
checkClazzAnotation(dtoClass);
annotationFlag.put(dtoClass, Boolean.TRUE);
}
}
}

  2.根据类初始化它的校验对象  

VNumber vn=ReflectUtils.getAnnotation(pd,VNumber.class);
if(vn!=null){
this.addValidator(new NumberValidator(vn),dtoClass,pd.getName());
}
VLength vl=ReflectUtils.getAnnotation(pd,VLength.class);
if(vl!=null){
this.addValidator(new LengthValidator(vl),dtoClass,pd.getName());
}
VRegex vr=ReflectUtils.getAnnotation(pd,VRegex.class);
if(vr!=null){
this.addValidator(new RegexValidator(vr),dtoClass,pd.getName());
}

  3.执行过程中

    1.当前对象循环,2.子对象循环,3.校验过滤器覆盖

    public void _validate(Object dto,String parentPath,int idx) throws Throwable{

        PropertyDescriptor[] pds=Introspector.getBeanInfo(dto.getClass()).getPropertyDescriptors();
String realParentPath=parentPath;
if(idx>-1 && parentPath!=null){
realParentPath=(parentPath+"["+idx+"]");
}
ValidateContext context=new DefaultValidateContext(this.bean,realParentPath,dto,errors);
//
ConfigLoader configLoader=validateSupport.getConfigLoader();
configLoader.checkConfigLoaded(dto.getClass());
//----------------------------
for(int i=0;i<pds.length;i++){
PropertyDescriptor pd=pds[i];
if(pd.getReadMethod()==null)continue;
Object value=pd.getReadMethod().invoke(dto);
//---------------------------------------------------------------------
//根据参数名取得验证器集合
String realPath=null;
String idxPath=(parentPath==null?pd.getName():(parentPath+"."+pd.getName()));;
if(idx>-1 && realParentPath!=null){
realPath=realParentPath+"."+pd.getName();
}else{
realPath=idxPath;
}
boolean isArray=pd.getPropertyType().isArray();
int isBaseArray=0;//0未知,1是,2否
if(isArray){
if(isBaseType(pd.getPropertyType().getComponentType())){
isBaseArray=1;
}else{
isBaseArray=2;
}
}
ValidatorsSet validators=null;
//--------------------------------------------------------------------
ValidatorsSet temp=configLoader.getValidators(dto.getClass(),pd.getName());
if(temp!=null){//如果未绑定任何验证器
if(validators==null){
validators=new ValidatorsSet();
}
validators.addAll(temp);
} if(pathValidators!=null && idx>-1 && parentPath!=null){
temp=pathValidators.get(idxPath);
if(temp!=null){
if(validators==null){
validators=new ValidatorsSet();
}
validators.addAll(temp);
}
}else if(pathValidators!=null){
temp=pathValidators.get(realPath);
if(temp!=null){
if(validators==null){
validators=new FieldValidators();
}
validators.addAll(temp);
}
}
if(isArray && isBaseArray==1){
if(validators !=null){
if(value==null){
validators.validate(context,pd,null,realPath,log);
}else{
int arrLen=Array.getLength(value);
if(arrLen==0){
validators.validate(context,pd,null,realPath,log);
}else{
for(int m=0;m<arrLen;m++){
Object arrItem=Array.get(value,m);
if(arrItem!=null ){
validators.validate(context,pd,arrItem,realPath+"["+m+"]",log);
}
}
}
}
}
}else{
if(validators!=null){
//进行验证
validators.validate(context,pd,value,realPath,log);
}
}
//---------------------------------------------------------------------
if(value!=null){
if(validateSupport.supports(pd.getPropertyType())){
_validate(value,idxPath,-1);
}
else if(isArray && isBaseArray==2){
int arrLen=Array.getLength(value);
for(int m=0;m<arrLen;m++){
Object arrItem=Array.get(value,m);
if(arrItem!=null ){
if(validateSupport.supports(arrItem.getClass())){
_validate(arrItem,idxPath,m);
}
}
}
}else if(value instanceof Collection){
Collection<?> list=(Collection<?>)value;
int tempInt=-1;
for(Object obj:list){
tempInt++;
if(obj!=null && validateSupport.supports(obj.getClass())){
_validate(obj,idxPath,tempInt);
} }
}else if(value instanceof Map){
Map<?,?> map=(Map<?,?>)value;
Set<?> list=map.entrySet();
for(Object entryObj:list){
Map.Entry<?,?> entry=(Map.Entry<?,?>)entryObj;
Object vv=entry.getValue();
if(vv!=null && validateSupport.supports(vv.getClass())){
_validate(vv,idxPath+"."+entry.getKey(),-1);
}
}
}
}
}
}

spring 参数校验的更多相关文章

  1. Spring Boot 参数校验

    1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spr ...

  2. Spring基础系列-参数校验

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9953744.html Spring中使用参数校验 概述 ​ JSR 303中提出了Bea ...

  3. spring注解式参数校验

    很痛苦遇到大量的参数进行校验,在业务中还要抛出异常或者返回异常时的校验信息,在代码中相当冗长,今天我们就来学习spring注解式参数校验. 其实就是:hibernate的validator. 开始啦. ...

  4. Spring Boot参数校验

    1. 概述 作为接口服务提供方,非常有必要在项目中加入参数校验,比如字段非空,字段长度限制,邮箱格式验证等等,数据校验常用到概念:JSR303/JSR-349: JSR303是一项标准,只提供规范不提 ...

  5. Spring Boot 2.x基础教程:JSR-303实现请求参数校验

    请求参数的校验是很多新手开发非常容易犯错,或存在较多改进点的常见场景.比较常见的问题主要表现在以下几个方面: 仅依靠前端框架解决参数校验,缺失服务端的校验.这种情况常见于需要同时开发前后端的时候,虽然 ...

  6. 如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!

    本文为作者原创,如需转载请在文首著名地址,公众号转载请申请开白. springboot-guide : 适合新手入门以及有经验的开发人员查阅的 Spring Boot 教程(业余时间维护中,欢迎一起维 ...

  7. Spring Boot 之:接口参数校验

    Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ...

  8. 如何在 Spring/Spring Boot 中做参数校验

    数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据. 本文结合自己在项目 ...

  9. spring 接口校验参数(自定义注解)

    1. 注解类 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.l ...

随机推荐

  1. 通过Spring Resource接口获取资源

    目录 1       Resource简介 2       通过ResourceLoader获取资源 3       在bean中获取Resource的方式 1       Resource简介 在S ...

  2. Codeforces Round #598 (Div. 3) B Minimize the Permutation

    B. Minimize the Permutation You are given a permutation of length nn. Recall that the permutation is ...

  3. Python之xml读写

    遇到问题xml文件读写,没有子节点需要新建ChildNode. # -*- coding: utf-8 -*- import os import shutil import xml.dom.minid ...

  4. windows_环境变量

    今天在windows下安装了openSSH,就想在windows下也添加一个服务器地址的环境变量,添加是会了,引用却不会,网上也没找到相应的文章,就自己看了看别人的bat程序,然后找到了引用变量的方法 ...

  5. 牛客网刷题总结—Day1

    1.关于哈夫曼树 哈夫曼树也称最优二叉树,其n个叶子节点都是带有权值的,其节点的带权路径长度(n个叶子节点的权值*其到根节点的路径之和)最小的二叉树即为哈夫曼树. 一般的哈夫曼树不存在度为1的节点(除 ...

  6. 配置yum仓库:yum install 软件

    1.一个重要模板: 进入/etc/yum.repos.d文件夹,新建一个xiaoxu.repo文件,其中xiaoxu可以根据需要来取名. [模板] vim  xiaoxu.repo [rhel]    ...

  7. How To Use These LED Garden Lights

    Are you considering the lighting options for the outdoor garden? Depending on how you use it, LED ga ...

  8. winform学习(3)窗体事件

    窗体的常用事件 事件可以理解为用户的操作,如点击鼠标键盘 应用程序需要在事件发生时进行响应,因此事件分为: 注册事件:必须为对象注册事件才会被执行(如为某控件添加一个单击的事件) 触发事件:注册后的事 ...

  9. Can't bind to 'ngModel' since it isn't a known property of 'input'.

    angular项目启动报错 Can't bind to 'ngModel' since it isn't a known property of 'input'. 原因:当前module模块未引入 ' ...

  10. SQL 杂项

    select  *  from 表  where to_date(ksrq,'yyyy-MM-dd')<=sysdate and  sysdate  <= to_date(jsrq,'yy ...