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

前端 未结 3 1361
盖世英雄少女心
盖世英雄少女心 2020-12-24 15:11

I try to access an open data web service which gives me traffic infos. Documentation says that requests have to be GET and need to contain Accept: applica

相关标签:
3条回答
  • 2020-12-24 15:22

    Isn't accept(MediaType.APPLICATION_JSON) and header("Content-type","application/json") the same?

    No, they are different.
    This is how they are related:

    Client                     Server
    (header)                   (class/method annotation)
    ====================================================
    Accept          <--->      @Produces
    Content-Type    <--->      @Consumes
    

    The server consumes what it receives from the client in body (its format is specified in Content-Type) and it produces what the client accepts (its format is specified in Accept).

    Example:

    • client sends the following headers:
      • Content-Type = text/xml (it sends an XML in body)
      • Accept = application/json (it expects to get a JSON as a response)
    • server needs to have at least the following annotations for the corresponding method (the annotations are taken from the class level, if they are not explicitly mentioned for that method):
      • @Consumes(MediaType.TEXT_XML) (it gets an XML from the client)
      • @Produces(MediaType.APPLICATION_JSON) (it sends a JSON to the client)

    Obs:

    1. The server can be more flexible, being configured to get/produce multiple possible formats.

      E.g.: a client can send an XML while another client can send a JSON to the same method if it has the following annotation: @Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML }).

    2. The MediaType values are just String constants:

      public final static String APPLICATION_JSON = "application/json";
      public final static String TEXT_XML = "text/xml";
      
    0 讨论(0)
  • 2020-12-24 15:32

    The Accept header tells the server what your client wants in the response. The Content-Type header tells the server what the client sends in the request. So the two are not the same.

    If the server only accepts application/json, you must send a request that specifies the request content:

    Content-Type: application/json
    

    That's why your edited code works.

    Edit

    In your first code you use WebTarget.request(MediaType... acceptedResponseTypes). The parameters of this method

    define the accepted response media types.

    You are using Innvocation.Builder.accept(MediaType... mediaTypes) on the result of this method call. But accept() adds no new header, it is unnecessary in your first code.

    You never specify the content type of your request. Since the server expects a Content-Type header, it responds with 415.

    0 讨论(0)
  • 2020-12-24 15:35

    You can use the ContainerResponseFilter to set the default Accept header if it is not provided in the input request.

    @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 );
            }
            // ...
        }
    }
    
    0 讨论(0)
提交回复
热议问题