数据响应与内容协商

数据响应与内容协商

在这里插入图片描述

1、响应JSON

1.1、jackson.jar+@ResponseBody

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
web场景自动引入了json场景
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-json</artifactId>
      <version>2.3.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
package com.wenliang.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.wenliang.bean.Person;

import java.util.Date;

@Controller
public class ResponseTestController {
    
    

    @ResponseBody
    @GetMapping("/test/person")
    public Person getPerson(){
    
    
        Person person = new Person();
        person.setAge(20);
        person.setBirth(new Date());
        person.setUserName("ayan");
        return person;
    }


}

给前端自动返回json数据;

2、内容协商

根据客户端接收能力不同,返回不同媒体类型的数据。

1、引入xml依赖

 <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

2、postman分别测试返回json和xml

只需要改变请求头中Accept字段。Http协议中规定的,告诉服务器本客户端可以接收的数据类型。
在这里插入图片描述

3、开启浏览器参数方式内容协商功能

为了方便内容协商,开启基于请求参数的内容协商功能。

spring:
    contentnegotiation:
      favor-parameter: true  #开启请求参数内容协商模式

发请求:
http://localhost:8080/test/person?format=json
http://localhost:8080/test/person?format=xml

4、自定义 MessageConverter

实现多协议数据兼容。json、xml、x-guigu
0、@ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理
1、Processor 处理方法返回值。通过 MessageConverter 处理
2、所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)
3、内容协商找到最终的 messageConverter

SpringMVC的什么功能。一个入口给容器中添加一个 WebMvcConfigurer

 @Bean
    public WebMvcConfigurer webMvcConfigurer(){
    
    
        return new WebMvcConfigurer() {
    
    

            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    
    

            }
        }
    }
package com.wenliang.converter;

import com.wenliang.bean.Person;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

public class AyanMessageConverter implements HttpMessageConverter<Person> {
    
    

    @Override
    public boolean canRead(Class<?> aClass, MediaType mediaType) {
    
    
        return false;
    }

    @Override
    public boolean canWrite(Class<?> aClass, MediaType mediaType) {
    
    
        return false;
    }

    /**
     * 服务器要统计所有MessageConverter都能写出哪些内容类型
     * application/x-ayan
     * @return
     */
    @Override
    public List<MediaType> getSupportedMediaTypes() {
    
    
        return MediaType.parseMediaTypes("application/x-ayan");
    }

    @Override
    public Person read(Class<? extends Person> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
    
    
        return null;
    }

    @Override
    public void write(Person person, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
    
    
        //自定义协议数据的写出
        String data  = person.getUserName()+";"+person.getAge()+";"+person.getBirth();

        //写出去
        OutputStream body = httpOutputMessage.getBody();
        body.write(data.getBytes());
    }
}

@Bean
    public  WebMvcConfigurer webMvcConfigurer(){
    
    

        return  new WebMvcConfigurer() {
    
    

            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    
    
                    converters.add(new AyanMessageConverter());
            }
}
@Override
            public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    
    
                // Map<string, MediaType> mediaTypes
                Map<String, MediaType> mediaTypes = new HashMap<>();
                mediaTypes.put("json",MediaType.APPLICATION_JSON);
                mediaTypes.put("xml",MediaType.APPLICATION_XML);
                mediaTypes.put("aa",MediaType.parseMediaType("application/x-ayan"));
                //指定支持解析哪些参数对应的哪些媒体类型
                ParameterContentNegotiationStrategy parametercontentNegotiationstrategy = new ParameterContentNegotiationStrategy(mediaTypes);

                HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
                configurer.strategies(Arrays.asList(headerStrategy,parametercontentNegotiationstrategy));
            }

有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。
大家考虑,上述功能除了我们完全自定义外?SpringBoot有没有为我们提供基于配置文件的快速修改媒体类型功能?怎么配置呢?【提示:参照SpringBoot官方文档web开发内容协商章节】

猜你喜欢

转载自blog.csdn.net/weixin_51600120/article/details/114637214