将请求报文转换为Java对象,或将Java对象转换为响应报文2个注解和2个类型
@RequestBody,@ResponseBody
RequestEntity,ResponseEntity
RequestEntity:表示完整的请求报文(用的少,几乎不用)
该类型用于获取完整的请求报文,一般用在控制器方法的形参位置,不用是因为,都有更方便的方式来获取
- 其中getHeaders()获取请求报文的请求头信息
- 其中getBody()获取请求报文的请求体信息
public String testRequestEntity(RequestEntity entity){
//获取请求报文的请求头信息
HttpHeaders httpHeaders = entity.getHeaders();
//)获取请求报文的请求体信息
String body = entity.getBody();
return "success";
}
@RequestBody 将请求体和形参绑定
@RequestBody 将请求体和形参绑定,可以自动将json格式的请求体转换为java对象
post请求体中存储的数据有两种:
1. name=value&name=value:直接通过控制器方法形参就可以获取
2. json格式的请求参数 {key:value,key:value}:不能直接通过控制器方法的形参获取
对于json格式的请求参数,通过@RequestBody注解标识的控制器方法的形参直接将json格式的请求参数转换为java对象
但是要满足三个条件:
* a>导入jackson的依赖
springmvc默认使用jackson处理json
com.fasterxml.jackson.core
jackson-databind
2.12.1
* b>SpringMVC的配置文件中设置开启mvc的注解驱动,才有jackson相关的处理器
会在HandlerAdaptor中会自动装配一个消息转换器:MappingJackson2HttpMessageConverter,可以将响应到浏览器的Java对象转换为Json格式的字符串
* c>在控制器方法的形参位置,设置json格式的请求参数要转换成的java类型(实体类或map)的参数,并使用@RequestBody注解标识
下面这种方式,是能获取请求体中的json字符串,但是没啥卵用
@RequestMapping("/test/requestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "success";
}
@RequestBody后边一般跟的是实体类对象或者map集合
@RequestMapping("/test/json/requestBody")
@ResponseBody
public String testRequestBody(@RequestBody Map map) throws IOException {
System.out.println(map);
return "hello,axios";
}
//有实体类则用实体类
public void testRequestBody(@RequestBody User user, HttpServletResponse response) throws IOException {
System.out.println(user);
response.getWriter().print("hello,axios");
}
测试结果:
@ResponseBody用于标识一个控制器方法
@ResponseBody可以将标注方法的返回值直接作为响应报文的响应体响应到浏览器
若需要响应到浏览器一个json格式的数据,此时要满足三个条件:
a>导入jackson的依赖(同上)
b>SpringMVC的配置文件中设置开启mvc的注解驱动(同上)
c>在控制器方法上,使用@ResponseBody注解进行标识
@ResponseBody测试一:
不加该注解
@RequestMapping("/test/responseBody")
public String testResponseBody(){
return "success";
}
意思是跳转到"success.html"页面
--------
加了@ResponseBody注解之后
@RequestMapping("/test/responseBody")
@ResponseBody
public String testResponseBody(){
return "success";
}
意思是给浏览器回写数据
@ResponseBody测试二:
让我很惊讶的是我忘记了以前是怎么给浏览器回写数据的,原来方法可以返回值为void,也能给浏览器回写数据。用response
public void testRequestBody(@RequestBody User user, HttpServletResponse response) throws IOException {
System.out.println(user);
response.getWriter().print("hello,axios");
}
说正事,我们的@ResponseBody吊的一批
在控制器方法中,只需要将要转换为json的java对象作为方法的返回值,就会自动转换为json字符串,并响应到浏览器
@RequestMapping("/test/responseBody")
@ResponseBody
public Employee testResponseBody(@RequestBody Employee employee){
System.out.println(employee);
return employee;
}
前端页面:
testResponseBody(){
axios.post(
"/maven_springmvc/test/responseBody",
{id:1001,lastName:"狂野猩",email:"123456",gender:23}
).then(response=>{
console.log(response.data);
});
}
测试结果:@RequestBody获取了请求体中的json数据赋值给Employee对象,并将信息打印到了控制台,之后使用@ResponseBody将该对象以json格式返回给了浏览器,显示在浏览器的控制台
上面方法倘若不加@ResponseBody注解,则响应的是User对象的内存地址或者是重写toString后的内容。
@ResponseBody测试三:
实体类,Map转json字符串再响应给浏览器在浏览器控制台打印的就是json对象
list集合,响应给浏览器在浏览器控制台打印的就是json数组
@RequestMapping("/test/responseBody")
@ResponseBody
public List testResponseBody(@RequestBody Employee employee){
Employee e1 = new Employee(1001,"狂野猩","123456",23);
Employee e2 = new Employee(1002,"猛虎王","123456",23);
Employee e3 = new Employee(1003,"暴龙神","123456",23);
List list = Arrays.asList(e1, e2, e3);
System.out.println(employee);
return list;
}
复合注解@RestController
就相当于为类添加了@Controller注解,
并且为类中的每个方法添加了@ResponseBody注解
ResponseEntity 设置响应到浏览器的响应报文
ResponseEntity类型用在控制器方法的返回值,返回的ResponseEntity就是响应到浏览器的响应报文。用的最多的地方就是文件下载。
使用ResponseEntity实现下载文件的功能
new ResponseEntity(响应体,响应头,响应状态码);
文件下载
MultiValueMap 可以用来获取请求头,也可以用来设置响应头
attachment:以附件方式下载
文件下载:文件由服务器复制到浏览器
ResponseEntity
@RequestMapping("/download")
public ResponseEntity testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("picture");
//D:\workspaces\maven_springmvc\target\maven_springmvc-1.0-SNAPSHOT\picture
realPath = realPath + File.separator + "guanxiaotong.jpg";
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组,is.available()获取字节输入流所对应文件所有的字节数
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=guanxiaotong.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}
文件名有中文怎么解决??
文件上传 是要求必须掌握的
poi:通过java代码操作办公软件
文件上传的步骤:
1、导入commons-fileupload的依赖
commons-fileupload
commons-fileupload
1.3.1
2、在SpringMVC的配置文件“springMVC.xml”中设置文件上传解析器,BeanId是固定的,且必须设置。MultipartResolver是接口,得用它的实现类
3、在页面中设置form表单,表单中设置文件域并且form的提交方式必须为post,form中必须设置属性enctype="multipart/form-data",表示以二进制传输数据,默认是name=value&name=value
页面效果:
4、可以在控制器方法的形参位置,获取封装了上传的文件封装的MultipartFile对象,通过此对象可以获取文件相关信息
MultipartFile 封装了请求数据中的文件,此时这个文件存储在内存中或临时的磁盘文件中,需要将其转存到一个合适的位置,因为请求结束后临时存储将被清空。在 MultipartFile 接口中有如下方法:
- String getName(); // 获取参数的名称
- String getOriginalFilename(); // 获取文件的原名称
- String getContentType(); // 文件内容的类型
- boolean isEmpty(); // 文件是否为空
- long getSize(); // 文件大小
- byte[] getBytes(); // 将文件内容以字节数组的形式返回
- InputStream getInputStream(); // 将文件内容以输入流的形式返回
- void transferTo(File dest); // 将文件内容传输到指定文件中
- 看着这么多代码,实际上都是为了给transferTo()方法传参的。
- 往哪上传:以后会上传到七牛云或者文件服务器,但是现在只能传到部署路径。
- 写到某个文件中,而不是写到某一个目录中。
- MultipartFile是SpringMVC封装上传文件的类型
@RequestMapping("/up") public String testUp(MultipartFile photo, HttpSession session) throws IOException { //获取ServletContext ServletContext servletContext = session.getServletContext(); //获取当前web应用的真实路径 String photoPath = servletContext.getRealPath("photo"); //获取服务器中photo目录所对应的文件 File file = new File(photoPath); //判断file所对应的目录是否存在,若不存在则创建 if(!file.exists()){ file.mkdir(); } //获取上传的文件的文件名 String fileName = photo.getOriginalFilename(); //获取随机序列UUID String uuid = UUID.randomUUID().toString(); //获取上传的文件的后缀名 String hzName = fileName.substring(fileName.lastIndexOf(".")); //获取新的文件名 fileName = uuid + hzName; //获取上传文件的最终位置 String finalPath = photoPath + File.separator + fileName; //上传文件 photo.transferTo(new File(finalPath)); return "success"; }
上传成功:
这个UUID就很灵性: