java - Dropwizard 支持多种序列化格式

标签 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 服务,并试图弄清楚如何实现多种格式支持,但文档在这方面是贫瘠的。有什么想法吗?

最佳答案

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

例如如果客户端发送的是JSON数据,那么客户端应该设置请求头Content-Type: application/json。 Jersey 将使用 @Consume("application/json") 查找方法或类。如果找到它,则意味着该应用已配置为支持媒体类型 application/json。如果不支持,则客户端将收到回复,指出不支持该媒体类型。

同样当客户端请求数据时,它应该设置Accept: application/json 请求头。 Jersey 将寻找 @Produces("application/json")。如果它无法为端点找到它,那么客户端将收到一条消息,指出它不是可接受的类型。

因此我们可以为同一端点支持不同的媒体类型。您可以像这样声明方法

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

您需要关心的是如果对于每个可以处理Foo< 序列化的媒体类型都有一个MessageBodyWriter/ 类型。查看更多信息 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());
}

至于您在 URL 中使用 .xml.json 扩展名,客户端通常不会这样说它想要什么类型。通常将 Accept 请求 header 设置为您的服务器支持的类型之一,如上所述。

但是 支持 URL 类型扩展,但它通常适用于无权设置 header 的客户端,例如浏览器。但是您需要使用 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);

另请参阅:

关于java - Dropwizard 支持多种序列化格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32513922/

相关文章:

java - 如何识别从 byte[] 转换而来的具有负值的 int?

java - 从按下的 JMenuItem 获取文本?

java - MULTIPART_FORM_DATA : No injection source found for a parameter of type public javax. ws.rs.core.Response

tomcat - Jersey 是如何连接到 servlet 3 容器的

java - 使用 UriBuilder 从 XmlAdapter 创建绝对 URI

java - java应用程序可以管理Derby数据库中的触发器和UDF吗?

java - AChartEngine 绘图、ArrayList 索引

jquery - Ajax 调用下载从 RESTful 服务返回的文件

javascript - 无法从 JSON 获取嵌套对象

使用多线程的 Java Rest 客户端