Spring MVC @RestController and redirect

SpringRestSpring MvcRedirectHttp Redirect

Spring Problem Overview


I have a REST endpoint implemented with Spring MVC @RestController. Sometime, depends on input parameters in my controller I need to send http redirect on client.

Is it possible with Spring MVC @RestController and if so, could you please show an example ?

Spring Solutions


Solution 1 - Spring

Add an HttpServletResponse parameter to your Handler Method then call response.sendRedirect("some-url");

Something like:

@RestController
public class FooController {

  @RequestMapping("/foo")
  void handleFoo(HttpServletResponse response) throws IOException {
    response.sendRedirect("some-url");
  }

}

Solution 2 - Spring

To avoid any direct dependency on HttpServletRequest or HttpServletResponse I suggest a "pure Spring" implementation returning a ResponseEntity like this:

HttpHeaders headers = new HttpHeaders();
headers.setLocation(URI.create(newUrl));
return new ResponseEntity<>(headers, HttpStatus.MOVED_PERMANENTLY);

If your method always returns a redirect, use ResponseEntity<Void>, otherwise whatever is returned normally as generic type.

Solution 3 - Spring

Came across this question and was surprised that no-one mentioned RedirectView. I have just tested it, and you can solve this in a clean 100% spring way with:

@RestController
public class FooController {

    @RequestMapping("/foo")
    public RedirectView handleFoo() {
        return new RedirectView("some-url");
    }
}

Solution 4 - Spring

redirect means http code 302, which means Found in springMVC.

Here is an util method, which could be placed in some kind of BaseController:

protected ResponseEntity found(HttpServletResponse response, String url) throws IOException { // 302, found, redirect,
    response.sendRedirect(url);
    return null;
}

But sometimes might want to return http code 301 instead, which means moved permanently.

In that case, here is the util method:

protected ResponseEntity movedPermanently(HttpServletResponse response, String url) { // 301, moved permanently,
    return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY).header(HttpHeaders.LOCATION, url).build();
}

Solution 5 - Spring

As the redirections are usually needed in a not-straightforward path, I think throwing an exception and handling it later is my favourite solution.

Using a ControllerAdvice

@ControllerAdvice
public class RestResponseEntityExceptionHandler
    extends ResponseEntityExceptionHandler {

  @ExceptionHandler(value = {
      NotLoggedInException.class
  })
  protected ResponseEntity<Object> handleNotLoggedIn(
      final NotLoggedInException ex, final WebRequest request
  ) {
    final String bodyOfResponse = ex.getMessage();

    final HttpHeaders headers = new HttpHeaders();
    headers.add("Location", ex.getRedirectUri());
    return handleExceptionInternal(
        ex, bodyOfResponse,
        headers, HttpStatus.FOUND, request
    );
  }
}

The exception class in my case:

@Getter
public class NotLoggedInException extends RuntimeException {

  private static final long serialVersionUID = -4900004519786666447L;

  String redirectUri;

  public NotLoggedInException(final String message, final String uri) {
    super(message);
    redirectUri = uri;
  }
}

And I trigger it like this:

if (null == remoteUser)
  throw new NotLoggedInException("please log in", LOGIN_URL);

Solution 6 - Spring

if you @RestController returns an String you can use something like this

return "redirect:/other/controller/";

and this kind of redirect is only for GET request, if you want to use other type of request use HttpServletResponse

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionalexanoidView Question on Stackoverflow
Solution 1 - SpringNeil McGuiganView Answer on Stackoverflow
Solution 2 - SpringArne BurmeisterView Answer on Stackoverflow
Solution 3 - SpringDhatGuyView Answer on Stackoverflow
Solution 4 - SpringEricView Answer on Stackoverflow
Solution 5 - SpringÁrpád MagosányiView Answer on Stackoverflow
Solution 6 - SpringskuarchView Answer on Stackoverflow