Dropwizard支持多种序列化格式

sme*_*eeb 1 java rest jax-rs jersey 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
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*tha 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());
} 
Run Code Online (Sandbox Code Playgroud)

您需要担心的是,每种媒体类型是否都有一个MessageBodyWriter可以处理类型序列化的媒体类型Foo。在JAX-RS实体提供者中查看更多内容。

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

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

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

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

至于你使用的.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);
Run Code Online (Sandbox Code Playgroud)

也可以看看: