Springfox (swagger2) doesn't work with GsonHttpMessageConverterConfig

I am trying to create a spring-boot application (v1.2.3) 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 to json, and I do it like this:

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

The problem is that when using GsonHttpMessageConverter , swagger v2 generates the 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: ... 

JSON has a value prefix, and real JSON becomes an escaped string.

this is how it should be if you don't use GsonHttpMessageConverter :

 { "swagger": "2.0", "info": { "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry 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 the right JAON Swagger without value and output?

+7
source share
5 answers

Solved the problem on my own:

the problem was 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 correctly, I applied SpringfoxJsonToGsonAdapter and added it to my gson configuration:

adapter:

 public class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> { @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(); } } 
+27
source

I switched to a similar problem, but found a slightly different solution that also uses the aforementioned serializer.

We define the Bean ability to auto-learn Gson objects. To fix the problem with Swagger, an important part is also adding a "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 is only listed here for completeness.

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

To use the Gson object, simply 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 ;-) } } 
+1
source

This is Oleg Maevsky's solution to the SpringFox + Gson problem translated into Kotlin:

 internal class SpringfoxJsonToGsonAdapter : JsonSerializer<Json> { 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() } 
+1
source

This is the same decision as Oleg Mayevsky . I just get rid of the SpringfoxJsonToGsonAdapter class using the lambda function instead:

 @Bean public GsonHttpMessageConverter gsonHttpMessageConverter() { GsonHttpMessageConverter converter = new GsonHttpMessageConverter(); converter.setGson(gson()); return converter; } private Gson gson() { final GsonBuilder builder = new GsonBuilder(); JsonSerializer<Json> jsonSerializer = (Json json, Type type, JsonSerializationContext context) -> new JsonParser().parse(json.value()); builder.registerTypeAdapter(Json.class, jsonSerializer); return builder.create(); } 
0
source

A couple of things that I found missing in the above instructions are package and import. When I first tried this, I used my own packages, but swagger-ui.html still said no packages were found. It seems that the package is specific.

The classes below are exactly the same as above, but I have included the whole class with package names and import. Registration of the adapter is the same as described above.

JSON class first

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

and adapter class:

 package springfox.documentation.spring.web.json; import java.lang.reflect.Type; import com.google.gson.*; public class SpringfoxJsonToGsonAdapter implements com.google.gson.JsonSerializer<Json> { @Override public JsonElement serialize(Json json, Type type, JsonSerializationContext context) { final JsonParser parser = new JsonParser(); return parser.parse(json.value()); } } 
-1
source

All Articles