REST Jersey GET PUT冲突

时间:2013-07-23 13:47:05

标签: rest spring-mvc jersey

我使用的是泽西版1.17.1 + tomcat 7.0.39 + Spring MVC 3.2.1。

问题是当我扩展GET处理程序的@Path时,我无法弄清楚为什么我的PUT处理程序停止工作?

我的Spring MVC控制器中的以下配置/匹配按预期工作:

 @GET
 @Path("/{id}")   // <--- WORKS!
 [...]

 @PUT
 @Path("/{id}")   // <--- WORKS!  
 [...]      

每当我扩展GET 处理程序的匹配时,才能够 处理不仅

/anyId    

请求以及表单的请求

/anyId/
/anyId/anyfile.ext

然后没有触及 PUT匹配停止工作

 @GET
 @Path("/{id:.*[^/]}{fileName:.*}")   // <--- WORKS!
 [...]

 @PUT
 @Path("/{id}")                       // <--- Not working any longer: 
                                      //      "405 Method Not Allowed" 
 [...]

将GET路径的匹配更改为上述PUT请求后,获取“405 Method Not Allowed”状态代码。

当我像第一种情况一样简化GET路径时,PUT处理程序再次开始工作。

这是泽西岛的错误还是什么?

2 个答案:

答案 0 :(得分:1)

405表示没有方法匹配该资源请求中的方法。这表明某些东西(或几个东西)有一个匹配的@Path注释,但该(Java)方法没有正确的方法。 (如果可以的话,在查看正在进行的操作时打开详细的调试;它会有所帮助。当你完成时关闭它;它通常会留下太冗长。)

现在,了解@Path映射到与请求中的路径匹配的正则表达式是有帮助的,如果没有另外指定,则有助于理解路径模板部分{{1} })与正则表达式{id}有效匹配,即尽可能多的字符,而不进入路径的下一部分,查询部分或任何矩阵参数。 (不知道矩阵参数是什么?你可能想要知道!)

为了匹配所有这些形式:

/anyId    
/anyId/
/anyId/anyfile.ext

最好每个HTTP方法使用两个Java方法:

[^?/;]+

这很有效,但它很冗长。


可能更容易返回一个代表资源的对象,并在其上定义了操作:

@GET @Path("{id}")
…
@GET @Path("{id}/{file:.*}")
…
class MyResource {
    private String id, file;
    MyResource(String id, String file) {
        this.id = id; this.file = file;
    }
    // Can't remember if @Path is needed on these; "/" is a special case IIRC
    @GET @Path("/") @Produces(…)
    public String get() { … }
    @PUT @Path("/") @Produces(…) @Consumes(…)
    public String put(String message) { … }
}

就像那样,您将从提供正确方法的代码中拆分解析路径的代码。我使用CXF(另一个JAX-RS实现)来做这件事,它运行得相当好。

答案 1 :(得分:0)

<405> A 405通常意味着找不到合适的方法。很难说只提供了您提供的小片段,但您需要确保在@Consumes方法上有适当的PUT注释。

您也可以尝试将@Path更改为@Path("{id: [^/]+}/{fileName: .+}")之类的内容,看看是否有帮助。如果没有,请提供完整的控制器。