Spring MVC 系列:HttpMessageConverter(@RequestBody、RequestEntity、@ResponseBody、@RestController、ResponseEntity、文件上传下载)
HttpMessageConverter,报文信息转换器,将请求报文转换为Java对象,或将Java对象转换为响应报文
HttpMessageConverter提供了两个注解和两个类型:@RequestBody,@ResponseBody,RequestEntity,ResponseEntity
一、@RequestBody
@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<form method="post" th:action="@{/testRequestBody}">
用户名:<input type="text" name="username"/> <br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录">
</form>
</form>
</body>
</html>
java
package com.mcode.api.controller;
import com.mcode.api.bean.User;
import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* ClassName: HttpController
* Package: com.mcode.api.controller
* Description:
*
* @Author robin
* @Create 2023/8/8 21:58
* @Version 1.0
*/
@Controller
public class HttpController {
@RequestMapping(value = "/testRequestBody")
public String testRequestBody(@RequestBody String requestBody) {
System.out.println("requestBody:" + requestBody);
return "success";
}
}
输出结果:
二、RequestEntity
RequestEntity封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的请求报文就会赋值给该形参,可以通过getHeaders()获取请求头信息,通过getBody()获取请求体信息
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<form method="post" th:action="@{/testRequestBody}">
用户名:<input type="text" name="username"/> <br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录">
</form>
</form>
<h2>testRequestEntity</h2>
<form method="post" th:action="@{/testRequestEntity}">
用户名:<input type="text" name="username"/> <br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
java
package com.mcode.api.controller;
import com.mcode.api.bean.User;
import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* ClassName: HttpController
* Package: com.mcode.api.controller
* Description:
*
* @Author robin
* @Create 2023/8/8 21:58
* @Version 1.0
*/
@Controller
public class HttpController {
@RequestMapping(value = "/testRequestBody")
public String testRequestBody(@RequestBody String requestBody) {
System.out.println("requestBody:" + requestBody);
return "success";
}
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String> requestEntity) {
System.out.println("requestHeader:" + requestEntity.getHeaders());
System.out.println("requestBody:" + requestEntity.getBody());
return "success";
}
}
输出结果:
三、@ResponseBody
@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
html
<a th:href="@{/testResponseBody}">测试testResponseBody</a>
java
produces = "text/html;charset=UTF-8" 设置返回数据的类型以及编码
package com.mcode.api.controller;
import com.mcode.api.bean.User;
import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* ClassName: HttpController
* Package: com.mcode.api.controller
* Description:
*
* @Author robin
* @Create 2023/8/8 21:58
* @Version 1.0
*/
@Controller
public class HttpController {
@RequestMapping(value = "/testRequestBody")
public String testRequestBody(@RequestBody String requestBody) {
System.out.println("requestBody:" + requestBody);
return "success";
}
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String> requestEntity) {
System.out.println("requestHeader:" + requestEntity.getHeaders());
System.out.println("requestBody:" + requestEntity.getBody());
return "success";
}
@RequestMapping(value = "/testResponseBody",produces = "text/html;charset=UTF-8")
@ResponseBody
public String testResponseBody(){
return "成功";
}
}
四、SpringMVC处理json
@ResponseBody处理json的步骤:
a>导入jackson-databind依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
b>在SpringMVC的核心配置文件中开启mvc的注解驱动,此时在HandlerAdaptor中会自动装配一个消息转换器:MappingJackson2HttpMessageConverter,可以将响应到浏览器的Java对象转换为Json格式的字符串
<!-- 开启MVC注解驱动 -->
<mvc:annotation-driven/>
c>在处理器方法上使用@ResponseBody注解进行标识
@RequestMapping("/testResponseBodyJSON")
@ResponseBody
public User testResponseBodyJSON(){
return new User(1,"张三","123456");
}
d>将Java对象直接作为控制器方法的返回值返回,就会自动转换为Json格式的字符串
输出结果:
五、@RestController
@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解
六、ResponseEntity
ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文
七、文件上传和下载
1、文件下载
使用ResponseEntity实现下载文件的功能
html
<a th:href="@{/testDown}">下载1.jpg</a><br>
java
package com.mcode.api.controller;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
/**
* ClassName: FileUpAndDownController
* Package: com.mcode.api.controller
* Description:
*
* @Author robin
* @Create 2023/8/8 22:58
* @Version 1.0
*/
@RestController
public class FileUpAndDownController {
/**
* 测试下载
* @param session
* @return
* @throws IOException
*/
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testDown(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
System.out.println(realPath);
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> 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;
}
}
2、文件下载
文件上传要求form表单的请求方式必须为post,并且添加属性enctype="multipart/form-data"
SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息
上传步骤:
a>添加依赖:
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.5</version>
</dependency>
b>在SpringMVC的配置文件中添加配置:
必须配置id
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
c>控制器方法:
package com.mcode.api.controller;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
/**
* ClassName: FileUpAndDownController
* Package: com.mcode.api.controller
* Description:
*
* @Author robin
* @Create 2023/8/8 22:58
* @Version 1.0
*/
@RestController
public class FileUpAndDownController {
/**
* 上传文件
* @param file
* @param session
* @return
* @throws IOException
*/
@RequestMapping("/testUp")
public String testUp(MultipartFile file,HttpSession session) throws IOException{
//获取上传的文件的文件名
String fileName = file.getOriginalFilename();
//获取上传的文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//将UUID作为文件名
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
//将uuid和后缀名拼接后的结果作为最终的文件名
fileName = uuid + suffixName;
//通过ServletContext获取服务器中upload目录的路径
ServletContext servletContext = session.getServletContext();
String realPath = servletContext.getRealPath("/upload");
File upFilePath = new File(realPath);
//判断upFilePath所对应路径是否存在
if(!upFilePath.exists()){
//若不存在,则创建目录
upFilePath.mkdirs();
}
String finalPath = realPath + File.separator + fileName;
//上传文件
file.transferTo(new File(finalPath));
return fileName;
}
}
d>html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>测试上传和下载</title>
</head>
<body>
<a th:href="@{/testDown}">下载1.jpg</a><br>
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
头像:<input type="file" name="file"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
注:必须在SpringMVC的配置文件中添加CommonsMultipartResolver的bean中配置Id,否则报错
八、全部代码
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mcode.api</groupId>
<artifactId>java-spring-mvc-demo03</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--SpringMVC-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.29</version>
</dependency>
<!--日志-->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.8</version>
<scope>test</scope>
</dependency>
<!--ServletAPI-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--Spring5和Thymeleaf整合包-->
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring5 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<finalName>java-spring-mvc-demo03</finalName>
</build>
</project>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.mcode.api.controller"/>
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- 接地跳转到目标页面 -->
<mvc:view-controller path="/" view-name="index"/>
<mvc:view-controller path="/file" view-name="file"/>
<!-- 静态资源处理器 -->
<mvc:default-servlet-handler/>
<!-- 开启MVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
</beans>
微信:17873041739