简单记录下 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的更多相关文章

  1. [转发]SPRING MVC3.2案例讲解--SPRING MVC3的@ResponseBody和ResponseEntity

    在传统的开发过程中,我们的控制CONTROLL层通常需要转向一个JSP视图:但随着WEB2.0相关技术的崛起,我们很多时候只需要返回数据即可,而不是一个JSP页面. SPRING MVC3的@Resp ...

  2. spring中的ResponseEntity理解

    参考: https://blog.csdn.net/weixin_37869477/article/details/82762976 https://blog.csdn.net/sswqzx/arti ...

  3. 【Spring】源码浅析 - ResponseEntity.ok 转载

    https://www.jianshu.com/p/1238bfb29ee1 ResponseEntity.ok具体源码

  4. Spring MVC中的ResponseEntity和ResponseBody的区别

    1.ResponseEntity的优先级高于@ResponseBody. 在不是ResponseEntity的情况下才去检查有没有@ResponseBody注解. 如果响应类型是ResponseEnt ...

  5. 用Spring中的ResponseEntity文件批量压缩下载

    我看了很多网上的demo,先生成ZIP压缩文件,然后再下载. 我这里是生成ZIP文件流 进行下载.(核心代码没多少,就是一些业务代码) @RequestMapping(value = "/& ...

  6. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  7. Spring 4 使用Freemarker模板发送邮件&添加附件

    前言 Spring对Java的邮件发送提供了很好的支持,提供了超级简单的API,大大简化了Java邮件发送功能的开发. Spring对Email的支持是基于JavaMail API开发的,所以,我们在 ...

  8. Spring 4 创建REST API

    什么是REST 全称:表述性状态转移 (Representational State Transfer), 将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户端(或者反过来). 面向资源,而 ...

  9. [Java] Spring MVC 知识点

    云图: @Service 用于标注业务层组件. 在 Spring-servlet 配置xml中,component-scan 标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Compone ...

随机推荐

  1. ASP.NET Web API 框架研究 ASP.NET 路由

    ASP.NET Web API 如果采用Web Host方式来寄宿,在请求进入Web API 消息处理管道之前,就会用ASP.NET 自身的路由系统根据注册的路由表,解析出当前请求的HttpContr ...

  2. 20164317 《网络对抗技术》Exp6 信息搜集与漏洞扫描

    Exp6 信息搜集与漏洞扫描 一.原理与实践说明 (1)实践原理 信息搜集:渗透测试中首先要做的重要事项之一,搜集关于目标机器的一切信息 间接收集 DNS记录扫描和枚举 CorpWatch:auxil ...

  3. per学习笔记-zkclient,curator使用

    开源客户端,原生api的不足 连接的创建是异步的,需要开发人员自行编码实现等待 连接没有自动的超时重连机制 Zk本身没提供序列化机制,需要开发人员自行指定,从而实现数据的序列化和反序列化 Watche ...

  4. C#6.0语言规范(十五) 委托

    委托启用其他语言(如C ++,Pascal和Modula)已使用函数指针进行寻址的方案.但是,与C ++函数指针不同,委托是完全面向对象的,与成员函数的C ++指针不同,委托封装了对象实例和方法. 委 ...

  5. sublime text3: markdown 安装及常用语法简介

    自己上传到 github 上的 README.rdm 文件内容显示没有“美化”,所有内容都挤在一块儿了,很不舒服. 原因是:github 的文档 README.rdm 文件使用 markdown 编辑 ...

  6. git fetch 、git pull 与 git pull --rebase

    1. git fetch 与 git pull 都是从远程拉取代码到本地,git fetch只是拉取到本地,git pull不仅拉取到本地还merge到本地分支中.所以git pull是git fet ...

  7. DockerFile(保你会版本)(七)

    一.什么是dockerfile Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile自定义快速创建属于自己的镜像,Dockerfile是通过很多的参数指令编写的文件,通过do ...

  8. vue教程1-04 事件 v-on:click="函数"

    vue教程1-04 事件 v-on:click="函数"   v-on:click/mouseout/mouseover/dblclick/mousedown..... 实例:为d ...

  9. centos7.2 部署zabbix 3.2.7

    centos7.2 部署zabbix 3.2.7[zabbix@zabbixServer ~]$ cat /etc/redhat-release CentOS Linux release 7.2.15 ...

  10. (转载)Centos下Elasticsearch安装详细教程

    原文地址:http://www.cnblogs.com/sunny1009/articles/7874251.html Centos下Elasticsearch安装详细教程 1.Elasticsear ...