4

我一直在尝试一些关于 JAXRS 的样本(在这个例子中使用了 Jersey)。以下是我拥有的示例存根实现:

    @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");
    }
}

如果没有在其定义中包含getSize方法@Consumes(MediaType.APPLICATION_JSON),则此类在初始化期间会出现错误。但是有了它,StubImpl类会正确初始化并根据传入请求是否具有Content-Typeas来为请求提供服务application/json

初始化过程中发生错误:

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

据我了解,@GET 请求永远不需要@Consumes(MediaType.APPLICATION_JSON),因为它适用于正文中的内容类型(并且 GET 方法没有正文)。

现有的行为是预期的吗?

提前致谢

4

3 回答 3

7

根本不是 JAX-RS 专家,所以这只是一个猜测。

如果您不设置,Jersey 如何决定在 GET 请求进入时调用哪个方法@Consumes(MediaType.APPLICATION_JSON)

两种方法都在同一路径上响应 GET 请求,接受任何媒体类型,并产生相同的媒体类型。所以我的猜测是,当 GET 请求进入此路径时,Jersey 无法决定(除了随机)调用哪个方法,因此拒绝启动。

@Consumes请求具有 JSON 主体(即从不)时,注释使其调用 getSize,而在所有其他情况下(即始终)调用其他方法。

于 2013-05-22T15:22:47.283 回答
0

您没有为 getString 和 getSize 设置路径。这是根本原因。

   @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");
    }
}
于 2013-05-27T01:59:45.873 回答
0

从您在初始化时遇到的错误开始:

您收到错误的原因正如所@Stony Zhang建议的那样。当您删除 时@Consumes,这两种方法本质上都指向相同的路径,并且 JAX-RS 无法区分两个 RESTFul 端点。

@Consumes(MediaType.APPLICATION_JSON)GET 请求不需要。来自@Consumes 的oracle 文档 oracle 文档 @Consumes 注释用于指定资源可以从客户端接受或使用的表示的MIME 媒体类型。这意味着您确实不需要使用 json 作为端点将要接受的媒体类型。您可以使用 @Consumes("multipart/related") 或 @Consumes({"text/plain,text/html"}) 或其他任何东西,具体取决于您发送到服务器的 MIME 类型。

您说@GET 没有正文也是正确的。这放置在 @Path 注释中,是来自 url 的查询字符串输入。有点像

`@GET

 @Path("/stubservice/{id}")`
于 2013-05-28T21:47:01.647 回答