spring 参数校验
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 参数校验的更多相关文章
- Spring Boot 参数校验
		1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spr ... 
- Spring基础系列-参数校验
		原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9953744.html Spring中使用参数校验 概述  JSR 303中提出了Bea ... 
- spring注解式参数校验
		很痛苦遇到大量的参数进行校验,在业务中还要抛出异常或者返回异常时的校验信息,在代码中相当冗长,今天我们就来学习spring注解式参数校验. 其实就是:hibernate的validator. 开始啦. ... 
- Spring Boot参数校验
		1. 概述 作为接口服务提供方,非常有必要在项目中加入参数校验,比如字段非空,字段长度限制,邮箱格式验证等等,数据校验常用到概念:JSR303/JSR-349: JSR303是一项标准,只提供规范不提 ... 
- Spring Boot 2.x基础教程:JSR-303实现请求参数校验
		请求参数的校验是很多新手开发非常容易犯错,或存在较多改进点的常见场景.比较常见的问题主要表现在以下几个方面: 仅依靠前端框架解决参数校验,缺失服务端的校验.这种情况常见于需要同时开发前后端的时候,虽然 ... 
- 如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!
		本文为作者原创,如需转载请在文首著名地址,公众号转载请申请开白. springboot-guide : 适合新手入门以及有经验的开发人员查阅的 Spring Boot 教程(业余时间维护中,欢迎一起维 ... 
- Spring Boot 之:接口参数校验
		Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ... 
- 如何在 Spring/Spring Boot 中做参数校验
		数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据. 本文结合自己在项目 ... 
- spring 接口校验参数(自定义注解)
		1. 注解类 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.l ... 
随机推荐
- 通过Spring Resource接口获取资源
			目录 1 Resource简介 2 通过ResourceLoader获取资源 3 在bean中获取Resource的方式 1 Resource简介 在S ... 
- 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 ... 
- Python之xml读写
			遇到问题xml文件读写,没有子节点需要新建ChildNode. # -*- coding: utf-8 -*- import os import shutil import xml.dom.minid ... 
- windows_环境变量
			今天在windows下安装了openSSH,就想在windows下也添加一个服务器地址的环境变量,添加是会了,引用却不会,网上也没找到相应的文章,就自己看了看别人的bat程序,然后找到了引用变量的方法 ... 
- 牛客网刷题总结—Day1
			1.关于哈夫曼树 哈夫曼树也称最优二叉树,其n个叶子节点都是带有权值的,其节点的带权路径长度(n个叶子节点的权值*其到根节点的路径之和)最小的二叉树即为哈夫曼树. 一般的哈夫曼树不存在度为1的节点(除 ... 
- 配置yum仓库:yum install 软件
			1.一个重要模板: 进入/etc/yum.repos.d文件夹,新建一个xiaoxu.repo文件,其中xiaoxu可以根据需要来取名. [模板] vim xiaoxu.repo [rhel] ... 
- 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 ... 
- winform学习(3)窗体事件
			窗体的常用事件 事件可以理解为用户的操作,如点击鼠标键盘 应用程序需要在事件发生时进行响应,因此事件分为: 注册事件:必须为对象注册事件才会被执行(如为某控件添加一个单击的事件) 触发事件:注册后的事 ... 
- 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模块未引入 ' ... 
- SQL 杂项
			select * from 表 where to_date(ksrq,'yyyy-MM-dd')<=sysdate and sysdate <= to_date(jsrq,'yy ... 
