简体   繁体   English

@GET可以为JAX-RS实现定义Consumes Content-Type吗?

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

I have been trying few samples on JAXRS (used Jersey for this example). 我一直在JAXRS上尝试一些示例(本例中使用Jersey)。 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. 如果没有在其定义中具有@Consumes(MediaType.APPLICATION_JSON) getSize方法,则@Consumes(MediaType.APPLICATION_JSON)在初始化期间出错。 But with it, StubImpl class initializes correctly and serves the requests based on whether the incoming requests have their Content-Type as application/json . 但有了它, StubImpl类正确初始化并根据传入的请求是否将其Content-Type作为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). 据我所知,@ GET请求永远不需要@Consumes(MediaType.APPLICATION_JSON)因为它适用于正文中的内容类型(并且GET方法没有正文)。

Is the existing behavior expected ? 现有行为是否有望?

Thanks in advance 提前致谢

Not a JAX-RS expert at all, so this is just a guess. 根本不是JAX-RS专家,所以这只是猜测。

How could Jersey decide which method to invoke when a GET request comes in if you don't set @Consumes(MediaType.APPLICATION_JSON) ? 如果你没有设置@Consumes(MediaType.APPLICATION_JSON) Jersey如何决定在GET请求进入时调用哪个方法?

Both methods answer to GET requests, on the same path, accept any media type, and produce the same media type. 两种方法都响应GET请求,在同一路径上接受任何媒体类型,并生成相同的媒体类型。 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. 所以我的猜测是,当GET请求进入此路径时,Jersey无法决定(除了随机)调用哪个方法,因此拒绝启动。

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). @Consumes注释使得它在请求具有JSON主体(即从不)时调用getSize,而在所有其他情况下(即始终)调用另一个方法。

You didn't set Path for neither getString nor getSize. 您没有为getString和getSize设置Path。 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. 您收到错误的原因是@Stony Zhang建议的那样。 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. 当你删除@Consumes ,这两个方法实际上指向相同的路径,并且JAX-RS无法区分两个RESTFul端点。

The @Consumes(MediaType.APPLICATION_JSON) is not needed by the GET request. GET请求不需要@Consumes(MediaType.APPLICATION_JSON) 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. 来自@Consumes oracle文档oracle文档 @Consumes注释用于指定资源可以从客户端接受或使用的表示的MIME媒体类型。 This means that you indeed, do not need to use json as the media type that the endpoint is going to accept. 这意味着您确实不需要使用json作为端点将接受的媒体类型。 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. 您可以使用@Consumes(“multipart / related”)或@Consumes({“text / plain,text / html”})或其他任何内容,具体取决于您向服务器发送的MIME类型。

You are also correct in saying that @GET does not have a body. 你说@GET没有正文你也是对的。 This is placed in the @Path annontation and is the querystring input from the url. 它放在@Path annontation中,是来自url的查询字符串输入。 It is something like 它就像是

`@GET

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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