Spring引导HandlerInterceptor负载均衡

时间:2016-09-02 13:56:16

标签: java spring spring-mvc spring-boot

我正在使用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)之前,有没有办法拦截请求?

1 个答案:

答案 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);
  }
}

为避免重复,您可能希望拥有一个您可以从拦截器和错误处理程序调用的公共类。