Rest 休息球衣得到放冲突
我使用的是jersey版本1.17.1+tomcat 7.0.39+Spring MVC 3.2.1 问题是,当我扩展GET处理程序的@Path时,我无法理解为什么PUT处理程序停止工作 我的Spring MVC控制器中的以下配置/匹配工作正常:Rest 休息球衣得到放冲突,rest,spring-mvc,jersey,Rest,Spring Mvc,Jersey,我使用的是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! [...] 请求,但也包括表格的请求 /anyI
@GET
@Path("/{id}") // <--- WORKS!
[...]
@PUT
@Path("/{id}") // <--- WORKS!
[...]
请求,但也包括表格的请求
/anyId/
/anyId/anyfile.ext
然后不接触使匹配停止工作:
@GET
@Path("/{id:.*[^/]}{fileName:.*}") // <--- WORKS!
[...]
@PUT
@Path("/{id}") // <--- Not working any longer:
// "405 Method Not Allowed"
[...]
@GET
@路径(“/{id:.[^/]}{fileName:..*}”)//A 405通常意味着找不到合适的方法。仅凭您提供的小片段很难说,但您需要确保在PUT
方法上有适当的@Consumes
注释
您还可以尝试将@Path
更改为类似@Path(“{id:[^/]+}/{fileName:.+}”)
,看看是否有帮助。如果没有,请提供完整的控制器。405表示没有与该资源请求中的方法匹配的方法。这表明某个(或几个)东西有一个匹配的@Path
注释,但是(Java)方法没有正确的方法。(如果可以的话,在查看正在发生的事情时打开详细调试;这很有帮助。但在完成后关闭它;它将过于详细,无法正常打开。)
现在,它有助于理解@Path
被映射到一个与请求中的路径匹配的正则表达式,如果您没有另外指定,那么路径模板部分({id}
)将被正则表达式[^?/;]+
有效匹配,即。,尽可能多的字符,而不进入路径的下一部分、查询部分或任何矩阵参数。(不知道矩阵参数是什么?您可能不想知道!)
为了匹配所有这些表格:
/anyId
/anyId/
/anyId/anyfile.ext
这是可行的,但很冗长
相反,返回一个表示资源并定义了操作的对象可能更容易:
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实现)做这件事,它工作得相当好。我非常确定控制器在这里并不重要。我故意跳过了。我已经使用远程调试对其进行了验证。当我使用更简单的映射时,两个方法(@Path)都可以正常工作-两个控制器都按预期输入。但是用正则表达式扩展GET@Path就足够了,然后PUT处理程序停止工作,服务器返回“Method not allowed”(扩展的GET匹配工作正常)。Donald,正如我在文章中所描述的,我的GET处理程序始终工作:在扩展它之前和之后,以便它能够处理以文件名结尾的请求。问题是,当我扩展GET@Path时,PUT处理程序停止匹配。我试图将我的GET处理程序分成两个独立的处理程序。再一次,在那之后,PUT handler停止了工作。。。
@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) { … }
}
@Path("{id}")
public MyResource getNoPath(@PathParam("id") String id) {
return new MyResource(id, null);
}
@Path("{id}/{file:.*}")
public MyResource getNoPath(@PathParam("id") String id, @PathParam("file") String file) {
return new MyResource(id, file);
}