Dropwizard支持多种序列化格式

时间:2015-09-11 01:05:24

标签: java rest jersey jax-rs dropwizard

在RESTful API中很常见的是查看可支持多种序列化格式的端点:

// Sends back "fizz" resource that has an id=34 as a JSON object
http://api.example.com/v2/fizz/34.json

// Sends back "fizz" resource that has an id=34 as an XML object
http://api.example.com/v2/fizz/34.xml

// Sends back "fizz" resource that has an id=34 as a binary object,
// say, using Google Protocol Buffers
http://api.example.com/v2/fizz/34.bin

我正在设计一个Dropwizard服务,我正在试图弄清楚如何实现多种格式支持,但这方面的文档很贫瘠。有什么想法吗?

1 个答案:

答案 0 :(得分:6)

通常,在@Produces@Consumes注释中以声明方式完成对不同格式配置的支持。当客户端发送数据时,Content-Type请求标头应设置为正在发送的数据的实际类型。

例如,如果客户端正在发送JSON数据,则客户端应设置请求标头Content-Type: application/json。泽西岛将寻找@Consume("application/json")的方法或类。如果找到它,则表示该应用程序已配置为支持媒体类型application/json。如果没有,那么客户端将收到回复,说不支持媒体类型。

同样,当客户端请求数据时,它应该设置Accept: application/json请求标头。泽西岛将寻找@Produces("application/json")。如果找不到端点,则客户端会收到一条消息,说明它不是可接受的类型。

因此,我们可以支持同一端点的不同媒体类型。您可以声明类似

的方法
@Produces({"application/json", "application/xml", "application/x-protobuf"})
public Response getFoo() {
    return Response.ok(new Foo());
} 

您需要关注的是如果对于可以处理MessageBodyWriter类型序列化的每种媒体类型都有Foo。请参阅JAX-RS Entity Providers

或者,如果application/jsonapplication/xmlapplication/x-protobuf媒体类型要求序列化不同的域类型,则可以使用不同的方法来处理不同的类型。例如,application/jsonapplication/xml,您通常可以使用相同的Foo域对象,因此您可以这样做

@Produces({"application/xml", "application/json"})
public Response getFooJsonOrXml() {
    return Response.ok(new Foo());
}

但对于Protobuf,它需要Protobuf编译的类。因此,您将返回生成的类型而不是Foo域对象。

@Produces("application/x-protobuf")
public Response getFooProtobuf() {
    return Response.ok(new ProtobufFoo());
}

至于您在网址中使用.xml.json扩展名,这通常不是客户说出所需类型的方式。通常将Accept请求标头设置为服务器支持的类型之一,如上所述。

支持URL类型扩展,但它通常适用于无权设置标头的客户端,例如浏览器。但您需要使用UriConnegFilter配置这些媒体类型映射。例如

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);

另见: