Spring MVC @RestController 和重定向

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29085295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:27:42  来源:igfitidea点击:

Spring MVC @RestController and redirect

springrestspring-mvcredirecthttp-redirect

提问by alexanoid

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.

我有一个用 Spring MVC @RestController 实现的 REST 端点。有时,取决于我的控制器中的输入参数,我需要在客户端上发送 http 重定向。

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

Spring MVC @RestController 是否可以使用,如果可以,请举例说明?

回答by Neil McGuigan

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

HttpServletResponse向您的处理程序方法添加一个参数,然后调用response.sendRedirect("some-url");

Something like:

就像是:

@RestController
public class FooController {

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

}

回答by Arne Burmeister

To avoid any direct dependency on HttpServletRequestor HttpServletResponseI suggest a "pure Spring" implementation returning a ResponseEntitylike this:

为了避免任何直接依赖HttpServletRequestHttpServletResponse我建议使用“纯 Spring”实现返回这样的ResponseEntity

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.

如果您的方法总是返回重定向,请使用ResponseEntity<Void>,否则通常以泛型类型返回。

回答by DhatGuy

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:

遇到这个问题,很惊讶没有人提到 RedirectView。我刚刚测试了它,你可以用干净的 100% 弹簧方式解决这个问题:

@RestController
public class FooController {

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

回答by Eric Wang

redirectmeans http code 302, which means Foundin springMVC.

redirect表示 http 代码302,也就是Found在 springMVC 中。

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

这是一个 util 方法,它可以放在某种类型中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 301instead, which means moved permanently.

但有时可能想要返回 http 代码301,这意味着moved permanently.

In that case, here is the util method:

在这种情况下,这是 util 方法:

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

回答by árpád Magosányi

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

@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);

回答by skuarch

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

如果你@RestController 返回一个字符串,你可以使用这样的东西

return "redirect:/other/controller/";

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

而这种重定向只针对GET请求,如果你想使用其他类型的请求,请使用 HttpServletResponse