HttpMessageConverter,又叫报文信息转换器,可以将请求报文转化为 Java 对象,或者将 Java 对象转化为响应报文。其中提供了两个注解和两个类型:@RequestBody,@ResponseBody,RequestEntity,ResponseEntity。
目录
@RequestBody
@RequestBody 可以获取到请求的请求体,需要在请求方法中设置一个形参,使用 @RequestBody 来进行标识。
测试
前台表单
<form th:action="@{/testRequestBody}" method="post">
用户:<input type="text" name="username">
密码:<input type="text" name="password">
<input type="submit" value="提交">
</form>
控制器方法
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String requestBody){
System.out.println(requestBody);
return "success";
}
结果:成功获取到了该请求的请求体
RequestEntity
RequestEntity 是封装请求报文的一种类型,我们如果在控制器方法的形参位置设置一个该类型的形参,那么当前请求的请求报文就会赋值给该形参,然后我们就可以使用该形参通过 getHeaders() 获取请求头信息,通过 getBody() 获取请求体信息
测试
前台表单
控制器方法
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String> requestEntity){
System.out.println(requestEntity.getHeaders());
System.out.println(requestEntity.getBody());
return "success";
}
结果:可以发现成功打印了请求头和请求体信息
@ResponseBody(重要)
@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
测试
前台链接
控制器方法1:我们可以知道这是会跳转到 success.html 页面的
@RequestMapping("/testResponseBody")
// @ResponseBody
public String testResponseBody(){
return "success";
}
控制器方法2:加上注解就会在页面输出 success
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody(){
return "success";
}
@ResponseBody处理JSON
步骤
①:导入 jackson 的相关依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
②:在 SpringMVC 的核心配置文件中开启mvc的注解驱动
<mvc:annotation-driven></mvc:annotation-driven>
③:在控制器方法上使用 @ResponseBody 注解进行标识
④:将 Java 对象直接作为控制器方法的返回值返回,就会自动转换为 Json 格式的字符串
@RequestMapping("/testResponseUser")
@ResponseBody
public User testResponseUser(){
return new User("TheShy", "TS666", 1, "男");
}
处理ajax
前台页面:使用 vue 和 axiso 发送一个 ajax 请求
<div id="app">
<a th:href="@{/testAjax}" @click="testAjax">testAjax</a><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({
methods:"post",
url:event.target.href,
params:{
username:"admin",
password:"123456"
}
}).then(function (response) {
alert(response.data);
});
event.preventDefault();
}
}
});
</script>
注:一定要开启相应的注解驱动,如下,否则 js 静态文件加载不进来,最开始少加了一个,页面一直跳转😭😭😭
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
控制器方法
@RequestMapping("testAjax")
@ResponseBody
public String testAxios(String username, String password){
System.out.println(username + ", " + password);
return "hello, axios";
}
结果:点击链接后会弹出提示框,然后控制台会打印服务器获得的 ajax 请求发送的数据,但是页面不会跳转
@RestController注解
该注解是 SpringMVC 中的一个复合注解,表示在控制器的类上,相当于为该类添加了 @Controller 注解,并且为其中的每一个控制器方法都添加上了 @ResponseBody 注解
ResponseEntity
ResponseEntity 用于设置控制器方法的返回值类型,设置之后该控制器方法的返回值就是响应到浏览器的响应报文
使用ResponseEntity实现下载文件的功能
现在在服务器中有一张图片,实现在网页中进行下载
前台页面
控制器方法
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/hhh.jpg");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组,is.available()是用来获取输入流文件所有的字节
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=hhh.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}
结果:成功下载了服务器中的图片
使用ResponseEntity实现上传文件的功能
文件上传要求 form 表单的请求方式必须为 post,并且添加属性 enctype="multipart/form-data",设置了该属性后 form 表单会将文件以二进制的方式上传,SpringMVC 中将上传的文件封装到MultipartFile 对象中,通过此对象可以获取文件相关信息
上传步骤:
①:添加依赖
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
②:在SpringMVC的配置文件中添加配置:
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<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";
}
结果:文件成功上传到了服务器中的 photo 文件夹中