我尝试访问一个开放数据网络服务,它为我提供了流量信息。文档说请求必须为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);
答案 0 :(得分:15)
Accept
标题告诉服务器您的客户在响应中想要的内容。 Content-Type
标头告诉服务器客户端在请求中发送的内容。所以两者不相同。
如果服务器只接受application/json
,则必须发送指定请求内容的请求:
Content-Type: application/json
这就是您编辑的代码有效的原因。
修改强>
在您的第一个代码中,您使用WebTarget.request(MediaType... acceptedResponseTypes)
。这个方法的参数
定义接受的响应媒体类型。
您正在对此方法调用的结果使用Innvocation.Builder.accept(MediaType... mediaTypes)
。但是accept()
没有添加任何新标头,在您的第一个代码中没有必要。
您永远不会指定请求的内容类型。由于服务器需要Content-Type
标头,因此它会以415
响应。
答案 1 :(得分:13)
不,他们是不同的 这就是它们的相关性:
["abc", "def"...]
和accept(MediaType.APPLICATION_JSON)
不一样吗?
header("Content-type","application/json")
服务器使用它从正文中的客户端接收的内容(其格式在Client Server
(header) (class/method annotation)
====================================================
Accept <---> @Produces
Content-Type <---> @Consumes
中指定)并且它产生客户端接受的内容(其格式在Content-Type
中指定)。
示例强>:
Accept
= Content-Type
(它在正文中发送XML)text/xml
= Accept
(希望获得JSON作为回复)application/json
(它从客户端获取XML)@Consumes(MediaType.TEXT_XML)
(它向客户端发送JSON)<强>观测值强>:
服务器可以更灵活,配置为获得/生成多个可能的格式。
例如:客户端可以发送XML,而另一个客户端可以将JSON发送到同一方法,如果它具有以下注释:@Produces(MediaType.APPLICATION_JSON)
。
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
值仅为MediaType
常量:
String
答案 2 :(得分:2)
如果输入请求中未提供默认的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 );
}
// ...
}
}