【问题标题】:Jersey HTTP Delete,Put Response Status: 405 (Method Not Allowed)Jersey HTTP Delete,Put 响应状态:405(不允许的方法)
【发布时间】:2020-12-15 20:11:36
【问题描述】:

第 1 天:在剩余端点下方添加删除操作。

@Path("/company/v1/department")
@Component
public class ManageResource {

@DELETE
@Path("/{identifier}/{identifier_value}/employee")
public void delete(@PathParam("identifier") String identifier,
                   @PathParam("identifier_value") final String identifierValue,
                   @QueryParam("age") final String age) {

 //delete operation
}
}

我能够通过以下请求使用邮递员调用 DELETE 端点:

DELETE: http://localhost:8080/company/v1/department/name/baner/employee?age=50

第 2 天:为同一资源中的更新操作添加了下面的休息端点。

@Path("/company/v1/department")
@Component
public class ManageResource {

@DELETE
@Path("/{identifier}/{identifier_value}/employee")
public void delete(@PathParam("identifier") String identifier,
                   @PathParam("identifier_value") final String identifierValue,
                   @QueryParam("age") final String age) {
   
//delete operation
}

@PUT
@Path("/empid/{value}/employee")
@Consumes(MediaType.APPLICATION_JSON)
public void update(@PathParam("value") final String identifierValue,
                   @RequestBody final EmployeeUpdateRequest request) {
   
//update operation
}
}

添加此新端点后,我可以使用邮递员通过以下请求调用 PUT:

PUT: http://localhost:8080/company/v1/department/empid/epid-123/employee
{
//Json request body
}

但是当我尝试调用 Delete 端点时,它给了我 405(不允许的方法)错误。 如果我评论我的新 Put 方法,则 Delete 方法可以正常工作。 另外,如果我将 Put 方法的 Path 替换为“/{identifier}/{identifier_value}/employee”,那么 Delete 和 Put 方法都可以正常工作。

我正在使用带有 tomcat 的 Jersey 1.19。 有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: java rest jersey http-status-code-405 http-method


    【解决方案1】:

    您的路径相互冲突。让我试着解释一下:

    DELETE = /{identifier}/{identifier_value}/employee 
    PUT = /empid/{value}/employee
    

    这意味着当我们评估从左到右的路径时,我们可以有 {identifier} 是任何东西或 "empid" 是一个固定字符串

    Jersey 总是尝试为 REST 端点找到“最完美”的匹配项。它通过评估从左到右的路径来做到这一点。 固定字符串总是优先于随机变量!

    基本上这意味着当你想调用 DELETE 时,你不能为变量“{identifier}”设置值“empid”,因为这样你就已经超出了范围

    所以 DELETE 调用

    http://localhost:8080/company/v1/department/empid/empid-123/employee
    

    将不起作用,因为 Jersey 必须决定请求中的“empid”是否匹配“{identifier}”(DELETE)或“empid”(PUT)。正如我在上面试图解释的那样,固定字符串具有更高的优先级。 相反,任何其他 DELETE 请求在

    http://localhost:8080/company/v1/department/{identifier}/empid-123/employee
    

    {identifier} != "empid"
    

    有效。

    可能的解决方案:

    让你的休息端点面向资源

    删除: /employee/{employee-id}

    放置: /employee/{employee-id}

    注意端点是如何相同的,因为除了大多数系统中的 ID 之外,不需要任何信息来识别实体。

    【讨论】:

    • 首先感谢您的回答。我了解 URL 优先级如何在其中发挥作用,但我不明白为什么也不考虑 HTTP 方法。两种请求方法完全不同,因此不应混淆选择适当的资源。也许我错了,但寻找正确资源的逻辑对我来说似乎是错误的。如果我有 2 个带有上述路径的 DELETE 资源(我的意思是如果我将 PUT 替换为 DELETE),那么当然很难解析路径,但这里不是这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 2019-10-28
    • 2019-03-05
    • 2014-10-04
    • 2016-11-04
    • 2017-06-15
    • 2021-06-04
    相关资源
    最近更新 更多