可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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() }