springboot 接口返回字符串带引号的问题解决

 更新时间:2022年04月15日 09:54:45   作者:Always_July  
本文主要介绍了springboot 接口返回字符串带引号的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

框架版本

springboot 2.2.1.RELEASE
fastjson 1.2.78

maven pom.xml parent 和 dependencies

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
    </dependencies>

问题

如下代码,返回结果是 "hello world",添加了一个双引号。

@RestController
@Slf4j
public class Hello1Controller {

    @GetMapping(value = "/printHello")
    @ResponseBody
    public String printHello() {
        return "hello world";
    }
}

排查

不管返回什么的结果,肯定经过MessageConvert进行消息的输出,debug看使用了哪一个MessageConvert

选择MessageConvert的方法是
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters(T, org.springframework.core.MethodParameter, org.springframework.http.server.ServletServerHttpRequest, org.springframework.http.server.ServletServerHttpResponse)

关键代码

        if (selectedMediaType != null) {
            selectedMediaType = selectedMediaType.removeQualityValue();
             // 打个断点在此处
            for (HttpMessageConverter<?> converter : this.messageConverters) {
                GenericHttpMessageConverter genericConverter = (converter instanceof GenericHttpMessageConverter ?
                        (GenericHttpMessageConverter<?>) converter : null);
                if (genericConverter != null ?
                        ((GenericHttpMessageConverter) converter).canWrite(targetType, valueType, selectedMediaType) :
                        converter.canWrite(valueType, selectedMediaType)) {
                    body = getAdvice().beforeBodyWrite(body, returnType, selectedMediaType,
                            (Class<? extends HttpMessageConverter<?>>) converter.getClass(),
                            inputMessage, outputMessage);
                    if (body != null) {
                        Object theBody = body;
                        LogFormatUtils.traceDebug(logger, traceOn ->
                                "Writing [" + LogFormatUtils.formatValue(theBody, !traceOn) + "]");
                        addContentDispositionHeader(inputMessage, outputMessage);
                        if (genericConverter != null) {
                            genericConverter.write(body, targetType, selectedMediaType, outputMessage);
                        }
                        else {
                            ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage);
                        }
                    }
                    else {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Nothing to write: null body");
                        }
                    }
                    return;
                }
            }
        }

debug发现我的messageConvert只有一个,是com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter。那肯定是经过FastJson将String 写到输出流。

debug查看FastJsonHttpMessageConverter具体的write 代码 ,可以看到此时输出字符串添加了引号。

方法:com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter#writeInternal

写个fastjson 转化字符串试试,如下结果输出是 "hello world",添加了引号。

import com.alibaba.fastjson.JSON;

public class JsonTest {
    public static void main(String[] args) {
        System.out.println(JSON.toJSONString("hello world"));
        // 
    }
}

问题所在

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer  {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setCharset(StandardCharsets.UTF_8);
        //设置允许返回为null的属性
        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
       
        fastJsonConverter.setFastJsonConfig(config);
        List<MediaType> list = new ArrayList<>();
        list.add(MediaType.APPLICATION_JSON);
        fastJsonConverter.setSupportedMediaTypes(list);
        converters.add(fastJsonConverter);
    }

}

我配置了FastJsonHttpMessageConverter ,导致只使用FastJsonHttpMessageConverter 进行消息转换。

解决方法

添加StringHttpMessageConverter ,让其转化String。注意顺序,StringHttpMessageConverter 要在FastJsonHttpMessageConverter 之前。

 @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setCharset(StandardCharsets.UTF_8);
        //设置允许返回为null的属性
        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue);

        fastJsonConverter.setFastJsonConfig(config);
        List<MediaType> list = new ArrayList<>();
        list.add(MediaType.APPLICATION_JSON);
        fastJsonConverter.setSupportedMediaTypes(list);

        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        stringHttpMessageConverter.setSupportedMediaTypes(list);
        converters.add(stringHttpMessageConverter);

        converters.add(fastJsonConverter);
    }

返回数据没有引号了。

参考资料

【Spring】HttpMessageConverter的作用及替换

到此这篇关于springboot 接口返回字符串带引号的问题解决的文章就介绍到这了,更多相关springboot 返回字符串带引号内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中序列化与反序列化的特性解读

    Java中序列化与反序列化的特性解读

    这篇文章主要介绍了Java中序列化与反序列化的特性解读,当我们需要将内存中的对象持久化到磁盘,数据库中时, 当我们需要与浏览器进行交互时,当我们需要实现 RPC 时, 这个时候就需要序列化和反序列化了,需要的朋友可以参考下
    2023-08-08
  • Java处理多API请求的方法详解

    Java处理多API请求的方法详解

    Java 中的并发是指语言并行运行多个线程的能力,允许同时执行多个任务,
    2023-10-10
  • 分享java中设置代理的两种方式

    分享java中设置代理的两种方式

    有时候我们的程序中要提供可以使用代理访问网络,代理的方式包括http、https、ftp、socks代理。比如在IE浏览器设置代理,这里简单介绍下,需要的朋友可以参考下
    2015-12-12
  • Spring Security OAuth2 授权码模式的实现

    Spring Security OAuth2 授权码模式的实现

    这篇文章主要介绍了Spring Security OAuth2 授权码模式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • java判断中文字符串长度的简单实例

    java判断中文字符串长度的简单实例

    下面小编就为大家带来一篇java判断中文字符串长度的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • idea中无法自动装配未找到 ‘XXXXXXX‘ 类型的 Bean

    idea中无法自动装配未找到 ‘XXXXXXX‘ 类型的 Bean

    本文主要介绍了idea中无法自动装配未找到 ‘XXXXXXX‘ 类型的 Bean的原因及三种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Spring中@RequestParam、@RequestBody和@PathVariable的用法详解

    Spring中@RequestParam、@RequestBody和@PathVariable的用法详解

    这篇文章主要介绍了Spring中@RequestParam、@RequestBody和@PathVariable的用法详解,后端使用集合来接受参数,灵活性较好,如果url中没有对参数赋key值,后端在接收时,会根据参数值的类型附,赋一个初始key,需要的朋友可以参考下
    2024-01-01
  • 深入了解Java中Synchronized的各种使用方法

    深入了解Java中Synchronized的各种使用方法

    在Java当中synchronized关键字通常是用来标记一个方法或者代码块。本文将通过示例为大家详细介绍一下Synchronized的各种使用方法,需要的可以参考一下
    2022-08-08
  • Springboot整合mybatis-plus使用pageHelper进行分页(使用步骤)

    Springboot整合mybatis-plus使用pageHelper进行分页(使用步骤)

    PageHelper是一个MyBatis分页插件,可以方便地实现数据库查询结果的分页功能,在Maven或Gradle项目中引入依赖,并在配置文件中进行配置,本文给大家介绍Springboot整合mybatis-plus使用pageHelper进行分页,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • Java并发编程示例(八):处理线程的非受检异常

    Java并发编程示例(八):处理线程的非受检异常

    这篇文章主要介绍了Java并发编程示例(八):处理线程的非受检异常,Java为我们提供了一种机制,专门用于处理由Thread对象抛出的非受检异常,以避免程序的退出,需要的朋友可以参考下
    2014-12-12

最新评论