通常对不同格式配置的支持只需在@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/json、application/xml、application/x-protobuf 媒体类型需要序列化不同的域类型,您可以使用不同的方法来处理不同的类型。例如,application/json 和 application/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);
另请参阅: