繁体   English   中英

Spring MVC @RestController并重定向

[英]Spring MVC @RestController and redirect

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

Spring MVC @RestController是否可以,如果可以,请举个例子吗?

HttpServletResponse参数添加到您的Handler方法中,然后调用response.sendRedirect("some-url");

就像是:

@RestController
public class FooController {

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

}

为了避免直接依赖于HttpServletRequestHttpServletResponse我建议一个“纯Spring”实现,返回一个ResponseEntity,如下所示:

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

如果您的方法始终返回重定向,请使用ResponseEntity<Void> ,否则通常以泛型类型返回的任何内容。

遇到了这个问题,很惊讶没有人提到RedirectView。 我刚刚对其进行了测试,您可以使用以下方法以干净的100%弹簧方式解决此问题:

@RestController
public class FooController {

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

redirect表示http代码302 ,表示在springMVC中Found

这是一个util方法,可以将其放在某种BaseController

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

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

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

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

由于通常需要在非直截了当的路径中进行重定向,因此我认为抛出异常并在以后进行处理是我最喜欢的解决方案。

使用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
    );
  }
}

在我的情况下的异常类:

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

我这样触发它:

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

如果您@RestController返回一个字符串 ,则可以使用类似以下的内容

return "redirect:/other/controller/";

并且这种重定向仅适用于GET请求,如果您想使用其他类型的请求,请使用HttpServletResponse

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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