我正在使用Spring Boot实现(某种)负载平衡HandlerInterceptor
。
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
if (shouldUseServer1(uri)) {
response.sendRedirect(server1Uri);
} else {
response.sendRedirect(server2Uri);
}
}
这个想法是,基于url,我们要么重定向到一个服务,要么重定向到另一个服务。该应用程序没有任何明确的RequestMapping
(尚未)。
现在问题是,当调用拦截器时,请求被重定向到默认的Spring错误处理程序。因此,HttpServletRequest
中存储的URI将替换为/error
(实际上拒绝访问原始URI)。
在将请求重新路由到错误处理程序(或获取原始uri)之前,有没有办法拦截请求?
答案 0 :(得分:1)
修改强>
由于Spring MVC处理没有映射的请求的方式,您需要一个过滤器:
@Component
public class CustomFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
request.getSession().setAttribute("ORIGINAL_REQUEST_URI", request.getRequestURI());
chain.doFilter(request, response);
// alternatively, ignore the last 2 lines
// and just do your redirects from here
// and don't continue the filter chain
}
@Override
public void destroy() {}
@Override
public void init(FilterConfig arg0) throws ServletException {}
}
否则,如果您不依赖会话you'll need to make the DispatcherServlet
throw an exception in case no handler mapping is found,然后从@ControllerAdvice
错误处理程序发送重定向:
@ControllerAdvice
class NoHandlerFoundExceptionExceptionHandler {
@ExceptionHandler(value = NoHandlerFoundException.class)
public ModelAndView
defaultErrorHandler(HttpServletRequest req, NoHandlerFoundException e) throws Exception {
String uri = // resolve the URI
return new ModelAndView("redirect:" + uri);
}
}
为避免重复,您可能希望拥有一个您可以从拦截器和错误处理程序调用的公共类。