Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 开发jax-rs应用程序时如何处理accept参数_Java_Rest_Jax Rs - Fatal编程技术网

Java 开发jax-rs应用程序时如何处理accept参数

Java 开发jax-rs应用程序时如何处理accept参数,java,rest,jax-rs,Java,Rest,Jax Rs,为了处理不同版本的内容类型,我尝试使用“accept*”头()的accept参数 问题是Jax RS注释不支持接受参数 @GET @产生(“应用程序/vnd.test;版本=1”) 公共响应测试1(){ 返回Response.ok(“版本1”,“应用程序/vnd.test”).build(); } @得到 @产生(“应用程序/vnd.test;版本=2”) 公众回应测试2(){ 返回Response.ok(“版本2”,“应用程序/vnd.test”).build(); } 导致媒体类型冲突异常

为了处理不同版本的内容类型,我尝试使用“accept*”头()的accept参数

问题是Jax RS注释不支持接受参数

@GET
@产生(“应用程序/vnd.test;版本=1”)
公共响应测试1(){
返回Response.ok(“版本1”,“应用程序/vnd.test”).build();
}
@得到
@产生(“应用程序/vnd.test;版本=2”)
公众回应测试2(){
返回Response.ok(“版本2”,“应用程序/vnd.test”).build();
}
导致媒体类型冲突异常:

Producing media type conflict. The resource methods public javax.ws.rs.core.Response test.resources.TestResource.test2() and public javax.ws.rs.core.Response test.resources.TestResource.test1() can produce the same media type
也许,这个异常只与我的JAX-RS框架(Jersey)有关,但我担心这是由于对accept参数没有明确的定义

到目前为止,我使用的内容类型将版本保存在它们的名称中,但我发现这个解决方案非常糟糕

@GET
@Produces("application/vnd.test-v1")
public Response test() {
    return Response.ok("Version 1", "application/vnd.test-v1").build();
}
您对如何处理accept参数有什么想法吗

编辑

我想我还不够清楚。 我想自动将请求路由到特定的方法。 这些方法进行版本控制,并对应于返回内容类型的特定版本。 JAX-RS当前的实现阻止我使用accept参数来路由请求(到相应的方法)

greenkode建议我在分派方法中管理
版本
接受参数(使用
@HeaderParam(“接受”)
)。 该解决方案最终将重写嵌入框架中的内容协商逻辑(并在JSR311中描述)

如何使用JAX-RS中的accept参数和内容协商逻辑


也许一个解决方案是使用另一个框架(我现在只与Jersey合作)。但我不知道是哪一个。

除非我遗漏了什么。JAX-RS确实支持接受参数。查看
@Consumes(“*/*”)
注释。此外,由于在同一url上有两个
GET
方法,因此会出现媒体类型冲突的异常。用
@Path(“test2”)
注释test2()方法,然后将
GET
请求发送到url/test2。这应该可以消除这个错误

编辑

您可以使用
@HeaderParams
注入
Accept
头的值。这是我所做的一个例子

@Path("/conneg")
public class ConnNeg {

    @GET
    @Produces("application/vnd.test;version=1")
    public Response test1(@HeaderParam("Accept") String header) {
        System.out.println(header);
        return Response.ok("Version 1", "application/vnd.test").build();
    }
}
通过请求

接受:应用程序/vnd.test;版本=2,应用程序/vnd.test;版本=1;q=0.1

这会打印出来

应用/vnd.test;版本=2,应用程序/vnd.test;版本=1;q=0.1


然后您可以手动处理它。这就是您要寻找的吗?

对于Jersey framework,HTTP请求的Accept头声明了最可接受的内容。如果资源类能够生成多个MIME媒体类型,则选择的资源方法将对应于客户端声明的最可接受的媒体类型。 在您的情况下,如果accept标头为

Accept: application/vnd.mycompany.mytype;version=2
然后将调用方法test1()

如果是

Accept: application/vnd.mycompany.mytype;q=0.9 version=2, application/vnd.mycompany.mytype;version=1
后者将被称为

在同一@products声明中可以声明多个媒体类型,例如:

@GET
@Produces({"application/vnd.mycompany.mytype; version=2", "application/vnd.mycompany.mytype; version=1"})
public Response test() {
    return Response.ok("").build();
}
如果两种媒体类型中的任何一种都可以接受,则将调用test(9)方法。如果两种媒体类型都可以接受,则将调用第一种媒体类型


希望有帮助!

JAX-RS规范没有明确说明忽略Accept头参数的任何内容。但唯一明确定义处理的参数是质量(q)。这是一个可能需要改进的领域,因为它似乎导致了歧义(或彻底的错误)在Jersey实现中。当前版本的Jersey(1.17)在将传入请求与资源方法匹配时未考虑Accept标头参数,这就是为什么会出现错误:

严重:正在生成媒体类型冲突。资源方法

关于资源:

@GET
@Produces("application/vnd.test;version=1")
public Response test1() {
    return Response.ok("Version 1", "application/vnd.test").build();
}

@GET
@Produces("application/vnd.test;version=2")
public Response test2() {
    return Response.ok("Version 2", "application/vnd.test").build();
}
@Path("/content/version")
public class ContentVersionResource {

    @GET
    @Produces("application/vnd.test;version=1")
    public Response test1() {
        return Response.ok("Version 1", "application/vnd.test").build();
    }

    @GET
    @Produces("application/vnd.test;version=2")
    public Response test2() {
        return Response.ok("Version 2", "application/vnd.test").build();
    }
}
Jersey似乎根据Accept标头“type/subtype”执行“唯一性”检查,完全忽略任何参数。这可以通过在“matching”资源方法上使用不同的标头对进行测试来确认:

Resource 1 Resource 2 ---------------------------------------- text/html;q=0.4 text/html;q=0.8 text/html text/html;q=0.2 text/html text/html;qs=1.4 text/html;qs=1.4 text/html;qs=1.8 text/html;level=1 text/html;level=2 text/html;foo=bleh text/html;bar=23 与以下Accept标头成功匹配:

接受:应用程序/vnd.test;版本=1;q=0.3,应用程序/vnd.test;版本=2;q=0.5
答复:第2版

这是:

接受:应用程序/vnd.test;版本=1;q=0.5,应用程序/vnd.test;版本=2;q=0.3
答复:第1版


你可以下载并使用它进行测试。Git、Maven和JBoss 7.x必需

我已经知道JAX-RS不支持accept参数。我想要的是关于如何正确处理这些参数的建议。哦,我明白了。我把
媒体范围
accept参数
搞混了。实际上,这不是我想要的。有了这个解决方案在上,我仍然必须手动将所有请求路由到每个版本特定的方法。我还必须处理媒体类型冲突异常。现在这很有趣。阅读注释,我发现JAX-RS在表达这一点上没有问题。相反,这是Jersey实现的问题,至少还有一个实现可以解决n去做。(我希望知道我使用的框架CXF是否有问题,但我现在正在路上,无法测试…)关于您选择如何实现的任何更新。我也需要这样做,我很想知道所选答案是否对您有效。我不久前尝试过RESTEasy…但显然,我错过了一些要点。感谢您的回答。我能够根据版本匹配端点。感谢您的回答。如果没有,我如何默认为版本在标题中指定了。
@Path("/content/version")
public class ContentVersionResource {

    @GET
    @Produces("application/vnd.test;version=1")
    public Response test1() {
        return Response.ok("Version 1", "application/vnd.test").build();
    }

    @GET
    @Produces("application/vnd.test;version=2")
    public Response test2() {
        return Response.ok("Version 2", "application/vnd.test").build();
    }
}