Dropwizard 支持多种序列化格式
Dropwizard support for multiple serialization formats
在 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数据,那么客户端应该设置请求headerContent-Type: application/json
。 Jersey 将寻找方法或 class 与 @Consume("application/json")
。如果找到它,则表示该应用已配置为支持媒体类型 application/json
。如果不支持,则客户端将收到回复,说明不支持媒体类型。
同理当客户端请求数据时,应该设置Accept: application/json
请求header。泽西岛将寻找 @Produces("application/json")
。如果它无法为端点找到它,那么客户端将收到一条消息,说明它不是可接受的类型。
因此我们可以为同一端点支持不同的媒体类型。你可以像
这样声明方法
@Produces({"application/json", "application/xml", "application/x-protobuf"})
public Response getFoo() {
return Response.ok(new Foo());
}
你需要关心的事情是 如果 每个媒体类型都有一个 MessageBodyWriter
可以处理 [=23] 的序列化=] 类型。在 JAX-RS Entity Providers.
查看更多
或者,如果 application/json
、application/xml
、application/x-protobuf
媒体类型需要不同的域类型进行序列化,您可以使用不同的方法来处理不同的类型。例如,application/json
和 application/xml
,你通常可以使用相同的 Foo
域 object,所以你可以只做
@Produces({"application/xml", "application/json"})
public Response getFooJsonOrXml() {
return Response.ok(new Foo());
}
但是对于Protobuf,它需要Protobuf编译classes。因此,您将 return 生成的类型代替 Foo
域 object。
@Produces("application/x-protobuf")
public Response getFooProtobuf() {
return Response.ok(new ProtobufFoo());
}
至于您在 URL 中使用 .xml
、.json
扩展名,客户通常不会这样说它想要什么类型。通常将 Accept
请求 header 设置为您的服务器支持的类型之一,如上所述。
但是 支持 URL 类型扩展,但它通常适用于无法设置 header 的客户s,例如浏览器。但是您需要使用 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);
另请参阅:
在 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数据,那么客户端应该设置请求headerContent-Type: application/json
。 Jersey 将寻找方法或 class 与 @Consume("application/json")
。如果找到它,则表示该应用已配置为支持媒体类型 application/json
。如果不支持,则客户端将收到回复,说明不支持媒体类型。
同理当客户端请求数据时,应该设置Accept: application/json
请求header。泽西岛将寻找 @Produces("application/json")
。如果它无法为端点找到它,那么客户端将收到一条消息,说明它不是可接受的类型。
因此我们可以为同一端点支持不同的媒体类型。你可以像
这样声明方法@Produces({"application/json", "application/xml", "application/x-protobuf"})
public Response getFoo() {
return Response.ok(new Foo());
}
你需要关心的事情是 如果 每个媒体类型都有一个 MessageBodyWriter
可以处理 [=23] 的序列化=] 类型。在 JAX-RS Entity Providers.
或者,如果 application/json
、application/xml
、application/x-protobuf
媒体类型需要不同的域类型进行序列化,您可以使用不同的方法来处理不同的类型。例如,application/json
和 application/xml
,你通常可以使用相同的 Foo
域 object,所以你可以只做
@Produces({"application/xml", "application/json"})
public Response getFooJsonOrXml() {
return Response.ok(new Foo());
}
但是对于Protobuf,它需要Protobuf编译classes。因此,您将 return 生成的类型代替 Foo
域 object。
@Produces("application/x-protobuf")
public Response getFooProtobuf() {
return Response.ok(new ProtobufFoo());
}
至于您在 URL 中使用 .xml
、.json
扩展名,客户通常不会这样说它想要什么类型。通常将 Accept
请求 header 设置为您的服务器支持的类型之一,如上所述。
但是 支持 URL 类型扩展,但它通常适用于无法设置 header 的客户s,例如浏览器。但是您需要使用 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);
另请参阅: