From 7038d3437915e4863ea108d47328646c9a474932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=9A=E4=BD=99=E5=B8=83=E9=81=93=E5=B8=88?= Date: Sat, 4 Jun 2022 21:16:54 +0800 Subject: [PATCH] fix spring-doc issue #387. --- .../FastJsonHttpMessageConverter.java | 13 ++- .../support/springdoc/OpenApiJsonWriter.java | 28 ------ .../springdoc/OpenApiJsonWriterTest.java | 85 +++++++++++++++---- 3 files changed, 80 insertions(+), 46 deletions(-) delete mode 100644 extension/src/main/java/com/alibaba/fastjson2/support/springdoc/OpenApiJsonWriter.java diff --git a/extension/src/main/java/com/alibaba/fastjson2/support/spring/http/converter/FastJsonHttpMessageConverter.java b/extension/src/main/java/com/alibaba/fastjson2/support/spring/http/converter/FastJsonHttpMessageConverter.java index a6b2827601..92d82ed6bd 100644 --- a/extension/src/main/java/com/alibaba/fastjson2/support/spring/http/converter/FastJsonHttpMessageConverter.java +++ b/extension/src/main/java/com/alibaba/fastjson2/support/spring/http/converter/FastJsonHttpMessageConverter.java @@ -117,11 +117,18 @@ private Object readType(Type type, HttpInputMessage inputMessage) { protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { HttpHeaders headers = outputMessage.getHeaders(); - - int len = JSON.writeTo(baos, object, config.getDateFormat(), config.getWriterFilters(), config.getWriterFeatures()); + int contentLength; + + if (object instanceof String && JSON.isValidObject((String) object)) { + byte[] strBytes = ((String) object).getBytes(config.getCharset()); + contentLength = strBytes.length; + baos.write(strBytes, 0, strBytes.length); + } else { + contentLength = JSON.writeTo(baos, object, config.getDateFormat(), config.getWriterFilters(), config.getWriterFeatures()); + } if (headers.getContentLength() < 0 && config.isWriteContentLength()) { - headers.setContentLength(len); + headers.setContentLength(contentLength); } baos.writeTo(outputMessage.getBody()); diff --git a/extension/src/main/java/com/alibaba/fastjson2/support/springdoc/OpenApiJsonWriter.java b/extension/src/main/java/com/alibaba/fastjson2/support/springdoc/OpenApiJsonWriter.java deleted file mode 100644 index f37f83625b..0000000000 --- a/extension/src/main/java/com/alibaba/fastjson2/support/springdoc/OpenApiJsonWriter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.alibaba.fastjson2.support.springdoc; - -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONWriter; -import com.alibaba.fastjson2.writer.ObjectWriter; - -import java.lang.reflect.Type; - -/** - * OpenApiJsonWriter: SpringDoc的Json处理,解决json对象转成了json字符串,导致接口文档无法显示 - * - * @author Victor.Zxy - * @since 2.0.6 - */ -public class OpenApiJsonWriter - implements ObjectWriter { - public static final OpenApiJsonWriter INSTANCE = new OpenApiJsonWriter(); - - @Override - public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) { - if (object == null) { - jsonWriter.writeNull(); - } else { - String value = object.toString(); - jsonWriter.writeAny(JSON.parse(value)); - } - } -} diff --git a/extension/src/test/java/com/alibaba/fastjson2/springdoc/OpenApiJsonWriterTest.java b/extension/src/test/java/com/alibaba/fastjson2/springdoc/OpenApiJsonWriterTest.java index 74e99c9669..12404f5121 100644 --- a/extension/src/test/java/com/alibaba/fastjson2/springdoc/OpenApiJsonWriterTest.java +++ b/extension/src/test/java/com/alibaba/fastjson2/springdoc/OpenApiJsonWriterTest.java @@ -1,27 +1,82 @@ package com.alibaba.fastjson2.springdoc; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONFactory; -import com.alibaba.fastjson2.JSONWriter; -import com.alibaba.fastjson2.support.springdoc.OpenApiJsonWriter; +import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.List; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ExtendWith(SpringExtension.class) +@WebAppConfiguration +@ContextConfiguration public class OpenApiJsonWriterTest { - String jsonStr = "{\"openapi\":\"3.0.1\",\"info\":{\"title\":\"OpenAPI definition\",\"version\":\"v0\"},\"servers\":[{\"url\":\"http://localhost:8099\",\"description\":\"Generated server url\"}],\"paths\":{},\"components\":{}}"; + @Autowired + private WebApplicationContext wac; - @Test - public void test() { - OpenApiJsonWriter writer = OpenApiJsonWriter.INSTANCE; - writer.write(JSONWriter.of(), null); - writer.write(JSONWriter.of(), jsonStr); + private MockMvc mockMvc; + + private static String openapi = "{\"openapi\":\"3.0.1\",\"info\":{\"title\":\"OpenAPI definition\",\"version\":\"v0\"},\"servers\":[{\"url\":\"http://localhost:8099\",\"description\":\"Generated server url\"}],\"paths\":{},\"components\":{}}"; + + @BeforeEach + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac) // + .addFilter(new CharacterEncodingFilter("UTF-8", true)) // 设置服务器端返回的字符集为:UTF-8 + .build(); } @Test - public void test1() { - JSONFactory.getDefaultObjectWriterProvider().register(String.class, OpenApiJsonWriter.INSTANCE); - assertEquals(jsonStr, JSON.toJSONString(jsonStr)); - JSONFactory.getDefaultObjectWriterProvider().unregister(String.class, OpenApiJsonWriter.INSTANCE); + public void test() throws Exception { + mockMvc.perform( + (post("/test").characterEncoding("UTF-8") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(openapi) + )).andExpect(status().isOk()).andDo(print()); + } + + @RestController + @RequestMapping + public static class TestController { + @PostMapping(path = "/test", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public String test(@RequestBody String openapi) { + return openapi; + } + } + + @ComponentScan(basePackages = "com.alibaba.fastjson2.springdoc") + @Configuration + @Order(Ordered.LOWEST_PRECEDENCE + 1) + @EnableWebMvc + public static class WebMvcConfig + implements WebMvcConfigurer { + @Override + public void configureMessageConverters(List> converters) { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + converters.add(converter); + } } }