Spring ResponseEntity
简单记录下 ResponseEntity 的使用方式
@RequestMapping(value="/demo1" )
public ResponseEntity demo1(){
// 使用方式一.
// ResponseEntity responseEntity = new ResponseEntity(new User("lvbb",24),HttpStatus.OK); // 使用方式二.
return ResponseEntity.ok(new User("lvbb",24));
}
效果: 在引入jackson的jar包,以及开启<mvc:annotation-driven/>之后,访问请求可以看到 界面上显示出 User 的json格式。
说明. ResponseEntity可以理解为 @ResponseBody + @ResponseStatus 的组合.
ResponseEntity类介绍:
ResponseEntity类继承自HttpEntity,有三个关键属性 httpStatus 、body、httpHeader,分别代表响应状态码、响应体、响应头信息;
原理简单记录:
Spring对于@RequestMapping方法返回值有个接口,专门用来处理返回值类型HandlerMethodReturnValueHandler,接口两个声明方法:supportsReturnType判断是否支持对当前返回值类型,如果是支持解析该种返回值,就调用接口第二个方法handleReturnValue,解析@RequestMapping返回值。
Spring4.3.0 <mvc:annotation-driven/>一共会为我们注册15个HandlerMethodReturnValueHandler的实现类. 其中 RequestResponseBodyMethodProcessor用来处理@ResponseBody,而HttpEntityMethodProcessor是用来处理 ReponseEntity类型的返回值. 这里也可以发现一点:HttpEntityMethodProcessor在arrayList中的位置要比RequestResponseBodyMethodProcessor靠前,所以 使用了 ResponseEntity 就没有@ResponseBody出场的机会了.
从HandlerMethodReturnValueHandler接口的第一个方法分析使用满足条件:
代码片段位于:org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor#supportsReturnType
只要@RequestMapping的方法返回值为 HttpEntity的实现类 且不是 RequestEntity类或其子类 就会使用HttpEntityMethodProcessor来处理 请求返回值,简单来说ResponseEntity类就行.
从HandlerMethodReturnValueHandler接口的第二个方法分析使用如何将ResponseEntity返回给浏览器?
代码片段位于:org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor#handleReturnValue
对比@ResponseEntity解析器RequestResponseBodyMethodProcessor,很多地方相似,这两个解析器都继承自AbstractMessageConverterMethodProcessor。
记录下与@ResponseBody不同的地方:1. 可以设置HttpHeaders响应头消息,并通过Response写回;通过这种方式 ResponseEntity可以实现下载文件
2. 可以设置HttpStatus,设置响应状态码.
代码具体地方都和ResponseEntity一样,可以看下我这篇解析:
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { mavContainer.setRequestHandled(true);
if (returnValue == null) {
return;
} ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest); Assert.isInstanceOf(HttpEntity.class, returnValue);
HttpEntity<?> responseEntity = (HttpEntity<?>) returnValue; HttpHeaders outputHeaders = outputMessage.getHeaders();
HttpHeaders entityHeaders = responseEntity.getHeaders();
if (outputHeaders.containsKey(HttpHeaders.VARY) && entityHeaders.containsKey(HttpHeaders.VARY)) {
List<String> values = getVaryRequestHeadersToAdd(outputHeaders, entityHeaders);
if (!values.isEmpty()) {
outputHeaders.setVary(values);
}
}
if (!entityHeaders.isEmpty()) {
for (Map.Entry<String, List<String>> entry : entityHeaders.entrySet()) {
if (!outputHeaders.containsKey(entry.getKey())) {
outputHeaders.put(entry.getKey(), entry.getValue());
}
}
} if (responseEntity instanceof ResponseEntity) {
outputMessage.getServletResponse().setStatus(((ResponseEntity<?>) responseEntity).getStatusCodeValue());
HttpMethod method = inputMessage.getMethod();
boolean isGetOrHead = (HttpMethod.GET == method || HttpMethod.HEAD == method);
if (isGetOrHead && isResourceNotModified(inputMessage, outputMessage)) {
outputMessage.setStatusCode(HttpStatus.NOT_MODIFIED);
// Ensure headers are flushed, no body should be written.
outputMessage.flush();
// Skip call to converters, as they may update the body.
return;
}
} // Try even with null body. ResponseBodyAdvice could get involved.
writeWithMessageConverters(responseEntity.getBody(), returnType, inputMessage, outputMessage); // Ensure headers are flushed even if no body was written.
outputMessage.flush();
}
简单记录下:ResponseEntity小文件下载的方式
@RequestMapping(value="/demo2")
public ResponseEntity demo2() throws IOException {
ClassPathResource resource = new ClassPathResource("download/note.txt");
InputStream in = resource.getInputStream();
byte[] bytes = new byte[in.available()];
in.read(bytes);
HttpHeaders headers=new HttpHeaders();
headers.add("Content-Disposition","attachment;filename="+resource.getFilename());
HttpStatus statusCode=HttpStatus.OK;
return new ResponseEntity(bytes,headers,statusCode);
}
效果等同于:利用@ResponseEntity返回byte数组
//通过 ResponseBody返回文件 二进制文件
@RequestMapping(value="/demo11")
@ResponseBody
public byte[] demo11(HttpServletResponse response) throws IOException {
ClassPathResource resource = new ClassPathResource("download/note.txt");
InputStream in = resource.getInputStream();
byte[] bytes = new byte[in.available()];
in.read(bytes);
response.addHeader("Content-Disposition","attachment;filename="+resource.getFilename());
return bytes;
}
最原始的方式:
@RequestMapping(value="/demo3")
public void demo3(HttpServletResponse response) throws IOException {
ClassPathResource resource = new ClassPathResource("download/note.txt");
InputStream in = resource.getInputStream();
response.addHeader("Content-Disposition","attachment;filename="+resource.getFilename());
FileCopyUtils.copy(in,response.getOutputStream());
}
Spring ResponseEntity的更多相关文章
- [转发]SPRING MVC3.2案例讲解--SPRING MVC3的@ResponseBody和ResponseEntity
在传统的开发过程中,我们的控制CONTROLL层通常需要转向一个JSP视图:但随着WEB2.0相关技术的崛起,我们很多时候只需要返回数据即可,而不是一个JSP页面. SPRING MVC3的@Resp ...
- spring中的ResponseEntity理解
参考: https://blog.csdn.net/weixin_37869477/article/details/82762976 https://blog.csdn.net/sswqzx/arti ...
- 【Spring】源码浅析 - ResponseEntity.ok 转载
https://www.jianshu.com/p/1238bfb29ee1 ResponseEntity.ok具体源码
- Spring MVC中的ResponseEntity和ResponseBody的区别
1.ResponseEntity的优先级高于@ResponseBody. 在不是ResponseEntity的情况下才去检查有没有@ResponseBody注解. 如果响应类型是ResponseEnt ...
- 用Spring中的ResponseEntity文件批量压缩下载
我看了很多网上的demo,先生成ZIP压缩文件,然后再下载. 我这里是生成ZIP文件流 进行下载.(核心代码没多少,就是一些业务代码) @RequestMapping(value = "/& ...
- 基于spring注解AOP的异常处理
一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...
- Spring 4 使用Freemarker模板发送邮件&添加附件
前言 Spring对Java的邮件发送提供了很好的支持,提供了超级简单的API,大大简化了Java邮件发送功能的开发. Spring对Email的支持是基于JavaMail API开发的,所以,我们在 ...
- Spring 4 创建REST API
什么是REST 全称:表述性状态转移 (Representational State Transfer), 将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户端(或者反过来). 面向资源,而 ...
- [Java] Spring MVC 知识点
云图: @Service 用于标注业务层组件. 在 Spring-servlet 配置xml中,component-scan 标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Compone ...
随机推荐
- linux 查看、关闭 ssh pts/n登录的用户
1.查看登录用户: [root@TiaoBan- bin]# w :: up days, :, users, load average: 1.90, 1.75, 1.84 USER TTY FROM ...
- double float的精度问题
三部曲 1: #include <iostream> #include <stdio.h> #include <string.h> using namespace ...
- nips 2016 吴恩达
一年一度的 NIPS 又来了.今年举办地是笔者最爱的欧洲城市巴塞罗那.阳光沙滩配学术,确实很爽.这次的会议的第一天开场的大部分时间安排给了 tutorial.其中人数爆满的依旧是吴恩达(AndrewN ...
- await和async在C#一般处理程序(ashx)中的使用
public class hello : HttpTaskAsyncHandler, IReadOnlySessionState { public IFetchServise fetch { get; ...
- dev gridview自动列宽和单元、行、checkbox选中和多选
#region 自动列宽 for (int I = 0; I < gridView1.Columns.Count; I++) { this.gridView1.BestFitColumns(); ...
- wpf根据X与Y轴获取内部值
效果图: 环境 Visual Studio ,.Net Framework 4.0 SDK 支持Windows XP,Windows Win7.. 实现方法: 创建ListBox设置ListBox.I ...
- 格式化json日期'/Date(-62135596800000)/'
日期经过json序列化之后,变成了'/Date(-62135596800000)/'字符串,在显示数据时,我们需要解释成正常的日期. Insus.NET和js库中,写了一个jQuery扩展方法: $. ...
- 浏览器标识ua
# LinuxLinux / Firefox 29: Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0Linux ...
- 异步三部曲之promise
概述 这是我看你不知道的JavaScript(中卷)的读书笔记,供以后开发时参考,相信对其他人也有用. 例子 首先来看一个例子,如果我们要异步获取x和y,然后把他们打印出来,那么用回调可以编写代码如下 ...
- 【转】如何用css限制文字长度,使溢出的内容用省略号…显示
文章转自这里(现在貌似被黑了,建议不要点击了) ps:因在该地方没看到转载按钮,复制下存到这里以待自己方便,别人能看到帮助一下更是乐意之至,效果亲测可以实现,兼容IE.谷歌.火狐 由于文字内容长度的不 ...