I have been trying to add custom serialization of my Version class in RestComponent:
public class Version {
public int MAJOR;
public int MINOR;
public int REVISION;
public Integer BUILD;
}
Json output I expect:
"1.2.2"
not
{
"MAJOR": 1,
"MINOR": 2,
"REVISION": 2,
"BUILD": null
}
So I decide to use JsonSerializer and JsonDeserializer interfaces, also tried TypeAdapter. I’ve created a Gson Bean in my MVC configuration class, also tried to create GsonBuilder bean. In application properties I choosen gson as serializator, and removed Jackson dependencies.
@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();
}
All other settings as Exlusion strategies and pretty printing is working fine, but type adpapters – not.
I also tried to configure message converters (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()));
}
}
Advertisement
Answer
As explained in the reference documentation, you can customize the Gson infrastructure with a GsonBuilderCustomizer like so:
@Configuration
public class GsonConfiguration {
@Bean
public GsonBuilderCustomizer typeAdapterRegistration() {
return builder -> {
builder.registerTypeAdapter(Version.class, new VersionTypeAdapter());
};
}
}
Please make sure that you’ve set Gson as your preferred JSON library, as Jackson is often brought transitively by many dependencies. In application.properties, you can add the following:
spring.mvc.converters.preferred-json-mapper=gson
I’ve successfully tested this approach with the following controller:
@RestController
public class GsonController {
@GetMapping("/version")
public Version showVersion() {
return Version.fromVersionString("1.2.3-42");
}
}
The controller 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"