简体   繁体   中英

Can @GET define Consumes Content-Type for JAX-RS implementation?

I have been trying few samples on JAXRS (used Jersey for this example). The following is a sample stub implemenatation I have:

    @Path("stubservice")
public class StubImpl
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getString(@QueryParam("first")
    int first, @QueryParam("second")
    int second)
    {
        return "first: " + first + " second: " + second;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public String getSize(@QueryParam("size")
                              int size,
                              @Context
                              HttpHeaders headers)
    {
        Gson gson = new Gson();
        return gson.toJson("something else");
    }
}

Without getSize method having @Consumes(MediaType.APPLICATION_JSON) in its definition, this class is having errors during initialization. But with it, StubImpl class initializes correctly and serves the requests based on whether the incoming requests have their Content-Type as application/json .

Error during initialization:

SEVERE: The following errors and warnings have been detected with resource and/or provider classes: SEVERE: Producing media type conflict. The resource methods public java.lang.String StubImpl.getString(int,int) and public java.lang.String StubImpl.getSize(int,javax.ws.rs.core.HttpHeaders) can produce the same media type

As I understand, @GET requests would never need @Consumes(MediaType.APPLICATION_JSON) as it is meant for the content type in the body (and GET method doesn't have body).

Is the existing behavior expected ?

Thanks in advance

Not a JAX-RS expert at all, so this is just a guess.

How could Jersey decide which method to invoke when a GET request comes in if you don't set @Consumes(MediaType.APPLICATION_JSON) ?

Both methods answer to GET requests, on the same path, accept any media type, and produce the same media type. So my guess is that Jersey can't decide (other than randomly) which method to call when a GET request comes in to this path, and thus refuses to start up.

The @Consumes annotation makes it call getSize when request has a JSON body (ie never), and the other method in all the other cases (ie always).

You didn't set Path for neither getString nor getSize. This is the root cause.

   @Path("stubservice")
public class StubImpl
    @GET
    @Path("getstring")   //the full path will be /stubservice/getstring
    @Produces(MediaType.APPLICATION_JSON)
    public String getString(@QueryParam("first")
    int first, @QueryParam("second")
    int second)
    {
        return "first: " + first + " second: " + second;
    }

    @GET
    @Path("getsize")    //the full path will be /stubservice/getsize
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public String getSize(@QueryParam("size")
                              int size,
                              @Context
                              HttpHeaders headers)
    {
        Gson gson = new Gson();
        return gson.toJson("something else");
    }
}

To start off with the error that you are getting on initialization:

The reason that you are getting the error is as @Stony Zhang suggests. When you remove the @Consumes , both of the methods are essentially pointing to the same path, and JAX-RS has no way of distinguishing between the two RESTFul endpoints.

The @Consumes(MediaType.APPLICATION_JSON) is not needed by the GET request. From the oracle documentation at @Consumes oracle documentation The @Consumes annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client. This means that you indeed, do not need to use json as the media type that the endpoint is going to accept. You can use @Consumes("multipart/related") or @Consumes({"text/plain,text/html"}) or whatever, depending on what MIME type you are sending to the server.

You are also correct in saying that @GET does not have a body. This is placed in the @Path annontation and is the querystring input from the url. It is something like

`@GET

 @Path("/stubservice/{id}")`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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