繁体   English   中英

带有Content-Type的GET Request和带有JAX-RS Jersey 2.2的Accept标头

[英]GET Request with Content-Type and Accept header with JAX-RS Jersey 2.2

我尝试访问开放数据网络服务,该服务为我提供了交通信息。 文档说请求必须是GET并且必须包含Accept: application/jsonContent-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

  1. 服务器可以更加灵活,配置为获取/产生多种可能的格式

    例如:如果客户端具有以下注释,则一个客户端可以发送XML,而另一个客户端可以将JSON发送到同一方法: @Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM