[英]GET Request with Content-Type and Accept header with JAX-RS Jersey 2.2
我尝试访问开放数据网络服务,该服务为我提供了交通信息。 文档说请求必须是GET
并且必须包含Accept: application/json
和Content-Type: application/json
。 我不明白为什么他们需要Content-Type
但是还可以:
我尝试仅使用Accept:
标头来检索数据,但始终得到415 Unsupported Media Type
。 现在,我目前正在以这种方式尝试(但不确定我是否正确设置了两个标头):
String entity = ClientBuilder.newClient().target(liveDataURI)
.path(liveDataPath)
.request(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.get(String.class);
如您所见,我正在使用Jersey 2.2,但仍收到415 Unsupported Media Type
。
编辑
所以我知道了,但是我不明白为什么。 accept(MediaType.APPLICATION_JSON)
和header("Content-type","application/json")
是否不相同?
String responseEntity = ClientBuilder.newClient()
.target(liveDataURI)
.path(liveDataPath)
.request(MediaType.APPLICATION_JSON)
.header("Content-type", "application/json")
.get(String.class);
Accept
标头告诉服务器您的客户端在响应中需要什么 。 Content-Type
标头告诉服务器客户端在请求中发送的内容 。 所以两者是不一样的。
如果服务器仅接受application/json
,则必须发送一个指定请求内容的请求:
Content-Type: application/json
这就是您编辑的代码起作用的原因。
编辑
在您的第一个代码中,您使用WebTarget.request(MediaType... acceptedResponseTypes)
。 该方法的参数
定义接受的响应媒体类型。
您正在此方法调用的结果上使用Innvocation.Builder.accept(MediaType... mediaTypes)
。 但是accept()
没有添加新的头文件,在您的第一个代码中是不必要的。
您永远不会指定请求的内容类型。 由于服务器需要Content-Type
标头,因此它会以415
响应。
accept(MediaType.APPLICATION_JSON)
和header("Content-type","application/json")
是否不相同?
不,他们不同。
它们是如何关联的:
Client Server
(header) (class/method annotation)
====================================================
Accept <---> @Produces
Content-Type <---> @Consumes
服务器使用主体接收从客户端接收的Content-Type
(其格式在Content-Type
指定),并生成客户端接受的内容(在Accept
指定其格式)。
范例 :
Content-Type
= text/xml
(它在正文中发送XML) Accept
= application/json
(它期望得到一个JSON作为响应) @Consumes(MediaType.TEXT_XML)
(它从客户端获取XML) @Produces(MediaType.APPLICATION_JSON)
(它将JSON发送到客户端) Obs :
服务器可以更加灵活,配置为获取/产生多种可能的格式 。
例如:如果客户端具有以下注释,则一个客户端可以发送XML,而另一个客户端可以将JSON发送到同一方法: @Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
。
MediaType
值只是String
常量:
public final static String APPLICATION_JSON = "application/json"; public final static String TEXT_XML = "text/xml";
如果输入请求中未提供默认的Accept标头,则可以使用ContainerResponseFilter
设置它。
@Provider
public class EntityResponseFilter implements ContainerResponseFilter {
private MediaType getExternalMediaType(){
MediaType mediaType = new MediaType("application", "vnd.xxx.resource+json")
return mediaType;
}
@Override
public void filter( ContainerRequestContext reqc , ContainerResponseContext resc ) throws IOException {
MediaType mediaType = getExternalMediaType();
List<MediaType> mediaTypes = reqc.getAcceptableMediaTypes();
if( mediaTypes.contains(mediaType) ) {
resc.setEntity( resc.getEntity(), new Annotation[0], mediaType );
}
// ...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.