2016-09-02 3 views
3

Springブートを使用してロードバランシングHandlerInterceptorを実装しています。スプリングブートHandlerInterceptor loadbalancing

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に基​​づいて、1つのサービスまたは別のサービスにリダイレクトするということです。アプリケーションに明示的なRequestMapping(まだ)がありません。

ここで問題は、インターセプタが呼び出されると、リクエストがデフォルトのSpringエラーハンドラにリダイレクトされることです。その結果、HttpServletRequestに格納されているURIは/error(実質的に元のURIへのアクセスを拒否する)に置き換えられます。

エラーハンドラにリルートされる前にリクエストを傍受する方法はありますか(元のuriを取得するには)?

答えて

1

EDIT:あなたはむしろに依存しないと思います。そうでない場合、

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

} 

がため春のMVCがマッピングされていないリクエストを処理する方法の

、あなたはどちらかのフィルタが必要になりますセッション、you'll need to make the DispatcherServlet throw an exception in case no handler mapping is found、その後、@ControllerAdviceエラーハンドラからのリダイレクトを送る:AVに

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

重複を避けるためには、インターセプタとエラーハンドラの両方から呼び出す共通のクラスを用意することができます。

+0

リダイレクトは正常に動作します。問題は、リクエストから元のURIが必要なことです。元のURIの 'RequestMapping'がない場合、Springはデフォルトのエラーコントローラに自動的に(?)をリダイレクトします。このリダイレクトは、 'HttpServletRequest'のURIを'/error'(または何らかのもの)に変更します。その結果、元のURIにアクセスできなくなりました(どこにリダイレクトする必要があるかを判断するため)。私の現在の回避策は 'RequestMapping(path =" ** ")'でシンプルなコントローラを用意することですが、それは汚れたハックのようです。 – irundaia

+0

ああ、申し訳ありませんが、私の理解では、インターセプタのリダイレクトにもかかわらず、/ errorへのリダイレクトが起こっていることを理解しました。私は自分の答えを更新します。元のリクエストURIをリクエスト属性として保存するだけの 'Filter'があれば大丈夫だと思います。 –

+0

そこに、助けてくれる希望。あなたのコントローラを使用する方法は間違いなく作業が少なくて済みます。もし正直であればおそらくハックは少なくなります:)リダイレクトをやっているだけなら、おそらく 'Filter'実装ではなくインターセプタ/コントローラアプローチ。 –

関連する問題