POJOのFormをSessionスコープで利用する(再送)
またまた、チャレンジ。
今度はアドバイスをもらって、AOPとして提供することが目標。
思いつかなかったけど、いい方法だなーっと思った。
一時的にAOPでパッチを当てて、正常になったらはずす。
うーん。しっくりくる。いい感じだ。
で、どこにアスペクトするかだけど・・・
やっぱり、S2RequestProcessorかなー。
もしかしたら、publicに変更してもらわないといけないかも。
ちょっと調査
S2RequestProcessor#processActionForm()がよさそう。
しかもpublic。
テストクラスは・・・思いつかないから、作らない・・・まずいかな
ま、ちょうどs2struts-exampleをさわってたからこれを利用しよーっと。
まずは、sessionスコープに格納されていないことを確認。
・・・きちんと動く
あれ?
直接JSPを表示してるからだ。
Actionを呼んだときにsessionに格納されているPOJOのFormを再利用しない。
だから単純にJSPを表示するときでもきちんとAction経由にするとうまくいかないはず。
うむ。期待通り。やっぱりsessionからPOJOのFormを取得できてなかった。
やっと、Interceptorの作成
まずは、もしPOJOのFormだったら、特別な処理にすればOKだから、FormBeanConfigをとってくればどうにかりそう。
っていうかModuleConfigってどうやってとるんだろう。
S2RequestProcessor#processActionForm()の引数ってrequest、response、ActionMappingの3つだし。
S2RequestProcessorのフィールドとして持ってるけど、どうやれば取れるんだろう・・・
MethodInvocation#getThis()ってなんかよさそうな気が・・・
ちょっとサンプルを作って動かしてみたら、アスペクトしたメソッドのオブジェクトが取れてそう。ちょっと勉強になった。
これでどうにかなりそう。
public class POJOFormInterceptor extends AbstractInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { ActionMapping mapping = getMapping(invocation); ModuleConfig moduleConfig = getModuleConfig(invocation); if (isPojoForm(mapping, moduleConfig)) { HttpServletRequest request = getRequest(invocation); ActionServlet servlet = getServlet(invocation); return createPojoForm(request, mapping, moduleConfig, servlet); } else { return invocation.proceed(); } } private boolean isPojoForm(ActionMapping mapping, ModuleConfig moduleConfig) throws Throwable { FormBeanConfig formConfig = moduleConfig.findFormBeanConfig(mapping .getName()); Class fromClass = RequestUtils.applicationClass(formConfig.getType()); return !ActionForm.class.isAssignableFrom(fromClass); } private ActionForm createPojoForm(HttpServletRequest request, ActionMapping mapping, ModuleConfig moduleConfig, ActionServlet servlet) { String attribute = mapping.getAttribute(); if (attribute == null) { return (null); } String name = mapping.getName(); FormBeanConfig config = moduleConfig.findFormBeanConfig(name); if (config == null) { return (null); } ActionForm instance = lookupPojoForm(request, attribute, mapping .getScope()); if (instance != null) { return (instance); } return RequestUtils.createActionForm(config, servlet); } private ActionForm lookupPojoForm(HttpServletRequest request, String attribute, String scope) { ActionForm instance = null; HttpSession session = null; if ("request".equals(scope)) { instance = (ActionForm) request.getAttribute(attribute); } else { session = request.getSession(); instance = (ActionForm) session.getAttribute(attribute); } return (instance); } // // // private HttpServletRequest getRequest(MethodInvocation invocation) { return (HttpServletRequest) invocation.getArguments()[0]; } private HttpServletResponse getResponse(MethodInvocation invocation) { return (HttpServletResponse) invocation.getArguments()[1]; } private ActionMapping getMapping(MethodInvocation invocation) { return (ActionMapping) invocation.getArguments()[2]; } private ModuleConfig getModuleConfig(MethodInvocation invocation) { S2RequestProcessor processor = (S2RequestProcessor) invocation .getThis(); return processor.getModuleConfig(); } private ActionServlet getServlet(MethodInvocation invocation) { S2RequestProcessor processor = (S2RequestProcessor) invocation .getThis(); return processor.getActionServlet(); } }
こんな感じになった。
これでs2struts-exampleのs2struts.diconを修正してTomcat起動。
そして確認。
ダメだ。
アスペクトできてない?もしかして。
うーん。printlnデバッグをしてみるか・・・
やっぱりダメだ。
困った。
って思ったら、RequestProcessor.diconってのがあった!!
そういえば、コンソールに処理時間が出力されてて不思議に思ってたんだよねー
RequestProcessor.diconを修正してTomcat起動。
うまくいった。
これでOKかな。