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. Python之xml读写

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

  2. 2.springboot------微服务

    什么是微服务? 微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合:可以通过http的方式进行互通.要说微服务架构,先得说说过去我们的单体应用架构. 单体应用架 ...

  3. Linux - Shell - find - 进阶: 范围

    概述 继续昨天的 find 背景 还有一些 过滤条件 1. 约束: 目录层数 概述 约束目录的层级 选项 -maxdepth 作用 约束最大目录层级 相对路径 -mindepth 作用 约束最小目录层 ...

  4. 【C语言】数组名作函数参数,完成数据的升序排列

    #include<stdio.h> void sort(int x[],int n); int main() { ] = { ,,,,,,,,, },i; sort(arr, ); pri ...

  5. 搭建Springboot监控中心报错A attempt was made to call the method reactor.retry.Retry.retryMax(I)Lreactor/ret)

    服务器还没启动就报错,是因为jar包的版本没对上,看的视频是SpringBoot2.0 ,现在已经是2.1.7了 将spring-boot-admin-starter-server版本改为最新就ok了

  6. python接口自动化测试 - requests库的post请求进行文件上传

    前言 如果需要发送文件到服务器,比如上传图片.视频等,就需要发送二进制数据. 一般上传文件使用的都是 Content-Type: multipart/form-data; 数据类型,可以发送文件,也可 ...

  7. opencv:形态学梯度

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  8. 吴裕雄 python 机器学习——集成学习梯度提升决策树GradientBoostingRegressor回归模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...

  9. Petr and a Combination Lock

    Petr has just bought a new car. He's just arrived at the most known Petersburg's petrol station to r ...

  10. 转载:ADTS header

    转自:http://blog.csdn.net/tx3344/article/details/7414543 1.ADTS是个啥 ADTS全称是(Audio Data Transport Stream ...