2.5.0版本
@ConfigurationProperties 装配properties中的对象,自动匹配
定制化mvc就是在配置里去创建webConfigurer组件
请求参数处理
rest请求
rest只是一个整合,不是新技术
利用http请求中,所带的method,进行区分
直接rest请求
直接工具是可以请求的,springboot默认开启rest请求
表单rest请求
由于表单提交只有get和post,无法实现rest请
- from提交为post
- 开启spring.mvc.hiddenmethod.filter.endabled=true
- 在表单中添加input标签,name或id为_method,value为rest类型,对应controller就会请求到
修改_method名称
- 自定一个配置即可。
1 |
|
请求映射
就是springmvc的请求映射
mappingRegistry,用于mapping注册到当前HandlerMapping
MatchingMappings,跟当前路径匹配的地址,一个个适配,根据请求类型,没有匹配的会返回404,如果有两个相同的会抛异常,所以只能存在一个。
自动配置下面五个HandlerMapping
- RequestMappingHandlerMapping 普通请求对应的handler
- 扫描@RequestMapping
- 同种路径和类型,只会存在一个
- WelcomePageHandlerMapping 欢迎页的handler
- springboot的,自动配置,/index,底层写死的
- 如果修改静态资源访问路径,不是默认根目录,那么静态资源路径的index.html,无法找到欢迎页。
- 可以自定义个请求路径,做欢迎页。
- BeanNameUrlHandlerMapping
- RouterFunctionMapping
- SimpleUrlHandlerMapping
请求进来,会循环扫描以上五个Mapping,找到对应Handler进行处理
所有改的请求映射,都在HandlerMapping
自定义HandlerMapping,由于灰度发版,新旧版本并行。
普通参数和基本注解
注解
- @PathVariable 路径变量
- 可以用@PathVariable Map<Stirng,String> map,接收全部值
- @RequestHeader 请求头
- 可以用 @RequestHeader Map<Stirng,String> header,接收全部值
- @RequestParam 请求参数
- 同属性多值,不要用@RequestParam Map<String,String> map,只能放一个值。
- 同属性多值,@RequestParam(“xxxx”) List<String> xxxx,接收
- @RequestAttribute 获取request中的属性
- @ModelAttribute ServletModelAttributeMethodProcessor解析
- 加在方法上
- 每次当前类的请求都会处理,并且会覆盖
- 无法返回值,可以入参数上加上model
- 有返回值,且@ModelAttribute(“XXXX”),key为XXX,value为返回值
- 有返回值,且@ModelAttribute(),入参无需用model,返回值就是attribute中的value,返回值类型小写开头,就是key
- @CookieValue cookie值
- @RequestBody 请求体
- @MatrixVariable 矩阵变量
- 根据RFC3986的规则,应当使用英文字符
;
进行分割 - 若是一个矩阵变量有多个值,应当使用英文符号
,
进行分割,或之命名多个重复的key即可。 - 原来 /cars/{path}?xxx=xxx&sss=vvvv querString 查询字符串。@RequestParam
- 用矩阵变量 /cars/{path;low=34;brand=byd,audi,yd}
- 页面开发,cookie禁用了,session里面的内容怎么使用
- session.set(a,b) —-> jsessionid —> cookie —–> 每次请求携带
- url重写:/cars;jsessionid=xxxxx 把cookie的值使用矩阵变量的方式进行传递。
- 矩阵变量需要在springboot中手动开启
- 在WwebMvcAutoConfiguration中configurePathMatch中UrlPathHelper
- UrlPathHelper中的一个属性,removeSemicolonContent,默认为true,对url中
;
之后的部分进行移除 - 自定义配置
- 第一种 实现WebMvcConfigurer,重写configurerPathMatch方法
- 第二种 直接创建WebMvcConfigurer组件,重写configurerPathMatch方法
- 根据RFC3986的规则,应当使用英文字符
1 |
|
1 |
|
Servlet API
ServletRequestMethodArgumentResolver解析以下参数
- WebRequest
- ServletRequest
- MultipartRequest
- HttpSession
- java.servlet.http.PushBuilder
- Principal
- InputStream
- Reader
- HttpMethod
- Locale
- TimeZone
- Zoneld
复杂参数
- Map 向map里放东西,相当于request.setattribute()
- mavContainer.getModel(); —–> BindingAwareModelMap 继承ModelMap,既是Model也是Map
- Model 同上
- Errors/BindingResult
- RedirectAttributes 重定向携带数据
- ServletResponse response
- SessionStatus
- UriComponentsBuilder
- ServletUriComponentsbBuilder
自定义对象参数
ServletModelAttributeMethodProcessor对对象进行解析,提供自动绑定
- 可以自动类型转换与格式化,可以级联封装
参数处理原理
- HandlerMapping中到到能处理的请求的Handler(controller.method)
- 为当前Handler找适配器HanlderAdapter
- RequestMappingHandlerAdapter 支持@RequestMapping的处理
- HandlderFuntionAdapter 支持函数式编程的处理
- HttpRequestHandlerAdapter servlet的支持
- SimpleControllerHandlerAdapter
拿到对相应的HandlerAdapter之后,执行handler
在handler中执行invokeHandlerMethod方法
在invokeHandlerMethod中封装了一个叫ServletInvocableHandlerMethod的对象
对象中封装了argumentResolvers的参数解析器
argumentResolvers的种类有:
- RequestParamMethodArgumentResolver
- RequestParamMapMethodArgumentResolver
- PathVariableMethodArgumentResolver
- PathVariableMapMethodArgumentResolver
- MatrixVariableMethodArgumentResolver
- MatrixVariableMapMethodArgumentResolver
- ServletModelAttributeMethodProcessor
- RequestResponseBodyMethodProcessor
- RequestPartMethodArgumentResolver
- RequestHeaderMethodArgumentResolver
- RequestHeaderMapMethodArgumentResolver
- ServletCookieValueMethodArgumentResolver
- ExpressionValueMethodArgumentResolver
- SessionAttributeMethodArgumentResolver
- RequestAttributeMethodArgumentResolver
- ServletRequestMethodArgumentResolver
- ServletResponseMethodArgumentResolver
- HttpEntityMethodProcessor
- RedirectAttributesMethodArgumentResolver
- ModelMethodProcessor
- MapMethodProcessor
- ErrorsMethodArgumentResolver
- SessionStatusMethodArgumentResolver
- UriComponentsBuilderMethodArgumentResolver
- PrincipalMethodArgumentResolver
- RequestParamMethodArgumentResolver
- ServletModelAttributeMethodProcessor
- 参数解析实现HandlerMethodArgumentResolver接口
- resolveArgument 解析参数
- supportsParameter 支持参数 当前解析器是否支持解析这个参数,支持才会调用resolveArgument进行参数的解析
- method中能写多少种参数,取决参数解析器
还封装了returnValueHandlders 返回值处理器,类型如下
- ModelAndViewMethodReturnValueHandler
- ModelMethodProcessor
- ViewMethodReturnValueHandler
- ResponseBodyEmitterReturnValueHandler
- StreamingResponseBodyReturnValueHandler
- HttpEntityMethodProcessor
- HttpHeadersReturnValueHandler
- CallableMethodReturnValueHandler
- DeferredResultMethodReturnValueHandler
- AsyncTaskMethodReturnValueHandler
- ServletModelAttributeMethodProcessor
- RequestResponseBodyMethodProcessor
- ViewNameMethodReturnValueHandler
- MapMethodProcessor
- ServletModelAttributeMethodProcessor
- method能返回什么参数,取决于返回值处理器
封装完毕后,ServletInvocableHandlerMethod回去调用invokeAndHandler的方法
在invokeAndHandler中调用invokeForRequest方法
在invokeForRequest中调用getMethodArgumentValues获取controller.method需要的参数
getMethodArgumentValues在InvocableHanderMethod.java中
- InvocableHanderMethod
- getMethodParamters 获取值
- 遍历参数
- this.resolvers.supportsParameter(parameter)//是否支持当前参数的解析
- 遍历26种参数解析器 break;
- 判断参数上的注解类型,没有注解的,默认走RequestParam
- 遍历26种参数解析器 break;
- this.resolvers.resolveArgument进行解析
- 获取参数,在request.attribute中,是由UrlPathHelper解析出来,请求最开始的时候。
- this.resolvers.supportsParameter(parameter)//是否支持当前参数的解析
拿到参数之后,会执行doInvoke
数据响应与内容协商
响应JSON
- 需要webmvc
- 依赖jackson
- @ResponseBody
请求是会携带当前的数据类型和能接收的数据类型,返回数据时,会根据接收类型,和当前的数据类型进行转换,这一步叫内容协商
HTTPMessageConverter
- canRead 判断能读
- canWrite 判断能写
- getSupportedMediaTypes 是否支持MediaType
- read 读
- write 写
将此class类型,转为MediaType类型的数据
内容协商原理
- 判断当前相应头中是否已有确定的媒体类型。MediaType
- 获取客户端(PostMan,浏览器)支持接收的内容类型。(获取客户端Accepte请求头字段)【application/xml】
- contenttNegotiationManager 内容协商管理起默认使用基于请求头的策略
- contenttNegotiationStraegy 确定客户端可以接受的内容类型
- 遍历循环所有当前系统的MessageConverter,看谁支持操作这个对象
- 找到支持操作的converter,把converter支持的媒体类型统计出来
- 客户端需要【application/xml】。服务端能力【10种,json、xml】
- application/json
- application/*+json
- application/*+xml;charset=UTF-8
- application/xml;charset=UTF-8
- text/xml;charset=UTF-8
- application/*+xml;charset=UTF-8
- 进行内容协商的租价匹配媒体类型
- 用支持讲对象转为最佳匹配媒体类型的converter。调用他的转换化
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- StringHttpMessageConverter
- ResourceHttpMessageConverter
- ResourceRegionHttpMessageConverter
- SourceHttpMessageConverter
- AllEncompassingFormHttpMessageConverter
- MappingJackson2HttpMessageConverter 直接返回true,啥都支持
- MappingJackson2HttpMessageConverter
- Jaxb2RootElementHttpMessageConverter 注解方式的xml
自定义MessageConverter
可以实现定制输入输出,自定义协议
1 | /** |
在配置中的webConfigure中添加实现即可 extendMessageConverters是扩充
1 |
|
开启浏览器参数方式内容协商功能
为了方便,开启基于请求的内容协商功能。
1 | spring: |
参数为format
开启参数,参数优先,否则为请求头,最后才是*/*
自定义协议
configureContentNegotiation会覆盖掉默认的协议,支持参数format
1 |
|
模板引擎
srpingboot默认不支持jsp,有是jar的原因。
freemarker
groovy-templates
thymeleaf
防止表单重复提交,最好的方式是重定向。
1 |
|
视图解析
ViewResolver
- ContentNegotiatingViewResolver
- BeanNameViewResolver
- ThymeleafViewResolver
- ViewResolverComposite
- InternalResourceViewResolver
原理
- 目标方法处理的过程中,所有数据都会被放在ModelAndViewContainer里面。包括数据和视图地址。
- 方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在ModelAndViewContainer
- 任何目标方法执行完成以后都会返回ModelAndView(数据和视图地址)
- processDispathResult处理派发结果(页面该如何响应)
- render(mv,request,response);进行页面渲染逻辑
- 根据方法的String返回值得到View对象【定义了页面的渲染逻辑】
- 所有的视图解析器尝试是否能根据当前返回值得到View对象
- 得到 redirect:/main.html –>RedirectView
- 未完待续
- 根据方法的String返回值得到View对象【定义了页面的渲染逻辑】
- render(mv,request,response);进行页面渲染逻辑