私の Spring MVC Web アプリには、ページの上部にナビゲーション メニューがあり、アイテムのリストへのリンクがあります。項目のリストはデータベースから取得されます。このメニューは、アプリケーション内のすべてのページに共通です。現在、すべてのコントローラーで、アイテムのリストを取得してセッションに保存し (まだセッションにない場合)、すべてのページで使用できるようにしています。うまくいきますが、これを行うにはもっと良い方法があるはずだと思います。この冗長性を避けるために、HandlerInterceptorAdapter を使用しようとしています。私はそれを機能させることができますが、完全ではありません。ページを初めてロードしたときに、セッションで設定したオブジェクトが表示されません。しかし、ページを更新すると、オブジェクトがセッションに表示されます。
この方法でインターセプターを作成しました:
public class MyHandlerInterceptor extends HandlerInterceptorAdapter {
private MyService myService;
//Constructor
public MyHandlerInterceptor(MyService myService) {
this.myService = myService;
}
//Overridden method
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("In posthandle...");
if (request.getSession().getAttribute("items") == null) {
request.getSession().setAttribute("items", myService.getCategories());
}
}
}
インターセプターを宣言しました:
<mvc:interceptors>
<bean class="com.gyanify.webapp.interceptors.MyHandlerInterceptor"
autowire="constructor"/>
</mvc:interceptors>
jsp がレンダリングされるまでに、オブジェクトがセッションに設定されているかどうかを確認しています。
...
Session Attributes <br/>
<%
System.out.println("Printing from the jsp...");
Enumeration keys = session.getAttributeNames();
while (keys.hasMoreElements())
{
String key = (String)keys.nextElement();
out.println(key + ": " + session.getValue(key) + "<br>");
}
%>
...
これで、最初にページをロードすると、コンソールに次の出力が表示されます。
...
Returning view....(this is printed from the controller)
Printing from the jsp...
In posthandle...
...
私の理解では、ページがレンダリングされる前に posthandle メソッドが呼び出されます。ただし、コンソールの出力によると、インターセプターの posthandle メソッドの前に jsp がレンダリングされていることがわかります。
なぜこのように振る舞うかを理解するのを手伝ってくれる人はいますか?