Java @GET define能否为JAX-RS实现使用内容类型?
我在JAXR上尝试了几个示例(本例中使用了Jersey)。以下是我的存根实现示例:Java @GET define能否为JAX-RS实现使用内容类型?,java,rest,get,jersey,jax-rs,Java,Rest,Get,Jersey,Jax Rs,我在JAXR上尝试了几个示例(本例中使用了Jersey)。以下是我的存根实现示例: @Path("stubservice") public class StubImpl @GET @Produces(MediaType.APPLICATION_JSON) public String getString(@QueryParam("first") int first, @QueryParam("second") int second) {
@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\u JSON)
,则此类在初始化过程中会出错。但是有了它,StubImpl
类将正确初始化,并根据传入请求是否具有内容类型
作为application/json
为请求提供服务
初始化期间出错:
严重:检测到资源和/或提供程序类出现以下错误和警告:
严重:产生媒体类型冲突。资源方法public java.lang.String StubImpl.getString(int,int)和public java.lang.String StubImpl.getSize(int,javax.ws.rs.core.HttpHeaders)可以生成相同的媒体类型
据我所知,@GET请求永远不需要@Consumes(MediaType.APPLICATION\u JSON)
,因为它是用于正文中的内容类型的(而GET方法没有正文)
是否预期现有行为
提前感谢根本不是JAX-RS专家,所以这只是一个猜测 如果不设置
@Consumes(MediaType.APPLICATION\u JSON)
,Jersey如何决定在GET请求传入时调用哪个方法
这两种方法都在同一路径上响应获取请求,接受任何媒体类型,并生成相同的媒体类型。所以我的猜测是Jersey无法决定(除了随机)当GET请求进入此路径时调用哪个方法,因此拒绝启动
@使用
注释使其在请求有JSON正文(即从不)时调用getSize,在所有其他情况下调用另一个方法(即始终)。您没有为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");
}
}
要从初始化时出现的错误开始,请执行以下操作: 您出现错误的原因正如
@Stony Zhang
所示。当您删除@Consumes
时,这两个方法基本上都指向同一条路径,JAX-RS无法区分这两个RESTFul端点
GET请求不需要@Consumes(MediaType.APPLICATION\u JSON)
。从oracle文档
@Consumes注释用于指定资源可以从客户端接受或使用哪些MIME媒体类型的表示。这意味着您确实不需要使用json作为端点将要接受的媒体类型。您可以使用@Consumes(“multipart/related”)或@Consumes({“text/plain,text/html”})或其他任何形式,具体取决于发送到服务器的MIME类型
你说@GET没有主体也是正确的。这被放置在@Path注释中,是来自url的查询字符串输入。有点像
`@GET
@Path("/stubservice/{id}")`
奇怪。。。你会犯什么样的错误?它是否可能与标有
@Context
注释的参数HttpHeaders
有关?@AlexR感谢您的回复。更新的错误信息有人注意到这个问题吗?它不是jersey bug就是jax rs规范bug。我E即使使用@Consumes
,它也应该给出相同的错误,但事实并非如此。在jersey jira上报道-他们反应很快。@string我一直在寻找你预测的答案(我想jersey的委托人可能会回应)。无论如何,谢谢。对不起,问题是两个@GET
方法的路径相同。我理解,如果@Path
不同,则不会导致任何问题。如果目标是使用相同的HTTP字(GET)和相同的URI路径(/)来定义这两个方法,那么您认为JERSEY将如何区别它们?我的意思是,从调用方的角度来看,您会在http请求中提供哪些不同的内容?知道查询参数不起作用。Morover,REST体系结构模式中不需要在GET中提供“主体”内容。@我理解Jersey在注释定义没有差异时会出错。然而,问题是关于影响实现的@Consumes
定义。到目前为止,我没有正确理解您的问题。如果我是正确的,您的问题可以改写为“JERSEY中是否有丢失的控件,使得它在这种情况下抛出相同的异常,无论GETs上是否有潜在的@Consumes?”。我会回答是的。我认为这是一个错误的猜测。Jersey可以根据Accept:
标题来决定,如果缺少该标题,则有一个优先顺序来提供编码。根据该顺序,它会找到用正确的@products
@randomstring:精确地注释的方法。但是,由于这两种方法都有相同的products
注释,它无法决定调用哪一个。请更正re-sameproducts
,但我关于猜测错误的意思是您猜测@Consumes
用于消除歧义。既然GET
没有身体,Jersey为什么还要费心去看@Consumes
,除非它是为了删除第一种情况下不应该存在的死代码。因此,无论@如何使用注释,歧义都会保持不变。好吧,OP的问题表明,这种歧义不会保持不变。请参见下面trevgiddy的答案。我敢打赌OP描述的行为依赖于实现。Jersey作为第一个与Java EE计划竞赛的参考实现,没有忽略应用于@GET
的@Consumes
,因此给出了一个“假阴性”-i。E它应该给出相同的初始化错误,但不是由于bug或由于spec bug导致的实现定义的行为