目录
八、ResponseEntity-返回值作为响应报文,实现文件下载
HttpMessageConverter,报文信息转换器,将请求报文转换为Java对象,或将Java对象转换为响应报文。 HttpMessageConverter提供了两个注解和两个类型:
@RequestBody,@ResponseBody, RequestEntity, ResponseEntity(文件下载)
@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值
- <form th:action="@{/testRequestBody}" method="post">
- 用户名:<input type="text" name="username"><br/>
- 密码:<input type="password" name="password"><br/>
- <input type="submit">
- form>
- @RequestMapping("/testRequestBody")
- public String testRequestBody(@RequestBody String requestBody){
- System.out.println("requestBody:"+requestBody);
- return "success";
- }
输出结果:
requestBody:username=admin&password=123456
RequestEntity封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的请求报文就会赋值给该形参,可以通过getHeaders()获取请求头信息,通过getBody()获取请求体信息
- <form th:action="@{/testRequestEntity}" method="post">
- 用户名:<input type="text" name="username"><br/>
- 密码:<input type="password" name="password"><br/>
- <input type="submit">
- form>
- @RequestMapping("/testRequestEntity")
- public String testRequestEntity(RequestEntity
requestEntity) { - System.out.println("requestHeader:"+requestEntity.getHeaders());
- System.out.println("requestBody:"+requestEntity.getBody());
- return "success";
- }
输出结果:
- requestHeader:[host:"localhost:8080", connection:"keep-alive", content-length:"24", cache-control:"max-age=0", sec-ch-ua:"" Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103"", sec-ch-ua-mobile:"?0", sec-ch-ua-platform:""Windows"", upgrade-insecure-requests:"1", origin:"http://localhost:8080", user-agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71", accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", sec-fetch-site:"same-origin", sec-fetch-mode:"navigate", sec-fetch-user:"?1", sec-fetch-dest:"document", referer:"http://localhost:8080/SpringMVC/", accept-encoding:"gzip, deflate, br", accept-language:"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", cookie:"JSESSIONID=8B43926B2EC67BD7894DC19AB0F9E017; Idea-78910da9=e89c6d10-8e05-4fd7-8e94-8d41c1b52e21", Content-Type:"application/x-www-form-urlencoded;charset=UTF-8"]
- requestBody:username=wz&password=111
@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
<a th:href="@{/testResponseBody}">响应体a><br/>
- @RequestMapping("/testResponseBody")
- @ResponseBody
- public String testResponseBody(){
- return "我是响应体!!!";
- }
首先导入jackson的依赖
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.12.1version>
- dependency>
在处理器方法上使用@ResponseBody注解进行标识 ,将Java对象直接作为控制器方法的返回值返回,就会自动转换为Json格式的字符串
- <form th:action="@{/testJson}" method="post">
- 用户名:<input type="text" name="username"><br>
- 密码:<input type="password" name="password"><br>
- <input type="submit">
- form>
- @RequestMapping("/testJson")
- @ResponseBody
- public User testJson(String username,String password){
- return new User(username,password);//响应给浏览器的就是json对象
- }
- <div id="app">
- <h1>testAjaxh1>
- <a th:href="@{/testAjax}" @click="testAjax">testAjaxa><br>
- div>
-
- <script type="text/javascript" th:src="@{/static/js/vue.js}">script>
- <script type="text/javascript" th:src="@{/static/js/axios.min.js}">script>
- <script type="text/javascript">
- var vue = new Vue({
- el:"#app",
- methods:{
- testAjax:function (event) {
- axios({
- method:"post",
- url:event.target.href,
- params:{
- username:"admin",
- password:"123456" //传给服务器的参数
- }
- }).then(function (response) {
- alert(response.data); //显示响应的内容
- });
- event.preventDefault();
- }
- }
- });
- script>
- @RequestMapping("/testAjax")
- @ResponseBody
- public String testAjax(String username, String password){
- System.out.println("username:"+username+",password:"+password);
- return "hello,ajax";//这是返回给浏览器的数据
- }
@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了 @Controller注解,并且为其中的每个方法添加了@ResponseBody注解
ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文。使用ResponseEntity可实现文件下载的功能
<a th:href="@{/testDown}">下载1.jpga><br>
- @RequestMapping("/testDown")
- public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
- //获取ServletContext对象
- ServletContext servletContext = session.getServletContext();
- //获取服务器中文件的真实路径
- String realPath = servletContext.getRealPath("/static/img/1.jpg");
- //创建输入流
- InputStream is = new FileInputStream(realPath);
- //创建字节数组
- byte[] bytes = new byte[is.available()];
- //将流读到字节数组中
- is.read(bytes);
- //创建HttpHeaders对象设置响应头信息
- MultiValueMap
headers = new HttpHeaders(); - //设置要下载方式以及下载文件的名字
- headers.add("Content-Disposition", "attachment;filename=1.jpg");
- //设置响应状态码
- HttpStatus statusCode = HttpStatus.OK;
- //创建ResponseEntity对象
- ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
- //关闭输入流
- is.close();
- return responseEntity;
- }
文件上传要求form表单的请求方式须为post,添加属性enctype="multipart/formdata"。SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息
添加依赖:
- <dependency>
- <groupId>commons-fileuploadgroupId>
- <artifactId>commons-fileuploadartifactId>
- <version>1.3.1version>
- dependency>
在SpringMVC的配置文件中添加配置:
- <bean id="multipartResolver"
- class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- bean>
核心代码:
- <form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
- 头像:<input type="file" name="photo"><br>
- <input type="submit" value="上传">
- form>
- @RequestMapping("/testUp")
- public String testUp(MultipartFile photo, HttpSession session) throws IOException {
- //获取上传的文件的文件名
- String fileName = photo.getOriginalFilename();
- //处理文件重名问题
- String hzName = fileName.substring(fileName.lastIndexOf("."));//获取后缀名
- fileName = UUID.randomUUID().toString() + hzName;//生成新的不会重复的文件名
- //获取服务器中photo目录的路径
- ServletContext servletContext = session.getServletContext();
- String photoPath = servletContext.getRealPath("photo");
- File file = new File(photoPath);
- if(!file.exists()){
- file.mkdir();//如果目录不存在,就创建一个
- }
- String finalPath = photoPath + File.separator + fileName;//最终的路径
- //实现上传功能
- photo.transferTo(new File(finalPath));
- return "success";
- }