千家信息网

Spring Boot数据响应问题实例分析

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,本文小编为大家详细介绍"Spring Boot数据响应问题实例分析",内容详细,步骤清晰,细节处理妥当,希望这篇"Spring Boot数据响应问题实例分析"文章能帮助大家解决疑惑,下面跟着小编的思路
千家信息网最后更新 2026年11月04日Spring Boot数据响应问题实例分析

本文小编为大家详细介绍"Spring Boot数据响应问题实例分析",内容详细,步骤清晰,细节处理妥当,希望这篇"Spring Boot数据响应问题实例分析"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    前言

    响应页面指的是我们如何发送一个请求,跳转到指定页面。将会在后面的视图解析中说明。 响应页面常见于开发单体应用。 响应数据常见于开发前后端分离的应用。后端代码主要用来接收请求。前端页面给我们发送过来请求,给前端响应json数据。或者给前端响应xml、图片、音视频数据。

    在前后端分离开发过程中,后端一般会将数据集封装成一个JSON对象响应给前端 ,一般只需要标准ResponseBody即可给前端返回数据

    1、响应Json数据:Jackson.jar+@ResponseBody

    假设给前端自动返回json数据,需要引入相关的依赖

        org.springframework.boot    spring-boot-starter-web    org.springframework.boot    spring-boot-starter-json    2.3.4.RELEASE    compile

    控制层代码如下:引入了依赖后,给方法上标注@ResponseBody,就可以给前端自动返回JSON数据。

    @Controllerpublic class ResponseTestController {    @ResponseBody //原理就是利用返回值处理器里面消息转换器进行处理    @GetMapping("/test/person")    public Person getPerson(){        Person person = new Person();        person.setAge(28);        person.setBirth(new Date());        person.setUserName("zhangsan");        return person;    }}

    测试:

    2、原理解析

    • 返回值处理器判断是否支持这种类型返回值supportsReturnType

    • 返回值处理器调用handleReturnValue进行处理

    • RequestResponseBodyMethodProcessor可以处理返回值标了@ResponseBody注解的。

      • 内容协商(浏览器默认会以请求头的方式告诉服务器他能接受什么样的内容类型)

      • 服务器最终根据自己自身的能力,决定服务器能生产出什么样内容类型的数据,

      • SpringMVC会挨个遍历所有容器底层的HttpMessageConverter,看谁能处理?(也就是把对象转换成为json数据)

      • 得到MappingJackson2HttpMessageConverter消息转换器可以将对象写为json

      • 利用MappingJackson2HttpMessageConverter将对象转为json再写出去。

      • 利用MessageConverters进行处理将数据写为json

    SpringMVC到底支持哪些返回值

    • ModelAndView //包含数据和页面

    • Model

    • View

    • ResponseEntity

    • ResponseBodyEmitter

    • StreamingResponseBody

    • HttpEntity

    • HttpHeaders

    • Callable //异步

    • DeferredResult

    • ListenableFuture

    • CompletionStage

    • WebAsyncTask

    • 有 @ModelAttribute 且为对象类型的

    • @ResponseBody 注解 ---> RequestResponseBodyMethodProcessor;处理器//即在方法上或者类上是否标注@ResponseBody

    HTTPMessageConverter原理

    MessageConverter规范

    HttpMessageConverter:看是否支持将 此 Class类型的对象,转为MediaType类型的数据。 例子:CanWrite将Person对象转为JSON。canRead或者 JSON转为Person

    默认的MessageConverter

    • 0 - 只支持Byte类型的

    • 1 - String

    • 2 - String

    • 3 - Resource

    • 4 - ResourceRegion

    • 5 - DOMSource.class \ SAXSource.class) \ StAXSource.class \StreamSource.class \Source.class

    • 6 - MultiValueMap

    • 7 - true //支持将任意对象转为指定的,不管是什么都支持

    • 8 - true

    • 9 - 支持注解方式xml处理的。

    最终 MappingJackson2HttpMessageConverter 把对象转为JSON(利用底层的jackson的objectMapper转换的)

    3、内容协商

    3.1、概述

    根据客户端接收能力不同【有的只接收xml,有的只接收json】,返回不同媒体类型的数据。比如返回xml数据给前

    引入支持XML依赖:

        com.fasterxml.jackson.dataformat    jackson-dataformat-xml

    重新编译该项目运行 ,返回了xml数据

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

    在上面的测试中,此时如果我用postman发送相同的请求,则得到的是json数据,为啥同样的请求,方式不一样,返回的数据不一样呢。原因就是请求头中规定的数据响应先后顺序

    查看请求头

    内容协商Accept中,浏览器具备什么类型数据的接收能力,可以看到xml数据是优先被接收的。

    可用Postman软件分别测试返回json和xml:只需要改变请求头中Accept字段(application/json、application/xml)。Http协议中规定的,告诉服务器本客户端可以接收的数据类型。

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

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

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

    发请求:

    • json类型: http://localhost:8080/test/person?format=json

    • xml类型:http://localhost:8080/test/person?format=xml

    确定客户端接收什么样的内容类型;

    1、Parameter策略优先确定是要返回json数据(获取请求头中的format的值) 2、最终进行内容协商返回给客户端json即可。

    4、内容协商原理

    • 判断当前响应头中是否已经有确定的媒体类型。MediaType

    • 获取客户端(PostMan、浏览器)支持接收的内容类型。(获取客户端Accept请求头字段)【application/xml】

    • contentNegotiationManager 内容协商管理器 默认使用基于请求头的策略

    • HeaderContentNegotiationStrategy 确定客户端可以接收的内容类型

    • 遍历循环所有当前系统的 MessageConverter,看谁支持操作这个对象(Person)

    • 找到支持操作Person的converter,把converter支持的媒体类型统计出来。

    • 客户端需要【application/xml】。服务端能力【10种、json、xml】

    • 进行内容协商的最佳匹配媒体类型

    • 用 支持 将对象转为 最佳匹配媒体类型 的converter。调用它进行转化 。

    导入了jackson处理xml的包,xml的converter就会自动进来

    WebMvcConfigurationSupportjackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);if (jackson2XmlPresent) {                    Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();                    if (this.applicationContext != null) {                            builder.applicationContext(this.applicationContext);                    }                    messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));            }

    5、自定义消息转换器MessageConverter

    5.1、概述

    实现多协议数据兼容。json、xml、x-guigu

    • @ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理

    • Processor 处理方法返回值。通过 MessageConverter 处理

    • 所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)

    • 内容协商找到最终的 messageConverter;

    要自定义SpringMVC的什么功能,即通过一个入口给容器中添加一个 WebMvcConfigurer

    假设你想基于自定义请求参数的自定义内容协商功能。换句话,在地址栏输入http://localhost:8080/test/person?format=gg返回数据,跟http://localhost:8080/test/person且请求头参数`Accept:application/x-guigu`的返回自定义协议数据的一致。

    演示

    通过上文分析,我们只需要实现WebMvcConfigurer接口,并实现了configureMessageConverters方法,就可以达到自定义消息转换器的目的。例如,我不想用jackson了,想用fastjson的消息转换器,我们可以添加fastjson相关的MessageConverter就可以了

    @Configurationpublic class WebConfig implements WebMvcConfigurer {    @Override    public void configureMessageConverters(List> converters) {        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();        List fastMediaTypes = new ArrayList<>();        fastMediaTypes.add(MediaType.TEXT_HTML);        fastMediaTypes.add(MediaType.APPLICATION_JSON);        fastConverter.setSupportedMediaTypes(fastMediaTypes);        FastJsonConfig fastJsonConfig = new FastJsonConfig();        fastJsonConfig.setSerializerFeatures(            SerializerFeature.WriteMapNullValue,            SerializerFeature.WriteNullStringAsEmpty,            SerializerFeature.WriteNullListAsEmpty,            SerializerFeature.WriteDateUseDateFormat);        SerializeConfig serializeConfig = SerializeConfig.globalInstance;        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);        serializeConfig.put(Long.class, ToStringSerializer.instance);        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);        fastJsonConfig.setSerializeConfig(serializeConfig);        fastConverter.setFastJsonConfig(fastJsonConfig);        converters.add(fastConverter);    }}

    测试

    @Datapublic class Person {    private String userName;    private Integer age;    //使用fastjson的注解进行转换    @JSONField(format = "yyyy-MM-dd")    private Date birth;    private Pet pet;}

    5.2、自定义的Converter

    除此之外,这些都是默认的,我们可以进行扩展,如下实现自定义的设置转化,如下,利用这个代码:

    @Beanpublic WebMvcConfigurer webMvcConfigurer(){    return new WebMvcConfigurer() {        @Override        public void extendMessageConverters(List> converters) {        }    }}

    测试

    @Configuration(proxyBeanMethods = false)public class WebConfig {    @Bean    public WebMvcConfigurer webMvcConfigurer(){        return new WebMvcConfigurer() {            @Override            public void extendMessageConverters(List> converters) {                converters.add(new GuiguMessageConverter());            }        }    }}
    /** * 自定义的Converter */public class GuiguMessageConverter implements HttpMessageConverter {    @Override    public boolean canRead(Class clazz, MediaType mediaType) {        return false;    }    @Override    public boolean canWrite(Class clazz, MediaType mediaType) {        return clazz.isAssignableFrom(Person.class);    }    /**     * 服务器要统计所有MessageConverter都能写出哪些内容类型     *     * application/x-guigu     * @return     */    @Override    public List getSupportedMediaTypes() {        return MediaType.parseMediaTypes("application/x-guigu");    }    @Override    public Person read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {        return null;    }    @Override    public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {        //自定义协议数据的写出        String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth();        //写出去        OutputStream body = outputMessage.getBody();        body.write(data.getBytes());    }}

    测试:

    import java.util.Date;@Controllerpublic class ResponseTestController {    /**     * 1、浏览器发请求直接返回 xml    [application/xml]        jacksonXmlConverter     * 2、如果是ajax请求 返回 json   [application/json]      jacksonJsonConverter     * 3、如果硅谷app发请求,返回自定义协议数据  [appliaction/x-guigu]   xxxxConverter     *          属性值1;属性值2;     *     * 步骤:     * 1、添加自定义的MessageConverter进系统底层     * 2、系统底层就会统计出所有MessageConverter能操作哪些类型     * 3、客户端内容协商 [guigu--->guigu]     *     * 作业:如何以参数的方式进行内容协商     * @return     */    @ResponseBody  //利用返回值处理器里面的消息转换器进行处理    @GetMapping(value = "/test/person")    public Person getPerson(){        Person person = new Person();        person.setAge(28);        person.setBirth(new Date());        person.setUserName("zhangsan");        return person;    }}

    日后开发要注意,有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。

    读到这里,这篇"Spring Boot数据响应问题实例分析"文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注行业资讯频道。

    数据 内容 类型 处理 协商 支持 对象 客户 客户端 前端 功能 测试 参数 媒体 消息 转换器 服务 处理器 方式 服务器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网络科技 南京欣网互联网络科技有限公司 蓝思科技飞鸽互联网 苏州找大状互联网科技有限公司 极限挑战互联网科技 有木互联网科技 互联网科技的未来发展 深圳期待互联网科技 撒么互联网科技公司 太原新华互联网科技学校怎么样 蓝色互联网科技 昭通云南众福互联网科技有限公司 宁夏科技产业互联网案例 苏州铭阳互联网科技有限公司 互联网公司黑科技创始人 恒生互联网科技业指数调整周期 国大互联网教育科技有限公司薪资 互联网领先科技宣传片 东营紫格互联网科技 前海云享互联网科技 广东猪兼强互联网科技有限公司 互联网科技巨头监管 紫鲸互联网科技 碳银互联网科技有限公司 互联网 科技服务平台 科技伦理 互联网公司 博兴的互联网电子科技公司 互联网和黑科技的看法 世界互联网科技公司市值排名 山东有哪些互联网科技公司
    0