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"