《Spring 5 官方文档》18. Web MVC 框架(五)
自定义WebDataBinder初始化
要通过Spring定制与PropertyEditor的请求参数绑定 WebDataBinder
,可以使用@InitBinder
控制器中的-annotated @InitBinder
方法,@ControllerAdvice
类中的方法或提供自定义 WebBindingInitializer
。有关更多详细信息,请参阅“使用@ControllerAdvice和@RestControllerAdvice建议控制器”一节。
使用@InitBinder自定义数据绑定
注释控制器方法,@InitBinder
允许您直接在控制器类中配置Web数据绑定。@InitBinder
识别用于初始化WebDataBinder
将用于填充命名和表示注释处理程序方法的对象参数的方法。
这种init-binder方法支持方法支持的所有参数@RequestMapping
,除了命令/表单对象和相应的验证结果对象。Init-binder方法不能有返回值。因此,它们通常被声明为void
。典型的参数包括WebDataBinder
与WebRequest
或者 java.util.Locale
允许代码注册上下文相关的编辑器。
以下示例演示@InitBinder
如何CustomDateEditor
为所有java.util.Date
表单属性配置一个 。
@Controller public class MyFormController { @InitBinder protected void initBinder(WebDataBinder binder){SimpleDateFormat dateFormat = new SimpleDateFormat( “yyyy-MM-dd”); dateFormat.setLenient(假); binder.registerCustomEditor(日期类,新和CustomDateEditor(日期格式,FALSE)); } // ... }
或者,从Spring 4.2起,考虑使用addCustomFormatter
来指定 Formatter
实现而不是PropertyEditor
实例。如果您碰巧Formatter
在共享FormattingConversionService
中安装一个基于安装程序的 方法,那么特别有用的方法可以重用于控制器特定的绑定规则调整。
@Controller public class MyFormController { @InitBinder protected binder.addCustomFormatter( new DateFormatter( “yyyy-MM-dd”)); } // ... }void initBinder(WebDataBinder binder) {
配置自定义WebBindingInitializer
要外部化数据绑定初始化,您可以提供WebBindingInitializer
接口的自定义实现,然后通过为其提供自定义bean配置来启用RequestMappingHandlerAdapter
,从而覆盖默认配置。
PetClinic应用程序中的以下示例显示了使用该接口的自定义实现的WebBindingInitializer
配置org.springframework.samples.petclinic.web.ClinicBindingInitializer
,它配置了几个PetClinic控制器所需的PropertyEditor。
<bean class = “org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter” > <property name = “cacheSeconds” value = “0” /> <property name = “webBindingInitializer” > <bean class = “org .springframework.samples.petclinic.web.ClinicBindingInitializer“ /> </ property> </ bean>
@InitBinder
方法也可以在一个@ControllerAdvice
注释类中定义,在这种情况下,它们适用于匹配控制器。这提供了使用a的替代方法 WebBindingInitializer
。有关更多详细信息,请参阅“使用@ControllerAdvice和@RestControllerAdvice建议控制器”一节。
通过@ControllerAdvice和@RestControllerAdvice为控制器提供建议
的@ControllerAdvice
注释是一个组件注释允许实现类自动检测通过类路径扫描。当使用MVC命名空间或MVC Java配置时,它将自动启用。
带注释的类@ControllerAdvice
可以包含@ExceptionHandler
, @InitBinder
和@ModelAttribute
注解的方法,这些方法将适用于 @RequestMapping
所有控制器的层次结构的方法,而不是内声明它们控制器层次。
@RestControllerAdvice
是一种@ExceptionHandler
方法@ResponseBody
,默认情况下方法采用语义。
二者@ControllerAdvice
并@RestControllerAdvice
可以针对控制器的一个子集:
//目标所有使用@RestController注释的控制器 @ControllerAdvice(annotations = RestController.class) public class AnnotationAdvice {} //定位特定包中的所有控制器@ControllerAdvice(“org.example.controllers”) public class BasePackageAdvice {} // Target所有可分配给特定类的控制器@ControllerAdvice(assignableTypes = {ControllerInterface.class,AbstractController.class}) public class AssignableTypesAdvice {}
查看 @ControllerAdvice
文档了解更多详细信息。
杰克逊序列化视图支持
有时将内容过滤将被序列化到HTTP响应主体的对象有时是有用的。为了提供这样的功能,Spring MVC内置了对Jackson的Serialization Views进行渲染的支持。
要使用@ResponseBody
返回的控制器方法或控制器方法 ResponseEntity
,只需@JsonView
使用指定要使用的视图类或接口的类参数添加注释:
@RestController public class UserController { @GetMapping(“/ user”)@JsonView(User.WithoutPasswordView.class) public User getUser(){ return new User( “eric”, “7!jd#h23”); } }公共类用户{公共接口 WithoutPasswordView {};public Interface WithPasswordView extends WithoutPasswordView {}; 私人字符串用户名;私人字符串密码; public User(){}} @JsonView(WithoutPasswordView。class) public String getUsername(){ return this .username; } @JsonView(WithPasswordView.class) public String getPassword(){ return this .password; } }public User(String username, String password) {this.username = username;this.password = password;
请注意,尽管@JsonView 允许指定多个类,但在控制器方法上的使用只支持一个类参数。如果需要启用多个视图,请考虑使用复合接口。
|
对于依赖于视图分辨率的控制器,只需将序列化视图类添加到模型中:
@Controller public class UserController extends AbstractController {@GetMapping(“/ user”) public String getUser(Model model){model.addAttribute(“user”,new User(“eric”,“7!jd#h23”));model.addAttribute(JsonView 类 .getName(),User.WithoutPasswordView。类);返回 “userView” ;} }
杰克逊JSONP支持
为了启用JSONP支持@ResponseBody
和ResponseEntity
方法,声明一个@ControllerAdvice
扩展的bean, AbstractJsonpResponseBodyAdvice
如下所示,构造函数参数指示JSONP查询参数名称:
@ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {public JsonpAdvice(){super(“callback”);} }
对于依赖于视图分辨率的控制器,当请求具有名为jsonp
或者的查询参数时,将自动启用JSONP callback
。这些名字可以通过jsonpParameterNames
财产定制。
18.3.4异步请求处理
Spring MVC 3.2介绍了基于Servlet 3的异步请求处理。与往常一样,一个控制器方法现在可以返回一个java.util.concurrent.Callable
并从Spring MVC管理的线程生成返回值,而不是返回一个 值。同时,主要的Servlet容器线程被退出并被释放并允许处理其他请求。Spring MVC Callable
在一个单独的线程中调用一个单独的线程TaskExecutor
,当Callable
返回时,请求被分派回到Servlet容器,以使用返回的值来恢复处理Callable
。这是一个这样一个控制器方法的例子:
@PostMapping public Callable <String> processUpload( final MultipartFile文件){返回 新的 Callable <String>(){public String call()throws Exception {// ... return “someView” ;}};}
另一个选项是控制器方法返回一个实例DeferredResult
。在这种情况下,返回值也将从任何线程生成,即不由Spring MVC管理的线程。例如,可以响应于诸如JMS消息,计划任务等的一些外部事件而产生结果。这是一个这样一个控制器方法的例子:
@RequestMapping(“/ quotes”) @ResponseBody public DeferredResult <String> quotes(){DeferredResult <String> deferredResult = new DeferredResult <String>();//将deferredResult保存在某个地方.. return deferredResult; }//在其他一些线程中... deferredResult.setResult(data);
没有任何Servlet 3.0异步请求处理功能的知识可能难以理解。这肯定有助于阅读。以下是有关基本机制的几个基本事实:
- A
ServletRequest
可以通过调用进入异步模式request.startAsync()
。这样做的主要作用是Servlet以及任何过滤器都可以退出,但响应将保持开放状态,以便稍后完成处理。 - 可以用于进一步控制异步处理的
request.startAsync()
返回 调用AsyncContext
。例如,它提供的方法dispatch
类似于Servlet API中的转发,但它允许应用程序在Servlet容器线程上恢复请求处理。 - 在
ServletRequest
提供对当前DispatcherType
可用于处理所述初始请求,一个异步调度,正向,以及其他的调度类型之间进行区分。
考虑到上述情况,以下是异步请求处理的事件的顺序Callable
:
- 控制器返回a
Callable
。 - Spring MVC启动异步处理,并在单独的线程中提交
Callable
到一个TaskExecutor
进行处理。 - 将
DispatcherServlet
所有过滤器的退出Servlet容器线程,但反应仍然开放。 - 所述
Callable
产生的结果和Spring MVC分派请求回Servlet容器以恢复处理。 - 在
DispatcherServlet
再次调用和处理与来自所述异步生产结果恢复Callable
。
序列DeferredResult
非常相似,除了由应用程序产生任何线程的异步结果:
- 控制器返回一个
DeferredResult
并将其保存在某些内存中的队列或列表中,可以访问它。 - Spring MVC启动异步处理。
- 在
DispatcherServlet
所有配置的过滤器的退出请求处理线程,但反应仍然开放。 - 应用程序
DeferredResult
从一些线程设置,Spring MVC将请求返回给Servlet容器。 - 在
DispatcherServlet
再次调用和处理与异步生产结果恢复。
有关异步请求处理的动机的进一步背景,何时或为什么使用它,请阅读 此博客文章系列。
异步请求异常处理
如果Callable
从控制器方法返回的值在执行时引发异常,会发生什么?简短的答案与控制器方法引发异常时发生的情况相同。它经历了常规异常处理机制。更长的解释是,当Callable
一个Exception Spring MVC调度到具有Exception
结果的Servlet容器并导致恢复请求处理时,Exception
而不是控制器方法返回值。使用时,DeferredResult
您可以选择是否调用 setResult
或setErrorResult
使用Exception
实例。
拦截异步请求
甲HandlerInterceptor
还可以实现AsyncHandlerInterceptor
以执行afterConcurrentHandlingStarted
回调,这就是所谓的代替postHandle
和afterCompletion
处理开始异步时。
A HandlerInterceptor
还可以注册一个CallableProcessingInterceptor
或一个DeferredResultProcessingInterceptor
以更深入地与异步请求的生命周期集成,例如处理超时事件。有关AsyncHandlerInterceptor
详细信息,请参阅Javadoc 。
该DeferredResult
类型还提供了诸如onTimeout(Runnable)
和onCompletion(Runnable)
。有关DeferredResult
详细信息,请参阅Javadoc 。
使用时,Callable
您可以使用一个实例来包装它WebAsyncTask
,它还提供了超时和完成的注册方法。
HTTP流式传输
控制器方法可以异步地使用DeferredResult
和Callable
产生其返回值,并且可以用于实现诸如 长轮询的技术 ,其中服务器可以尽快将事件推送到客户端。
如果您想在单个HTTP响应中推送多个事件怎么办?这是一个与“长查询”相关的技术,被称为“HTTP流”。Spring MVC可以通过ResponseBodyEmitter
可以用于发送多个对象的返回值类型来实现,而不是像通常情况那样@ResponseBody
发送的对象,其中每个发送的对象都被写入到响应中HttpMessageConverter
。
这是一个例子:
@RequestMapping(“/ events”) public ResponseBodyEmitter handle(){ResponseBodyEmitter emitter = new ResponseBodyEmitter();//保存发射的地方.. 返回发射器; }//在其他一些线程 emit.send(“Hello once”);//再次在 emitter.send(“Hello again”);//并在某个时候完成 emitter.complete();
注意,ResponseBodyEmitter
也可以用作身体 ResponseEntity
,以便自定义响应的状态和标题。
HTTP流与服务器发送的事件
SseEmitter
是ResponseBodyEmitter
为服务器发送事件提供支持 的子类。服务器发送的事件是相同的“HTTP流”技术的另一个变体,除了从服务器推送的事件根据W3C服务器发送事件规范进行格式化。
服务器发送事件可以用于其预期目的,即将事件从服务器推送到客户端。在Spring MVC中很容易做到,只需返回一个类型的值即可SseEmitter
。
请注意,Internet Explorer不支持服务器发送事件,而对于更高级的Web应用程序消息传递场景(如在线游戏,协作,财务应用程序等),最好考虑Spring的WebSocket支持,其中包括SockJS风格的WebSocket仿真回落到非常广泛的浏览器(包括Internet Explorer)以及更高级别的消息传递模式,用于通过更多以消息为中心的体系结构中的发布订阅模型与客户端进行交互。有关进一步的背景,请参阅 以下博文。
HTTP直接流向OutputStream
ResponseBodyEmitter
允许通过将对象写入响应来发送事件HttpMessageConverter
。这可能是最常见的情况,例如在编写JSON数据时。但是有时候,绕过邮件转换并直接写入响应OutputStream
(例如文件下载)是有用的。这可以在StreamingResponseBody
返回值类型的帮助下完成 。
这是一个例子:
@RequestMapping(“/ download”) public StreamingResponseBody handle(){ return new StreamingResponseBody(){@ Override public void writeTo(OutputStream outputStream) throws IOException { // write ...}}; }
注意,StreamingResponseBody
也可以用作身体 ResponseEntity
,以便自定义响应的状态和标题。
配置异步请求处理
Servlet容器配置
对于配置web.xml
为确保更新到版本3.0的应用程序:
<web-app xmlns = “http://java.sun.com/xml/ns/javaee” xmlns:xsi = “http://www.w3.org/2001/XMLSchema-instance” http:// java。 sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” 版本 = “3.0” >...</ web的应用>
必须在DispatcherServlet
通过 <async-supported>true</async-supported>
子元素中启用异步支持web.xml
。另外,任何Filter
参与异步请求处理的任务都必须配置为支持ASYNC分派器类型。对于Spring Framework提供的所有过滤器,ASYNC调度器类型应该是安全的,因为它们通常是扩展的OncePerRequestFilter
,并且具有对过滤器是否需要参与异步调度的运行时间检查。
以下是一些web.xml配置示例:
<web-app xmlns = “http://java.sun.com/xml/ns/javaee” xmlns:xsi = “http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation = “http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” 版本 = “3.0” ><filter> <filter-name> Spring OpenEntityManagerInViewFilter </ filter-name> <filter-class> org.springframework。〜.OpenEntityManagerInViewFilter </ filter-class> <async-supported> true </ async-supported> </ filter><滤波器映射> <滤波器名称>春OpenEntityManagerInViewFilter </过滤器名称> <URL模式> / * </ URL模式> <调度> REQUEST </调度程序> <调度> ASYNC </调度程序> </过滤器-mapping></ web的应用>
如果使用Servlet 3,例如通过基于Java的配置WebApplicationInitializer
,您还需要像之前一样设置“asyncSupported”标志以及ASYNC调度器类型web.xml
。为了简化所有这些配置,请考虑扩展 AbstractDispatcherServletInitializer
或更好地 AbstractAnnotationConfigDispatcherServletInitializer
自动设置这些选项,并使其很容易注册Filter
实例。
Spring MVC配置
MVC Java配置和MVC命名空间提供了配置异步请求处理的选项。WebMvcConfigurer
具有该方法 configureAsyncSupport
同时<mvc:annotation-driven>
具有<async-support>
子元素。
这些允许您配置用于异步请求的默认超时值,如果未设置,则取决于底层的Servlet容器(例如Tomcat上的10秒)。您还可以配置一个AsyncTaskExecutor
用于执行Callable
从控制器方法返回的实例。强制建议配置此属性,默认情况下Spring MVC使用SimpleAsyncTaskExecutor
。MVC Java配置和MVC命名空间也允许您注册CallableProcessingInterceptor
和 DeferredResultProcessingInterceptor
实例。
如果需要覆盖特定的默认超时值DeferredResult
,可以使用适当的类构造函数来实现。类似地,对于a Callable
,可以将它包装在一个WebAsyncTask
并使用适当的类构造函数来自定义超时值。类的构造函数WebAsyncTask
也允许提供一个 AsyncTaskExecutor
。
18.3.5测试控制器
该spring-test
模块提供一流的支持,用于测试带注释的控制器。参见第11.6节“Spring MVC测试框架”。
转载自 并发编程网 - ifeve.com
《Spring 5 官方文档》18. Web MVC 框架(五)相关推荐
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)
接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion
本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...
- 【Spring Boot官方文档原文理解翻译-持续更新中】
[Spring Boot官方文档原文理解翻译-持续更新中] 文章目录 [Spring Boot官方文档原文理解翻译-持续更新中] Chapter 4. Getting Started 4.1. Int ...
- Spring Boot 官方文档学习(一)入门及使用
Spring Boot 官方文档学习(一)入门及使用 个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问 ...
- Spring Boot 官方文档摘要
Spring Boot 官方文档摘要 一.Develop Your First Spring Boot Application Spring Boot 依赖于 groupId 为 org.spring ...
- 如何找到spring的官方文档位置
最近因为项目中遇到了一些问题, 百度不到比较好的方案, 就准备去看下spring的官方文档, 在此记录下: 1. 进入spring framework的官网项目页面: https://spring. ...
- 如何找到spring的官方文档
最近因为项目中遇到了一些问题, 百度不到比较好的方案, 就准备去看下spring的官方文档, 在此记录下: 1. 进入spring framework的官网项目页面: https://spring. ...
- Spring 4 官方文档学习(十一)Web MVC 框架之异常处理
1.HandlerExceptionResolver Spring HandlerExceptionResolver的实现们会处理controller执行过程中发送的unexpected except ...
- Spring 4 官方文档学习 Spring与Java EE技术的集成
本部分覆盖了以下内容: Chapter 28, Remoting and web services using Spring -- 使用Spring进行远程和web服务 Chapter 29, Ent ...
- Spring指南之使用Spring缓存数据(Spring Framework官方文档之缓存抽象详解)
1.请参见官方文档Spring指南之使用 Spring 缓存数据 2.请参见Spring官方文档之缓存抽象 3.参见github代码 文章目录 一.简介 二.你将创造什么(What You Will ...
最新文章
- 修改ie9默认的quirk模式
- JSON 是个什么??!!!
- 利用小波融合对由聚焦失败导致的图像模糊进行修复
- Spring 系列: Spring 框架
- 优化网页代码提高网页访问速度
- FreeRTOS内核实现05:支持多优先级
- delphi调用python_Delphi使用Python来解码邮件
- HTML5学习总结(2)——header/nav/footer/article/section/aside
- 大数据十大核心原理(互联网上整理)
- 下载Googleearth地图作为底图显示曝光点
- Hyperscan 5.4.0 安装教程 (CentOS7环境)
- Couldn't find leader offsets for Set news_topic
- 如何更改Dropbox的同步文件夹?
- 携程的旅游知识图谱构建和应用
- 关于html中锚点功能的使用
- 天梯图excl_Excel版CPU天梯图 方便打印.xls
- 基于达索系统3DE平台实现企业数字化转型的场景应用
- springboot设置空参数_springboot请求参数为空
- 数据防泄密软件都是怎么对文件加密的?
- 如何绘制程序流程图?绘制程序流程图工具介绍及功能讲解
热门文章
- 国际机器人联合会:全球工业机器人2019报告
- 动图|几张动图告诉你,工业机器人无所不能!
- 盘点2018十大科技丑闻,IT相关两项
- Nature最新研究:超9000学者每5天发1篇论文,这些高产作家背后的科研圈
- 机器学习帮助人类找到最硬的过渡金属氮化物
- 高盛:人工智能报告中文版(45页)
- 2020年投入200000000美元,华为不只挖掘年薪百万的“天才少年”
- 彩蛋还是陷阱?我所经历的期权往事
- 探讨ASP.NET 2.0中的Web控件改进技术(3)
- The encryption certificate of the relying party trust identified by thumbprint is not valid