前面几篇博文介绍了如何获取get/post传参,既然是http请求,一般也都是有来有往,有请求参数传递,就会有数据返回。那么我们通过springboot搭建的web应用,可以怎样返回数据呢?
本篇将主要介绍以下几种数据格式的返回实例
首先得搭建一个web应用才有可能继续后续的测试,借助SpringBoot搭建一个web应用属于比较简单的活;
创建一个maven项目,pom文件如下
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7</version> <relativePath/> <!-- lookup parent from update --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </pluginManagement> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
依然是一般的流程,pom依赖搞定之后,写一个程序入口
/** * Created by @author yihui in 15:26 19/9/13. */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class); } }
以下都中返回实例都放在同一个Controller中,具体定义如下
@Controller @RequestMapping(path = "data") public class DataRespRest { }
这个属于基础功能了,发起请求,返回一串文本,在SpringMVC的体系中,要实现这种通常的写法通常是直接定义方法的返回为String;当然还有另外一种非常基础的写法,直接将返回的数据通过 HttpServletResponse
的输出流中
下面给出这两种写法的实例
@ResponseBody @GetMapping(path = "str") public String strRsp() { return "hello " + UUID.randomUUID().toString(); } @ResponseBody @GetMapping(path = "str2") public void strRsp2(HttpServletResponse response) throws IOException { Map<String, String> ans = new HashMap<>(2); ans.put("a", "b"); ans.put("b", "c"); response.getOutputStream().write(JSON.toJSONString(ans).getBytes()); response.getOutputStream().flush(); }
注意上面的实现中,方法上面多了一个注解 @ResponseBody
,这个表示返回数据,而不是视图(后面会详细说明)
strRsp2
的输出借助了FastJson来实现将map序列化为json串,然后写入输出流
实例访问如下
从上面的输出也可以看出,第一种返回方式, ResponseHeaders
的 Content-Type: text/html;charset=UTF-8
;而第二种方式则没有这个响应头,需要我们自己主动设置(这里注意一下即可,在后面的返回图片中会介绍如何处理)
前面请求参数中允许传入输出参数,那么我们返回可以直接返回数组么?讲道理也应该是可以的
/** * 返回数组 * * @return */ @ResponseBody @GetMapping(path = "ary") public String[] aryRsp() { return new String[]{UUID.randomUUID().toString(), LocalDateTime.now().toString()}; }
然后请求输出为
注意下响应头,为 application/json
, 也就是说SpringMVC将数组当成json串进行返回了
在我们实际的业务开发中,这种应该属于非常常见的,直接返回一个POJO,调用者接受到一个json串,可以很容易的反序列化为我们需要的类型
/** * 返回POJO * * @return */ @ResponseBody @GetMapping(path = "bean") public DemoRsp beanRsp() { return new DemoRsp(200, "success", UUID.randomUUID().toString() + "--->data"); }
前面都是直接返回数据,但是我们平常使用浏览器中,更多的是发起一个请求,然后返回一个网页啊,难道说springmvc不能直接返回网页么?
当然是可以返回的,个人感觉在前后端分离逐渐流行之后,直接由后端返回网页的case不太多了,前端和后端作为独立的项目部署,两者之间通过json串进行交流;这里扯远了,我们下面看一下SpringMVC中如何返回网页
从上面直接返回字符串的case中,有一个想法,如果我直接返回一个html文本,会怎样?
@ResponseBody @GetMapping(path = "html") public String strHtmlRsp() { return "<html>/n" + "<head>/n" + " <title>返回数据测试</title>/n" + "</head>/n" + "<body>/n" + "<h1>欢迎欢迎,热烈欢迎</h1>/n" + "</body>/n" + "</html>"; }
测试如下
浏览器发起请求之后,将我们返回的html文本当做网页正常渲染了,所以我们如果想返回网页,就这么干么?
上面这种方式虽然说可以返回网页,但如果实际业务中真要这么干,估计分分钟转岗,还干什么后端!!!
下面看一下更常规的写法,首先我们需要配置下返回视图的前缀、后缀, 在 application.yml
配置文件中添加如下配置
spring: mvc: view: prefix: / suffix: .html
然后我们的静态网页,放在资源文件的static目录下,下面是我们实际的项目截图,index.html为我们需要返回的静态网页
接下来就是我们的服务接口
/** * 返回视图 * * @return */ @GetMapping(path = "view") public String viewRsp() { return "index"; }
注意下上面的接口,没有 @ResponseBody
注解,表示这个接口返回的是一个视图,会从static目录下寻找名为 index.html
(前缀路径和后缀是上面的application.yml中定义)的网页返回
实测case如下
图片返回与前面的又不太一样了,上面介绍的几种case中,要么是返回文本,要么返回视图,而返回图片呢,更多的是返回图片的字符数组,然后告诉浏览器这是个图片,老哥你按照图片渲染
直接返回二进制流,上面在介绍文本返回的两种方式中,有个直接通过 HttpServletResponse
向输出流中写数据的方式,我们这里是不是可以直接这么用呢?
下面给出一个从网络下载图片并返回二进制流的实际case
/** * 返回图片 */ @GetMapping(path = "img") public void imgRsp(HttpServletResponse response) throws IOException { response.setContentType("image/png"); ServletOutputStream outStream = response.getOutputStream(); String path = "https://spring.hhui.top/spring-blog/imgs/info/info.png"; URL uri = new URL(path); BufferedImage img = ImageIO.read(uri); ImageIO.write(img, "png", response.getOutputStream()); System.out.println("--------"); }
注意下上面的实例case,首先设置了返回的 ContentType
,然后借助 ImateIO
来下载图片(个人不太建议这种写法,很容易出现403),并将图片写入到输出流
实例演示如下
本篇博文主要介绍了几种常见数据格式的返回使用姿势,本文更多的是一种使用方式的实例case演示,并没有涉及到底层的支持原理,也没有过多的提及如何设置响应头,web交互中常见的cookies/session也没有说到,这些将作为下篇的内容引入,恳请关注
下面做一个简单的小结
@ResponseBody
注解,则表示我们返回的是数据,而不需要进行视图解析渲染; @RestController
注解,然后这个类中的接口都不需要添加 @ResponseBody
注解了 HttpServletResponse
的输出流中写数据的方式来返回数据,如返回图片常用这种case 尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
打赏 如果觉得我的文章对您有帮助,请随意打赏。