我正在尝试构建的是一个spring-boot(v1.2.3)应用程序,并使用SpringFox(swagger2)v2.0.0公开我的Rest API
我的Swagger Spring配置
@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");
}
}
我需要使用gson将我的pojo转换为json,我这样做:
@Configuration
public class GsonHttpMessageConverterConfig {
@Bean
public GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
converter.setGson(gson);
return converter;
}
}
麻烦的是,如果使用GsonHttpMessageConverter
,swagger v2会生成错误的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以value为前缀,真正的JSON成为转义字符串。
如果不使用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
...
是否有解决方案来创建没有值和转义的正确的swagger JSON?
答案 0 :(得分:27)
自己解决了这个问题:
问题在于序列化这个类:
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;
}
}
将序列化正确我实现了一个SpringfoxJsonToGsonAdapter并将其添加到我的gson配置中:
适配器:
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();
}
}
答案 1 :(得分:1)
遇到类似的问题,但发现了一个稍微不同的解决方案,也使用上面提到的序列化器。
我们定义一个Bean,以便能够自动装配Gson对象。为了解决Swagger的问题,重要的部分是添加&#34; registerTypeAdapter&#34;为Json班。
@Configuration
public class GsonConfiguration {
@Bean
public Gson gson() {
return new GsonBuilder().registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter()).create();
}
}
SpringfoxJsonToGsonAdapter的内容与上面相同,仅为了完整性而在此处列出。
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对象只需执行以下操作:
@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 ;-)
}
}
答案 2 :(得分:1)
这是Oleg Majewski将SpringFox + Gson问题转化为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()
}
答案 3 :(得分:0)
这与Oleg Majowski's相同。我只是使用lambda函数代替了SpringfoxJsonToGsonAdapter
类:
@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();
}
答案 4 :(得分:-1)
我发现上述说明中遗漏的一些内容是包和导入。当我第一次尝试这个时,我使用了自己的包,但swagger-ui.html仍然说没有找到包。包装似乎是特定的。
下面的类与上面的完全相同,但我在整个类中包含了包名和导入。注册适配器与上面记录的相同。
首先是JSON类
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;
}
}
和适配器类:
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());
}
}