22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传

一、HttpMessageConverter 报文信息转换器

将请求报文转换为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");
    }

测试结果:

22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传_第1张图片


@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");
    }

22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传_第2张图片

说正事,我们的@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格式返回给了浏览器,显示在浏览器的控制台

22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传_第3张图片


上面方法倘若不加@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;
    }

22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传_第4张图片


复合注解@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); // 将文件内容传输到指定文件中
  1. 看着这么多代码,实际上都是为了给transferTo()方法传参的。
  2. 往哪上传:以后会上传到七牛云或者文件服务器,但是现在只能传到部署路径。
  3. 写到某个文件中,而不是写到某一个目录中。
  4. 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";
    }

上传成功:

22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传_第5张图片

这个UUID就很灵性: 

22-06-20 西安 ssm springmvc(03) RequestEntity、@RequestBody、@ResponseBody、ResponseEntity 、文件下载与文件上传_第6张图片

你可能感兴趣的:(笔记,java,开发语言)