springfox(swagger2) does not work with GsonHttpMessageConverterConfig

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

What I am trying to build is a spring-boot (v1.2.3) application and expose my Rest API with SpringFox(swagger2) v2.0.0

my Swagger Spring config

@EnableSwagger2 @Configuration public class SwaggerConfig {      @Bean     public Docket myApi() {         return new Docket(DocumentationType.SWAGGER_2)             .genericModelSubstitutes(DeferredResult.class)             .useDefaultResponseMessages(false)             .forCodeGeneration(false)             .pathMapping("/my-prj");     }  } 

I need to use gson to convert my pojo's to json, and I do it this way:

@Configuration public class GsonHttpMessageConverterConfig {      @Bean     public GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {         GsonHttpMessageConverter converter = new GsonHttpMessageConverter();         converter.setGson(gson);         return converter;     } } 

The trouble is that if using GsonHttpMessageConverter, swagger v2 generates a wrong json:

{ "value": "{\"swagger\":\"2.0\",\"info\":{\"description\":\"Api Documentation\",\"version\":\"1.0\",\"title\":\"Api Documentation\",\"termsOfService\":\"urn:tos\",\"contact\":{\"name\":\"Contact Email\"},\"license\":{\"name\":\"Apache 2.0\",\"url\":\"http: ... 

the JSON is prefixed with value and the real JSON becomes an escaped string.

here is how it should be if not using GsonHttpMessageConverter:

{ "swagger": "2.0", "info": { "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a  ... 

Is there a solution to create a correct swagger JSON without value and escaping?

回答1:

solved the issue by myself:

the issue was with serializing this class:

package springfox.documentation.spring.web.json;  import com.fasterxml.jackson.annotation.JsonRawValue; import com.fasterxml.jackson.annotation.JsonValue;  public class Json {   private final String value;    public Json(String value) {     this.value = value;   }    @JsonValue   @JsonRawValue   public String value() {     return value;   } } 

to serialize it correct I implemented a SpringfoxJsonToGsonAdapter and added it to my gson config:

adapter:

public class SpringfoxJsonToGsonAdapter implements JsonSerializer {      @Override     public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {         final JsonParser parser = new JsonParser();         return parser.parse(json.value());     } }  

gson config:

@Configuration public class GsonHttpMessageConverterConfig {      @Bean     public GsonHttpMessageConverter gsonHttpMessageConverter() {         GsonHttpMessageConverter converter = new GsonHttpMessageConverter();         converter.setGson(gson());         return converter;     }      private Gson gson() {         final GsonBuilder builder = new GsonBuilder();         builder.registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter());         return builder.create();     } } 


回答2:

Ran into a similar problem but found a little different solution which is also using the above mentioned serializer.

We define a Bean to be able to autowire Gson objects. For fixing the issue with Swagger the important part there is to also add "registerTypeAdapter" for the Json class.

@Configuration public class GsonConfiguration {    @Bean    public Gson gson() {       return new GsonBuilder().registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter()).create();    } } 

The content of SpringfoxJsonToGsonAdapter is the same as above and only listed here for completeness.

public class SpringfoxJsonToGsonAdapter implements JsonSerializer {     @Override     public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {         final JsonParser parser = new JsonParser();         return parser.parse(json.value());     } } 

For using the Gson object just do something like this:

@Component public class Foobar {    @Autowired    Gson gson;     @Autowired    public Foobar() {       // ... some constructor work ...    }     public void someMethod() {       System.out.println(gson.toJson(...)); // Fill in some object ;-)    } } 


回答3:

This is Oleg Majewski's solution for SpringFox + Gson problem translated to Kotlin:

internal class SpringfoxJsonToGsonAdapter : JsonSerializer {      override fun serialize(json: Json, type: Type, context: JsonSerializationContext): JsonElement             = JsonParser().parse(json.value())  }  @Configuration open class GsonHttpMessageConverterConfig {      @Bean     open fun gsonHttpMessageConverter(): GsonHttpMessageConverter {         val converter = GsonHttpMessageConverter()         converter.gson = gson()         return converter     }      private fun gson(): Gson = GsonBuilder()             .registerTypeAdapter(Json::class.java, SpringfoxJsonToGsonAdapter())             .create()  } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!