简体   繁体   中英

Jersey HTTP Delete,Put Response Status: 405 (Method Not Allowed)

Day 1: Added below rest endpoint for delete operation.

@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
}
}

I was able to invoke DELETE endpoint using postman with below request:

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

Day 2: Added below rest endpoint for the update operation in the same resource.

@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
}
}

After adding this new endpoint, I am able to invoke PUT using postman with below request:

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

But when I try to invoke Delete endpoint it is giving me 405 (Method Not Allowed) error. If I comment my new Put method, then the Delete method works fine. Also, if I replace Path for Put method to "/{identifier}/{identifier_value}/employee" then both Delete and Put method works fine.

I am using Jersey 1.19 with tomcat. Can someone help me with this?

Your Paths are in conflict with each other. Let me try to explain:

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

That means when we evaluate the path from left to right, we can either have {identifier} which is anything or "empid" which is a fixed string

Jersey always tries to find the "most perfect" match for a REST endpoint. It does so by evaluating the path from left to right. Fixed strings always take precedence before random variables!

Basically that means when you want to call a DELETE, you cannot have the value "empid" for the variable "{identifier}" because then you are already out-of-scope

So the DELETE call to

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

will not work as Jersey had to make a decision whether "empid" in the request matches "{identifier}" (DELETE) or "empid" (PUT). And as i tried to explain above, fixed strings take a higher priority. In contrast, any other DELETE request where

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

and

{identifier} != "empid"

works.

Possible solution:

make your rest endpoints resource-oriented

DELETE: /employee/{employee-id}

PUT: /employee/{employee-id}

Notice how the endpoints are identical, since other than the ID in most systems, no information is needed to identify an entity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM