Java Spring boot Handler拦截器负载平衡
我正在使用Spring Boot实现(某种)负载平衡Java Spring boot Handler拦截器负载平衡,java,spring,spring-mvc,spring-boot,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)) { resp
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
s
现在的问题是,当调用拦截器时,请求被重定向到默认的Spring错误处理程序。因此,存储在HttpServletRequest
中的URI被替换为/error
(有效地拒绝对原始URI的访问)
在请求被重新路由到错误处理程序(或获取原始uri)之前,是否有办法拦截请求?编辑:
由于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 {}
}
否则,如果您不希望依赖会话,然后从@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);
}
}
为了避免重复,您可能希望有一个公共类,您将从拦截器和错误处理程序调用该类 重定向工作正常。问题是我需要请求中的原始URI。如果原始URI没有
RequestMapping
,Spring将自动重定向(?)到默认错误控制器。此重定向还将HttpServletRequest
中的URI更改为/error
(或类似内容)。因此,我无法再访问原始URI(以确定需要重定向到的位置)。我目前的解决方法是使用一个带有请求映射(path=“**”
)的简单控制器,但这似乎是一个肮脏的黑客行为。啊,对不起,从您的描述中,我了解到,尽管拦截器重定向,仍会发生重定向到/error
。然后我会更新我的答案,我想你应该可以使用一个过滤器
,将原始请求URI保存为请求属性。希望这能有所帮助。您使用控制器的方式肯定需要更少的工作,坦率地说,可能不太像黑客:)此外,如果您只是执行重定向,您可能最好使用过滤器实现,而不是使用拦截器/控制器方法。这确实有帮助。非常感谢你的努力:)别提了,我一路上也学到了一些东西:)