【问题标题】:Dropwizard support for multiple serialization formatsDropwizard 支持多种序列化格式
【发布时间】:2015-09-11 01:05:24
【问题描述】:

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

【问题讨论】:

    标签: java rest jersey jax-rs dropwizard


    【解决方案1】:

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

    例如,如果客户端正在发送 JSON 数据,则客户端应设置请求标头Content-Type: application/json。 Jersey 将寻找带有@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());
    } 
    

    您需要关心的是如果对于每个可以处理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 请求标头设置为您的服务器支持的类型之一,如上所述。

    但是 支持 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);
    

    另请参阅:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 2019-11-27
      • 2016-01-23
      • 2011-04-20
      • 2015-05-10
      相关资源
      最近更新 更多