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 getParametersStartingWith(ServletRequest request, @Nullable String prefix) {
        Assert.notNull(request, "Request must not be null");
        Enumeration paramNames = request.getParameterNames();
        Map 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)

 

 spring 参数校验_第1张图片

 

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){
            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){
                                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){
                        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);
                        }
                    }
                }
            }
        }
    } 
View Code

 

转载于:https://www.cnblogs.com/z-test/p/9989306.html

你可能感兴趣的:(spring 参数校验)