泽西队在PUT上回归405

时间:2015-07-15 20:40:31

标签: java rest jersey

我遇到使用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。

2 个答案:

答案 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),这不应该发生,所以要么我的理论是假的,要么是泽西岛的一个错误。