无法在 Spring 引导中注册 Gson TypeAdapter
Can't register Gson TypeAdapter in Spring Boot
我一直在尝试在 RestComponent 中添加我的版本 class 的自定义序列化:
public class Version {
public int MAJOR;
public int MINOR;
public int REVISION;
public Integer BUILD;
}
Json 我期望的输出:
"1.2.2"
没有
{
"MAJOR": 1,
"MINOR": 2,
"REVISION": 2,
"BUILD": null
}
所以我决定使用JsonSerializer和JsonDeserializer接口,也尝试了TypeAdapter。
我在我的 MVC 配置 class 中创建了一个 Gson Bean,还尝试创建 GsonBuilder bean。在应用程序属性中,我选择 gson 作为序列化程序,并删除了 Jackson 依赖项。
@Bean
public Gson gson() {
var strategy = new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(GsonExclude.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
};
return new GsonBuilder()
.registerTypeHierarchyAdapter(Version.class, new VersionGsonAdapter())
.addSerializationExclusionStrategy(strategy)
.addDeserializationExclusionStrategy(strategy)
.disableHtmlEscaping()
.serializeNulls()
.setPrettyPrinting()
.create();
}
排除策略和漂亮打印等所有其他设置工作正常,但键入适配器 - 不行。
我还尝试配置消息转换器(configureMessageConverters、extendMessageConverters):
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.removeIf(c -> c instanceof GsonHttpMessageConverter);
converters.add(new GsonHttpMessageConverter(gson()));
}
}
As explained in the reference documentation,您可以使用 GsonBuilderCustomizer
自定义 Gson 基础结构,如下所示:
@Configuration
public class GsonConfiguration {
@Bean
public GsonBuilderCustomizer typeAdapterRegistration() {
return builder -> {
builder.registerTypeAdapter(Version.class, new VersionTypeAdapter());
};
}
}
请确保您已将 Gson 设置为您的首选 JSON 库,因为 Jackson 经常被许多依赖项传递。在application.properties
中,您可以添加以下内容:
spring.mvc.converters.preferred-json-mapper=gson
我已经使用以下控制器成功测试了这种方法:
@RestController
public class GsonController {
@GetMapping("/version")
public Version showVersion() {
return Version.fromVersionString("1.2.3-42");
}
}
控制器returns:
➜ ~ http :8080/version
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Keep-Alive: timeout=60
Transfer-Encoding: chunked
"1.2.3-42"
我一直在尝试在 RestComponent 中添加我的版本 class 的自定义序列化:
public class Version {
public int MAJOR;
public int MINOR;
public int REVISION;
public Integer BUILD;
}
Json 我期望的输出:
"1.2.2"
没有
{
"MAJOR": 1,
"MINOR": 2,
"REVISION": 2,
"BUILD": null
}
所以我决定使用JsonSerializer和JsonDeserializer接口,也尝试了TypeAdapter。 我在我的 MVC 配置 class 中创建了一个 Gson Bean,还尝试创建 GsonBuilder bean。在应用程序属性中,我选择 gson 作为序列化程序,并删除了 Jackson 依赖项。
@Bean
public Gson gson() {
var strategy = new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(GsonExclude.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
};
return new GsonBuilder()
.registerTypeHierarchyAdapter(Version.class, new VersionGsonAdapter())
.addSerializationExclusionStrategy(strategy)
.addDeserializationExclusionStrategy(strategy)
.disableHtmlEscaping()
.serializeNulls()
.setPrettyPrinting()
.create();
}
排除策略和漂亮打印等所有其他设置工作正常,但键入适配器 - 不行。
我还尝试配置消息转换器(configureMessageConverters、extendMessageConverters):
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.removeIf(c -> c instanceof GsonHttpMessageConverter);
converters.add(new GsonHttpMessageConverter(gson()));
}
}
As explained in the reference documentation,您可以使用 GsonBuilderCustomizer
自定义 Gson 基础结构,如下所示:
@Configuration
public class GsonConfiguration {
@Bean
public GsonBuilderCustomizer typeAdapterRegistration() {
return builder -> {
builder.registerTypeAdapter(Version.class, new VersionTypeAdapter());
};
}
}
请确保您已将 Gson 设置为您的首选 JSON 库,因为 Jackson 经常被许多依赖项传递。在application.properties
中,您可以添加以下内容:
spring.mvc.converters.preferred-json-mapper=gson
我已经使用以下控制器成功测试了这种方法:
@RestController
public class GsonController {
@GetMapping("/version")
public Version showVersion() {
return Version.fromVersionString("1.2.3-42");
}
}
控制器returns:
➜ ~ http :8080/version
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Keep-Alive: timeout=60
Transfer-Encoding: chunked
"1.2.3-42"