HttpMessageConverter学习
HttpMessageConverter
HttpMessageConverter,报文信息转换器。
作用:
1、将请求报文转化为java对象
2、将java对象转化为响应报文
HttpMessageConverter提供了两个注解和两个类供我们使用:@RequestBody、@ResponseBody;RequestEntity、ResponseEntity。
实例一(获取请求体和请求头)
首先我们创建index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<form th:action="@{/testRequestBody}" method="post">
username<input type="text" name="username"><br>
password<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
<br>
<form th:action="@{/testRequestEntity}" method="post">
username<input type="text" name="username"><br>
password<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
创建跳转成功的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
success
</body>
</html>
创建对应的controller
package com.jin.spring.controller;
import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HttpController {
@RequestMapping("/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("请求头"+requestEntity.getHeaders());
System.out.println("请求体"+requestEntity.getBody());
System.out.println("requestEntity"+requestEntity.toString());
return "success";
}
}
这个时候我们点击第一个按钮
控制台
点击第二个按钮
控制台
实例二(通过servletapi访问response)
再controller里面添加
@RequestMapping("/testResponse")
public void testResponse(HttpServletResponse response) throws IOException {
response.getWriter().print("hello,response");
}
再index.html中添加
<a th:href="@{/testResponse}">通过servletAPI访问response</a>
点击超链接
实例三(responseBody)
我们修改success.html中的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>
再index.html中添加
<a th:href="@{/testResponseBody}">通过response来进行视图数据发送</a>
再控制器中添加
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody(){
return "success";
}
这个时候我们点击我们新加入的超链接
等一下!我们的效果应该是这个样子的呀
为什么? 原来是我们给方法加了一个注解 @ResponseBody,它把我们返回的字符串当作响应的响应体,而不是视图名称
我们把@ResponseBody去掉之后再点击超链接就可以显示
用httpmessageconverter显示json
我们先创建一个实体类User
package com.jin.spring.bean;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
public User() {
}
public User(Integer id, String username, String password, Integer age, String sex) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
编写控制类
@RequestMapping("testResponseUser")
@ResponseBody
public Object testResposeUser(){
User user = new User(1,"金田所","114514",24,"男");
return user;
}
<a th:href="@{/testResponseUser}">通过@RESPONSEbody响应user对象</a>
这个时候我们点击超链接会出现500的错误,是因为我们的http协议是用来对web浏览器和服务器设定约束的,我们又python做服务器的web应用,我们有java、php作为服务器的web应用,它没办法解析一个特定语言的对象,所以这个时候我们要引入json依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
我们再pom.xml导入依赖,同时我们再配置文件中配置
<mvc:annotation-driven/>
这是一个可以自动扫描注解的配置
它会在HandlerAdaptor中自动装配一个消息转换器:MappingJackson2HttpMessageConverter,可以将java对象转换为json格式的字符串
这个时候点击超链接就会出现
springmvc处理ajax
首先我们需要导入vue.js和axios.min.js(这两个都可以从github上爬取下来),并且将它放入我们再webapp下创建的文件夹
首先我们先再index.html中添加
<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({
method:"post",
url:event.target.href,
params:{
username:"admin",
password:"123456"
}
}).then(function (response) {
alert(response.data);
});
event.preventDefault();
}
}
});
</script>
在controller中添加
@RequestMapping("/testAjax")
@ResponseBody
public String testAxios(String username,String password){
System.out.println(username +""+ password);
return "hello,axios";
}
后面我们直接运行
点击testAjax,会出现alert
我们看控制台
@RestController注解
以后会很重要,很常用的一个注解——@RestController。这个注解是SpringMVC提供的一个复合注解,标识在控制器的类上,相当于为这个类添加@Controller注解,并且为这个类中所有的方法添加@ResponseBody注解。
ResponseEntity
用于控制器方法的返回值类型,该控制器方法的返回值就是响应到服务器的响应报文
ResponseEntity实现文件下载
创建一个新的controller.java
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@Controller
public class FileUpAndDownController {
@RequestMapping("/file")
public String toFile(){
return "file";
}
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testDownload(HttpSession session) throws IOException {
/*获取ServletContext对象*/
ServletContext context = session.getServletContext();
/*获取服务器中文件的真实路径*/
String path = context.getRealPath("/static/img/1.jpg");
/*输出路径文件*/
System.out.println(path);
/*创建输入流*/
InputStream inputStream = new FileInputStream(path);
/*创建字节数组*/
byte[] buffer = new byte[inputStream.available()];
/*将流读取到字节数组中*/
inputStream.read(buffer);
/*创建HttpHeaders对象设置响应头信息*/
MultiValueMap<String, String> headers = new HttpHeaders();
/*设置下载的方式和文件名*/
headers.add("Content-Disposition", "attachment;filename=爱丽丝老婆.jpg");
/*设置响应状态码*/
HttpStatus status = HttpStatus.OK;
/*创建ResponseEntity对象*/
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(buffer,headers,status);
/*关闭输入流*/
inputStream.close();
return responseEntity;
}
}
创建file.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>
</body>
</html>
这个时候我们点击下载
下载成功
实现上传功能
在file.html中添加
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
头像<input type="file" name="photo"><br>
<input type="submit" value="上传">
</form>
在pom.xml中添加依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
在springmvc配置文件中配置
<!--文件上传解析器,将上传的文件封装为MultiparFile-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
在controller中添加方法
@RequestMapping(value = "/testUp")
public String testUp(MultipartFile photo,HttpSession session) throws IOException {
//获取文件名
String fileName = photo.getOriginalFilename();
//获取servlet
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";
}
选择上传文件