spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.55k stars 38.12k forks source link

@ResponseStatus annotation is ignored in an @Controller redirect (RedirectView) [SPR-6144] #10812

Closed spring-projects-issues closed 9 years ago

spring-projects-issues commented 15 years ago

Flyin Wolf opened SPR-6144 and commented

In a controller that returns a RedirectView or "redirect:someViewName" the @ResponseStatus annotation is ignored. RedirectView always returns a hard coded 303 (or 302) in spite of the given value in the @ResponseStatus annotation.

i.e. @

@Controller
@RequestMapping(value = "/games")
public class GameController {
...
  @RequestMapping(method = RequestMethod.POST)
  @ResponseStatus( value=HttpStatus.CREATED ) 
  public View createGame( @ModelAttribute("gameForm") GameForm gameForm ) {
    return getRedirectViewForCreate(); // "redirect:somelocation.html";
  }
...

Got:

$ curl -i -d name="game1" http://localhost:8080/rook2/rest/games/form.html
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/rest/games/1.html
Content-Language: en-US
Content-Length: 0
Date: Wed, 23 Sep 2009 04:03:15 GMT

Expected:

$ curl -i -d name="game2" http://localhost:8080/rook2/rest/games/form.html
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Location: /rook2/rest/games/2.html
Content-Language: en-US
Content-Length: 0
Date: Wed, 23 Sep 2009 02:44:55 GMT

I notice this could also maybe solve - http://jira.springframework.org/browse/SPR-5468

RedirectView.sendRedirect(...) could look something like this:

protected void sendRedirect(
            HttpServletRequest request, HttpServletResponse response, String targetUrl, boolean http10Compatible)
            throws IOException {

        if (http10Compatible) {
            // Always send status code 302.
            response.sendRedirect(response.encodeRedirectURL(targetUrl));
        }
        else if ( getHttpStatusCode() == null ) {
            // Correct HTTP status code is 303, in particular for POST requests.
            response.setStatus(303);
            response.setHeader("Location", response.encodeRedirectURL(targetUrl));
        } else {
            if ( !isHttpStatusCodePreviouslySet() ) { // whatever... main thing is do NOT set it if the @ResponseStatus sets the status code
                response.setStatus( getHttpStatusCode() );
            }
            response.setHeader("Location", response.encodeRedirectURL(targetUrl));
        }

    }

Extending RedirectView works for me, but of course "redirect:something.html" would not work without also changing the class instantiated when "redirect:" is used. But again, as is, it does give unexpected behaviour.


Affects: 3.0 M4

Issue Links:

Referenced from: commits https://github.com/spring-projects/spring-framework/commit/5b12503c477a99eaddb25710a8b3a88d00e1c552

spring-projects-issues commented 15 years ago

Flyin Wolf commented

http://jira.springframework.org/browse/SPR-6008 (resolved) was also a problem where the annotation was ignored.

spring-projects-issues commented 15 years ago

Arjen Poutsma commented

Added formatting