Reputation: 131
In a RESTful Glassfish 4 application (JERSEY 2.22.2, MOXY as JSON Provider), we have a resource method that is able to produce both JSON and XML outputs.
The method response passes through a MessageBodyWriter, but it's used to build an Object Graph only in certain cases. In these cases, independently from the requested media type from the client, the graph is applied correctly.
On the other hand, when the isWriteable() method of our MessageBodyWirter returns false, therefore passing on to the next writer in the writers
list of the MessageBodyFactory, the behavior is different between a JSON media type request and an XML media type request (i.e. Accept: application/json
and Accept: application/xml
respectively in the request headers).
In the first case, the FilteringMoxyJsonProvider is selected as response writer, because the EntityFilteringFeature is registered. The response is written based on the entity filtering annotations.
Though when the client asks for an XML response, another MessageBodyWriter (org.glassfish.jersey.jaxb.internal.XmlRootElementJaxbProvider) is selected.
This is due to the ordering of the WriterModel
s in the MessageBodyFactory in which the FilteringMoxyJsonProvider is positioned after XmlRootElementJaxbProvider.
In this situation the XML response is written without having any filters applied to it.
We tried to look for a way to change the writers order, also tried to access to the EntityFieldProcessor class, without luck.
Is it possible to have both scenarios (i.e. JSON and XML response requests) work in the same way? Is it possible to exclude some writers from being registered or to change their order in the MessageBodyFactory?
Any help will be appreciated.
//Configuration
public class ApplicationConfigVersione1 extends ResourceConfig {
....
register(EntityFilteringFeature.class);
register(MyCustomWriter.class);
------------------------
@Produces({"application/json", "application/xml"})
public class MyCustomWriter implements MessageBodyWriter<MyCustomObject> {
....
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
if (mustUseCustomWriter()) {
return true;
} else {
return false;
//In this case, with request header accept=application/xml, the xml response is not filtered.
}
}
@Override
public void writeTo(MyCustomObject customObject, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
objectGraph = buildObjectGraph();
marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, objectGraph);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, mediaType.toString());
//**** objectGraph applies to XML and JSON media types
marshaller.marshall(object, entityStream);
Upvotes: 1
Views: 479
Reputation: 21
I have also tried to use Jersey's Entity Filtering mechanism with resources producing both application/json
and application/xml
responses and see different result information according to the repsonse type.
I suspect this closed/wont-fix github issue for the moxy component is the cause of the behaviour we are seeing with filtering: https://github.com/jersey/jersey/issues/3036
Upvotes: 1