我遇到使用embeded Jersey设置和测试REST调用的问题。我一直在PUT请求上获得405。
以下是一些请求。我使用了除一个以外的所有查询参数,它有一个默认值。这些URL由我的测试客户端中的Jersey WebResource生成。
curl -i -X PUT "http://localhost:8080/hash/wes?hiddenDirs=false&hiddenFiles=false&id=3edf4867-1211-4ae7-a251-2af28ffac5a2&recursive=false&rehash=false&hashType=SHA1"
curl -i -X PUT "http://localhost:8080/hash/wes?hiddenDirs=false&hiddenFiles=false&id=3edf4867-1211-4ae7-a251-2af28ffac5a2&recursive=false&rehash=false"
以下是卷曲的基本反应。它不列出PUT,但使用OPTIONS请求会列出PUT。
HTTP/1.1 405 Method Not Allowed
Allow: GET,OPTIONS,HEAD
Content-Length: 0
Server: Jetty(8.1.17.v20150415)
这是控制器类。我使用了很多常量,因此客户端和服务使用相同的值。您可以在下面的OPTIONS输出中看到翻译。
@Path(Constants.HASH_PATH) // "/hash"
public class HashController {
这是我希望处理呼叫的方法。
@PUT
@Path(Constants.PATH_REST) // "{path : .*}" - I want this to accept directory paths.
@Produces(MediaType.APPLICATION_JSON)
public Response hash(@PathParam("path") String path, @QueryParam(Constants.ID_PARAM) String id,
@QueryParam(Constants.HASH_TYPE_PARAM) @DefaultValue(HashProcessor.DEFAULT_HASH_TYPE) String hashType,
@QueryParam(Constants.HIDDEN_DIRS_PARAM) @DefaultValue("false") boolean hiddenDirectories,
@QueryParam(Constants.HIDDEN_FILES_PARAM) @DefaultValue("false") boolean hiddenFiles,
@QueryParam(Constants.RECURSIVE_PARAM) @DefaultValue("false") boolean recursive,
@QueryParam(Constants.REHASH_PARAM) @DefaultValue("false") boolean reHashExisting) {
Response ret = null;
我使用OPTIONS请求获取控制器的详细信息,并查看PUT定义。
curl -i -X OPTIONS http://localhost.corp.int:8080/hash > fileSync-hash.xml
这是输出。
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 1.19 02/11/2015 03:25 AM" />
<grammars>
<include href="http://localhost:8080/application.wadl/xsd0.xsd">
<doc title="Generated" xml:lang="en" />
</include>
</grammars>
<resources base="http://localhost:8080/">
<resource path="hash">
<resource path="{path : .*}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="path" style="template" type="xs:string" />
<method id="hash" name="PUT">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="id" style="query" type="xs:string" />
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="hashType" style="query" type="xs:string" default="SHA1" />
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="hiddenDirs" style="query" type="xs:boolean" default="false" />
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="hiddenFiles" style="query" type="xs:boolean" default="false" />
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="recursive" style="query" type="xs:boolean" default="false" />
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="rehash" style="query" type="xs:boolean" default="false" />
</request>
<response>
<representation mediaType="application/json" />
</response>
</method>
</resource>
<resource path="{id : [\w\-]*}">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="id" style="template" type="xs:string" />
<method id="status" name="GET">
<response>
<representation mediaType="application/json" />
</response>
</method>
</resource>
</resource>
</resources>
</application>
以下是来电的服务器输出。
2015-07-15 15:52:36 DEBUG nio:843 - created SCEP@6319a8b7{l(/10.20.67.195:56641)<->r(/10.20.67.71:8080),s=0,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=0}-{AsyncHttpConnection@2993b935,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-14,l=0,c=0},r=0}
2015-07-15 15:52:36 DEBUG HttpParser:281 - filled 271/271
2015-07-15 15:52:36 DEBUG Server:365 - REQUEST /hash/wes on AsyncHttpConnection@2993b935,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-5,l=3,c=0},r=1
2015-07-15 15:52:36 DEBUG ContextHandler:942 - scope null||/hash/wes @ o.e.j.s.ServletContextHandler{/,null}
2015-07-15 15:52:36 DEBUG ContextHandler:1014 - context=||/hash/wes @ o.e.j.s.ServletContextHandler{/,null}
2015-07-15 15:52:36 DEBUG ServletHandler:415 - servlet ||/hash/wes -> com.sun.jersey.spi.container.servlet.ServletContainer-68e816f5
2015-07-15 15:52:36 DEBUG ServletHandler:477 - chain=null
2015-07-15 15:52:36 DEBUG Server:367 - RESPONSE /hash/wes 405 handled=true
2015-07-15 15:52:36 DEBUG AsyncHttpConnection:211 - Enabled read interest SCEP@6319a8b7{l(/10.20.67.195:56641)<->r(/10.20.67.71:8080),s=1,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=0r}-{AsyncHttpConnection@2993b935,g=HttpGenerator{s=4,h=0,b=-1,c=-1},p=HttpParser{s=0,l=3,c=0},r=1}
2015-07-15 15:52:36 DEBUG ChannelEndPoint:118 - ishut SCEP@6319a8b7{l(/10.20.67.195:56641)<->r(/10.20.67.71:8080),s=1,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=0r}-{AsyncHttpConnection@2993b935,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-14,l=0,c=-3},r=1}
2015-07-15 15:52:36 DEBUG HttpParser:281 - filled -1/0
2015-07-15 15:52:36 DEBUG AsyncHttpConnection:145 - Disabled read interest while writing response SCEP@6319a8b7{l(/10.20.67.195:56641)<->r(/10.20.67.71:8080),s=1,open=true,ishut=true,oshut=false,rb=false,wb=false,w=true,i=0r}-{AsyncHttpConnection@2993b935,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=0,l=0,c=-3},r=1}
2015-07-15 15:52:36 DEBUG ChannelEndPoint:209 - close SCEP@6319a8b7{l(/10.20.67.195:56641)<->r(/10.20.67.71:8080),s=1,open=true,ishut=true,oshut=false,rb=false,wb=false,w=true,i=0!}-{AsyncHttpConnection@2993b935,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=0,l=0,c=-3},r=1}
2015-07-15 15:52:36 DEBUG nio:852 - destroyEndPoint SCEP@6319a8b7{l(null)<->r(0.0.0.0/0.0.0.0:8080),s=0,open=false,ishut=true,oshut=true,rb=false,wb=false,w=true,i=0!}-{AsyncHttpConnection@2993b935,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=0,l=0,c=-3},r=1}
我可以对同一个控制器进行GET调用。由于PUT失败,它会按预期返回404,但是我的代码返回404而不是Jersey。
curl -i -X GET "http://dsk-107312:8080/hash/3edf4867-1211-4ae7-a251-2af28ffac5a2"
这是一些服务器输出,因为Jersey会根据第一个请求进行自我配置。如果泽西没有发现控制器,那么GET也会失败。
Jul 15, 2015 3:46:13 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.wstrater.server.fileSync.server.handlers
Jul 15, 2015 3:46:13 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.wstrater.server.fileSync.server.handlers.FileController
class com.wstrater.server.fileSync.server.handlers.HelloWorldController
class com.wstrater.server.fileSync.server.handlers.HashController
class com.wstrater.server.fileSync.server.handlers.DirectoryController
Jul 15, 2015 3:46:13 PM com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
Jul 15, 2015 3:46:14 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.19 02/11/2015 03:25 AM'
我在其他控制器中成功使用了PUT,所以它必须简单。事实上,我希望我会偶然发现这篇文章经常发生,但不是这次。
谢谢,Wes。
答案 0 :(得分:1)
在我看来,Jersey(2.19)在运行你的路由示例时有一个错误。 我试过这个控制器模仿你的例子:
@Path("/hash")
public class HashController
{
@PUT @Produces("text/plain")
@Path("{path: .+}")
public String m1(@PathParam("path") String path) {
return "m1 called with path " + path;
}
@GET @Produces("text/plain")
@Path("{path: [\\w\\-]+}")
public String m2(@PathParam("path") String path) {
return "m2 called with path " + path;
}
}
运行CURL时,我得到与报告相同的行为:GET请求被罚款,PUT返回405.
但是当你在两种方法上使用相同的路径模板时(即在两种方法上都使用@Path("{path: .+}")
或@Path("{path: [\\w\\-]+}")
),一切正常。
答案 1 :(得分:0)
路径&#34; / hash / wes&#34;匹配你的两个路径方案&#34; / hash / {path:。}&#34;和&#34; / hash / {id:[\ w - ] }&#34;似乎球衣选择了第二种控制器方法 - 它支持GET但不支持PUT。
编辑:根据spec(3.7.2),这不应该发生,所以要么我的理论是假的,要么是泽西岛的一个错误。