简单记录下 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. HTML 基础 块级元素与行内元素

    块元素:单独占一行,宽度占整行,可以包含内联元素和其他块元素,通过样式display:inline,变为行内元素,不换行 内联元素:不单独占一行,宽度根据内容来决定,只能容纳文本或者其他内联元素 ,可 ...

  2. ORACLE EBS常用表

    http://www.cnblogs.com/quanweiru/archive/2012/09/26/2704628.html call fnd_global.APPS_INITIALIZE(131 ...

  3. Android-WebView与本地HTML (HTML调用-->Java的方法)

    上一篇博客 Android-WebView加载网络图片&网页 介绍了 使用WebView去加载网络上的图片与网页; 此篇博客专门介绍 Android-WebView与本地HTML (HTML调 ...

  4. 在Asp.Net MVC中利用快递100接口实现订阅物流轨迹功能

    前言 分享一篇关于在电商系统中同步物流轨迹到本地服务器的文章,当前方案使用了快递100做为数据来源接口,这个接口是收费的,不过提供的功能还是非常强大的,有专门的售后维护团队.也有免费的方案,类似于快递 ...

  5. CE修改器使用教程 [基础篇]

    Cheat Engine  是一款内存修改编辑工具 ,它允许你修改你的游戏或软件内存数据,以得到一些其他功能.它包括16进制编辑,反汇编程序,内存查找工具.与同类修改工具相比,它具有强大的反汇编功能, ...

  6. 520 简单表白代码(JS)

    这两天不知道咋了,迷迷糊糊的,突然知道今天是520的我,急急忙忙赶出个程序(新手,代码有点乱),发出来大家一起研究下(参考百度的). <!DOCTYPE html> <html> ...

  7. 【Spark调优】:RDD持久化策略

    [场景] Spark对RDD执行一系列算子操作时,都会重新从头到尾计算一遍.如果中间结果RDD后续需要被被调用多次,可以显式调用 cache()和 persist(),以告知 Spark,临时保存之前 ...

  8. 【Spark算子】:reduceByKey、groupByKey和combineByKey

    在spark中,reduceByKey.groupByKey和combineByKey这三种算子用的较多,结合使用过程中的体会简单总结: 我的代码实践:https://github.com/wwcom ...

  9. UICollectionView设置首个cell默认选中(二)

    上篇对于UICollectionView默认选中cell采取的是每个cell分别对应一个标识,也就代表着废除了UICollectionView的重用机制.对于较少的数据情况是可以的,但是对于数据比较大 ...

  10. linux 服务器脚本采集数据中文无法执行错误

    问题描述:在 RHEL6 版本的服务器上使用脚本操作数据库,其中一个SQL的字段值为中文,每次使用 crontab定时 执行该脚本无法获取数据,实现预期效果,而手动执行正常. oracle clien ...