Search code examples
springspring-restcontroller

Adding @ModelAttribute results in 400 (Bad Request) in Delete Request


I can submit a delete request fine with the following:

@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Result> deleteTest(@PathVariable String id) {
    return new ResponseEntity<>(Result.Success("Hi " + id + "!!!", null), HttpStatus.OK);
}

However, when I add an @ModelAttribute variable, I get 400 (Bad Request) as the http response code:

@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Result> deleteTest(@PathVariable String id, @ModelAttribute("authUser") User authUser) {
    return new ResponseEntity<>(Result.Success("Hi " + id + "!!!", null), HttpStatus.OK);
}

This @ModelAttribute is working fine with a put request handler I have in my @RestController but not in this delete request.

Here's the @ModelAttribute code:

@ModelAttribute("authUser")
public User authUser(@AuthenticationPrincipal SpringAuthUser springAuthUser) throws Exception {
    User user = ConstantsHome.userprofileMgr.getUserByUserId(springAuthUser.getUsername(), true, true);
    user.updateRights(null);
    request.getSession().setAttribute(ConstantsHome.USEROBJECT_KEY, user);
    return user;
}

Why would adding @ModelAttribute cause a delete request to return a 400 (Bad Request) http response?

I'm using spring-web-4.1.4 & spring-security-4.0.3


Solution

  • I digged a little and found that specifying a @PathVariable of "id" somehow attaches it to the @ModelAttribute variable (as a Long(!) instead of a String as I specified). I then came across this post that lead me to different ways to resolve the issue :

    Values of @PathVariable and @ModelAttribute overlapping.

    Ended up with this as a method declaration (replaced "id" with "userId"):

    @RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
    public ResponseEntity<Result> deleteUser(@PathVariable String userId,
                                             @ModelAttribute("authUser") User authUser) {
        ...
    }
    

    Hopefully this will help someone else quickly that might run into this issue instead of spending a day trying to figure it out...