Closed GuentherJulian closed 3 years ago
I tested the json-module.
<dependency>
<groupId>com.devonfw.java.modules</groupId>
<artifactId>devon4j-json</artifactId>
<version>2021.04.003</version>
</dependency>
@Named("ApplicationObjectMapperFactory")
public class ApplicationObjectMapperFactory extends ObjectMapperFactory {
public ApplicationObjectMapperFactory() {
super();
SimpleModule module = getExtensionModule();
// register spring-data Pageable
module.addSerializer(Pageable.class, new PageableJsonSerializer());
module.addDeserializer(Pageable.class, new PageableJsonDeserializer());
}
}
and inject custom mapper to resteasy
@Component
@Provider
@Consumes({"application/json", "application/*+json", "text/json"})
@Produces({"application/json", "application/*+json", "text/json"})
public class CustomJacksonJsonProvider extends ResteasyJackson2Provider {
@Inject
ObjectMapperFactory objectMapperFactory;
@Override
public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
ObjectMapper om = objectMapperFactory.createInstance();
return om;
}
}
Result:
I think you do not simple can use the devon4j-json module in the Quarkus context. You have to implement the ObjectMapperCustomizer
(io.quarkus.jackson.ObjectMapperCustomizer) as described here. Then you can add a custom serializer in the customize
method.
@Override
public void customize(ObjectMapper objectMapper) {
SimpleModule module = new SimpleModule();
module.addSerializer(Page.class, new JsonSerializer<Page>() {
@Override
public void serialize(Page value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
...
}
});
objectMapper.registerModule(module);
}
@GuentherJulian you are right. That should do it. Thanks. I saw the problem now, even the json-module does not provide a serializer for Page.class (only Pagable.class)
Implement custom mapper using io.quarkus.jackson.ObjectMapperCustomizer
(code in this branch)
the custom serializer for Page.class. We can customize further here if wanted
public class PageSerializer extends JsonSerializer<Page> {
@Override
public void serialize(Page page, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (page != null) {
jsonGenerator.writeStartObject();
jsonGenerator.writeObjectField("content", page.getContent());
jsonGenerator.writeObjectField("pageable", page.getPageable());
jsonGenerator.writeBooleanField("last", page.isLast());
jsonGenerator.writeNumberField("totalPages", page.getTotalPages());
jsonGenerator.writeNumberField("totalElements", page.getTotalElements());
jsonGenerator.writeBooleanField("first", page.isFirst());
jsonGenerator.writeNumberField("numberOfElements", page.getNumberOfElements());
jsonGenerator.writeObjectField("sort", page.getSort());
jsonGenerator.writeNumberField("number", page.getNumber());
jsonGenerator.writeNumberField("size", page.getSize());
jsonGenerator.writeBooleanField("empty", page.isEmpty());
jsonGenerator.writeEndObject();
}
}
}
register custom serializer to object mapper
@Singleton
public class CustomObjectMapper implements ObjectMapperCustomizer {
@Override
public void customize(ObjectMapper objectMapper) {
SimpleModule module = new SimpleModule();
module.addSerializer(Page.class, new PageSerializer());
objectMapper.registerModule(module);
}
}
Result:
@GuentherJulian should this be sufficient? We can create another issue to refactor the sample app.
@GuentherJulian should this be sufficient? We can create another issue to refactor the sample app.
Great! Yes, please create a following task to refactor the rest service.
Refactoring the sample app should follow by this issue
It looks ok for me
At the moment we use
PageImpl
as return type in our Rest Services. If we only use thePage
interface, serialization will not work in native mode. This is because JSON serialization uses reflection to determine the properties of an object. When usingPage
, only the interface is registered for reflection by Quarkus, so the other properties needed for paging are not accessible in native mode.In devon4j there were also issues with serializing
Page
to/from JSON. The solution in devon4j was to configure Jackson accordingly. https://github.com/devonfw/devon4j/tree/master/modules/json/src/main/java/com/devonfw/module/json/common/base/typeWe need to check if there is also a solution for Quarkus so that we can use
Page
instead ofPageImpl
.