springboot 接口返回字符串帶引號(hào)的問題解決
框架版本
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>
問題
如下代碼,返回結(jié)果是 "hello world",添加了一個(gè)雙引號(hào)。
@RestController @Slf4j public class Hello1Controller { @GetMapping(value = "/printHello") @ResponseBody public String printHello() { return "hello world"; } }
排查
不管返回什么的結(jié)果,肯定經(jīng)過MessageConvert進(jìn)行消息的輸出,debug看使用了哪一個(gè)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)
關(guān)鍵代碼
if (selectedMediaType != null) { selectedMediaType = selectedMediaType.removeQualityValue(); // 打個(gè)斷點(diǎn)在此處 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發(fā)現(xiàn)我的messageConvert只有一個(gè),是com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter。那肯定是經(jīng)過FastJson將String 寫到輸出流。
debug查看FastJsonHttpMessageConverter具體的write 代碼 ,可以看到此時(shí)輸出字符串添加了引號(hào)。
方法:com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter#writeInternal
寫個(gè)fastjson 轉(zhuǎn)化字符串試試,如下結(jié)果輸出是 "hello world",添加了引號(hào)。
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); //設(shè)置允許返回為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 ,導(dǎo)致只使用FastJsonHttpMessageConverter 進(jìn)行消息轉(zhuǎn)換。
解決方法
添加StringHttpMessageConverter ,讓其轉(zhuǎn)化String。注意順序,StringHttpMessageConverter 要在FastJsonHttpMessageConverter 之前。
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter(); FastJsonConfig config = new FastJsonConfig(); config.setCharset(StandardCharsets.UTF_8); //設(shè)置允許返回為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); }
返回?cái)?shù)據(jù)沒有引號(hào)了。
參考資料
【Spring】HttpMessageConverter的作用及替換
到此這篇關(guān)于springboot 接口返回字符串帶引號(hào)的問題解決的文章就介紹到這了,更多相關(guān)springboot 返回字符串帶引號(hào)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用agent實(shí)現(xiàn)main方法之前的實(shí)例詳解
這篇文章主要介紹了Java使用agent實(shí)現(xiàn)main方法之前的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下2017-10-10Java實(shí)現(xiàn)經(jīng)典游戲泡泡堂的示例代碼
這篇文章將利用Java制作經(jīng)典游戲——泡泡堂,游戲設(shè)計(jì)為雙人pk積分賽模式,在這個(gè)模式里面,玩家只要率先達(dá)到一定分?jǐn)?shù)既可以贏得比賽。感興趣的可以了解一下2022-04-04Spring源碼解析之循環(huán)依賴的實(shí)現(xiàn)流程
這篇文章主要介紹了Spring源碼解析之循環(huán)依賴的實(shí)現(xiàn)流程,文章基于Java的相關(guān)內(nèi)容展開循環(huán)依賴的實(shí)現(xiàn)流程,需要的小伙伴可以參考一下2022-07-07Java中ArrayList在foreach里remove的問題詳析
這篇文章主要給大家介紹了關(guān)于Java中ArrayList在foreach里remove問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧2018-09-09Java實(shí)現(xiàn)的簡單數(shù)字處理類及用法示例
這篇文章主要介紹了Java實(shí)現(xiàn)的簡單數(shù)字處理類及用法,涉及java數(shù)字運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2018-01-01