【发布时间】:2015-10-05 02:19:50
【问题描述】:
我在使用嵌入式 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"
这是 curl 的基本响应。它不会列出 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 会根据第一个请求进行自我配置。如果 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,所以它一定很简单。事实上,我希望我能偶然发现写这篇文章的频率如此之高,但这次不会。
谢谢,韦斯。
【问题讨论】: