解决@ResponseBody作用在返回类型为String的方法时的坑

 更新时间:2023年06月17日 15:46:16   作者:BryantLmm  
这篇文章主要介绍了解决@ResponseBody作用在返回类型为String的方法时的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@ResponseBody作用在返回类型为String的方法时的坑

在默认的Spring配置中,当在返回类型为String的Controller方法时,在其上加上@ResponseBody时会出现问题,那就是返回的不再是我们期待的Json格式的字符串了,而是会变成在正常的Json串前后加上双引号。

这是为什么呢?这是因为在HTTPMessageConverter中对应写json格式相应的处理类在写json的时候默认是对String类型进行这样处理的。

以Gson为例

在SpringBoot中,有相应的Configuartion来配置用户来解析Json格式的HttpMessageConverter,经过DEBUG发现,在HttpMessageConverter列表中第一个符合处理json返回格式的是GsonHttpMessageConverter,他是在GsonHttpMessageConvertersConfiguration类中被注入的。

他对json的处理是

    @Override
    protected void writeInternal(Object o, Type type, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
        Charset charset = getCharset(outputMessage.getHeaders());
        OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody(), charset);
        try {
            if (this.jsonPrefix != null) {
                writer.append(this.jsonPrefix);
            }
            if (type != null) {
                this.gson.toJson(o, type, writer);
            }
            else {
                this.gson.toJson(o, writer);
            }
            writer.close();
        }
        catch (JsonIOException ex) {
            throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
        }
    }

因为Gson默认对String类型的对象转化为json就是会加上双引号的,所以导致了String类型的返回不再是json串了。

如果想要String类型也转为正常的json格式的话,只要重写GsonHttpMessageConverter即可。

    @Override
    protected void writeInternal(Object o, Type type, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
        Charset charset = getCharset(outputMessage.getHeaders());
        OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody(), charset);
        try {
            if (this.jsonPrefix != null) {
                writer.append(this.jsonPrefix);
            }
            if (type != null) {
                //对于String类型的,直接拼接,不转json
            if("java.lang.String".equals(type.getTypeName())){
                writer.append(value.toString());
            }else{
                this.gson.toJson(o, type, writer);
                }
                }
            }
            else {
                this.gson.toJson(o, writer);
            }
            writer.close();
        }
        catch (JsonIOException ex) {
            throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
        }
    }

对于FastJson,在测试的时候发现,对于低版本的FastJson,会存在一个问题,就是当Java对象并没有默认的构造器的时候,是会报错的,需要使用新版本的FastJson才会去寻找合适的构造器去实例化对象。

至于哪个版本才可以称为新版本,没有仔细研究,我使用的1.2.47版本已经修复这个问题。

Fastjson还是有很多坑的,之前有研究过他之前的一个远程漏洞,这个后续会写一篇文章,个人并不建议使用Fastjson,推荐Gson。

对了,如果你使用的是fastjson提供的HTTPMessageConverter,是一样会对String格式做加引号处理的,具体可以看相应源码。

心得

所以为了@ResponseBody能良好的实现返回json格式的功能,要不我们就不要返回String对象,要么就需要重写相应将返回对象处理为Json的HTTPMessageConverter,特殊化他对String类型的处理。

response.body().string()的坑坑坑!!!

一不小心 浪费了2个小时 

response.body().string()

这个东西明明就看到过是string string为啥还是写成了toString()...

写成了response.body().toString()后打印出来的就是okhttp3.internal.http.RealResponseBody@815f248这样的数据!!!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • IDEA中osgi的开发应用指南详解

    IDEA中osgi的开发应用指南详解

    这篇文章主要介绍了IDEA中osgi的开发应用指南详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 实现分库分表功能

    Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 实现分库分表功能

    这篇文章主要介绍了Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 实现分库分表功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • IDEA如何对单个的java class文件打成jar包

    IDEA如何对单个的java class文件打成jar包

    这篇文章主要介绍了IDEA如何对单个的java class文件打成jar包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Spring源码完美导入IDEA的过程

    Spring源码完美导入IDEA的过程

    正值春节假期,小伙伴私信我idea导入spring源码的过程,今天抽空给大家整理一篇教程帮助大家学习Spring源码完美导入IDEA的详细过程,感兴趣的朋友一起看看吧
    2022-02-02
  • MybatisPlus BaseMapper 实现对数据库增删改查源码

    MybatisPlus BaseMapper 实现对数据库增删改查源码

    MybatisPlus 是一款在 Mybatis 基础上进行的增强 orm 框架,可以实现不写 sql 就完成数据库相关的操作,这篇文章主要介绍了MybatisPlus BaseMapper 实现对数据库增删改查源码解析,需要的朋友可以参考下
    2023-01-01
  • 微服务分布式架构实现日志链路跟踪的方法

    微服务分布式架构实现日志链路跟踪的方法

    在现有的系统中,由于大量的其他用户/其他线程的日志也一起输出穿行其中导致很难筛选出指定请求的全部相关日志。那我们如何来处理呢?带着这个问题一起通过本文学习下吧
    2021-08-08
  • Spring中的构造注入

    Spring中的构造注入

    这篇文章主要介绍了Spring中的构造注入,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java中弱引用和软引用的区别以及虚引用和强引用介绍

    Java中弱引用和软引用的区别以及虚引用和强引用介绍

    很早Java API就添加了弱引用(WeakReference)和软引用(SoftReference),但并不是所有的程序员都熟悉这两个概念
    2014-04-04
  • Spring计划任务用法实例详解

    Spring计划任务用法实例详解

    这篇文章主要介绍了Spring计划任务用法,结合实例形式详细分析了spring计划任务相关原理、配置、使用方法及操作注意事项,需要的朋友可以参考下
    2019-11-11
  • 使用Maven进行依赖排除的详细步骤

    使用Maven进行依赖排除的详细步骤

    在Maven中,依赖排除是一种常见的技术,用于从项目的依赖中排除特定的传递性依赖,这通常用于解决依赖冲突或避免引入不需要的库,以下是如何在Maven中使用依赖排除的详细步骤,包括代码示例,需要的朋友可以参考下
    2024-11-11

最新评论