Generally support for different format configuration is simply done declaratively in the @Produces
and @Consumes
annotations. When the client sends data, then the Content-Type
request header should be set to the actual type of the data being sent.
For example if the client is sending JSON data, then the client should set the request header Content-Type: application/json
. Jersey will look for a method or class with @Consume("application/json")
. If it finds it, then that means the app is configured to support the media type application/json
. If not, then the client will get a response back saying the media type is not supported.
Likewise when the client is requesting data, it should set the Accept: application/json
request header. Jersey will look for @Produces("application/json")
. If it can't find it for the endpoint, then the client will get a message saying it is not an acceptable type.
So we can support different media types for the same endpoint. You can declare the method like
@Produces({"application/json", "application/xml", "application/x-protobuf"})
public Response getFoo() {
return Response.ok(new Foo());
}
The thing that you need to be concerned about is if there is a MessageBodyWriter
for each of those media types that can handle the serialization of the Foo
type. See more at JAX-RS Entity Providers.
Alternatively, if the application/json
, application/xml
, application/x-protobuf
media types require different domain types to be serialized, you can have different methods to handle the different types. For example, application/json
and application/xml
, you can usually get away with using the same Foo
domain object, so you can just do
@Produces({"application/xml", "application/json"})
public Response getFooJsonOrXml() {
return Response.ok(new Foo());
}
But for Protobuf, it requires Protobuf compiled classes. So instead of the Foo
domain object, you would return the generated type.
@Produces("application/x-protobuf")
public Response getFooProtobuf() {
return Response.ok(new ProtobufFoo());
}
As for your use of the .xml
, .json
extension in your URLs, that is generally not the way for the client to say what type it wants. Usually the set the Accept
request header to one of the types that your server supports, as mentioned above.
But there is support for the URL type extension, but it is usually meant for clients that don't have access to setting the headers, for instance a browser. But you need to configure those media type mappings with the UriConnegFilter
. For example
Map<String, MediaType> map = new HashMap<>();
map.put("xml", MediaType.APPLICATION_XML_TYPE);
map.put("json", MediaType.APPLICATION_JSON_TYPE);
map.put("bin", ProtocolBufferMediaType.APPLICATION_PROTOBUF_TYPE);
env.jersey().property(ServerProperties.MEDIA_TYPE_MAPPINGS, map);
See Also: