DWRを使う
下記のURLの内容を参考にDWRを使ってみました。
http://www3.vis.ne.jp/~asaki/p_diary/diary.cgi?Date=2005-11-04
このcreatorを利用したところ、引数で全てのパラメータを渡すのであれば問題なかったのですが、セッションに格納されているログインユーザの情報を利用したかったので、下記のように書き換えました。
S2Creator.java
package sample.dwr; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.PropertyDesc; import org.seasar.framework.beans.factory.BeanDescFactory; import org.seasar.framework.container.ComponentDef; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.SingletonS2ContainerFactory; import org.seasar.struts.util.RequestUtil; import uk.ltd.getahead.dwr.WebContextFactory; import uk.ltd.getahead.dwr.create.AbstractCreator; public class S2Creator extends AbstractCreator { private String beanName; private Class clazz; public void setBeanName(String beanName) { this.beanName = beanName; } public Class getType() { if (clazz == null) { try { S2Container container = SingletonS2ContainerFactory.getContainer(); HttpServletRequest request = WebContextFactory.get().getHttpServletRequest(); container.setRequest(request); ComponentDef def = container.getComponentDef(beanName); clazz = def.getComponentClass(); } catch (Exception ex) { clazz = Object.class; } } return clazz; } public Object getInstance() throws InstantiationException { S2Container container = SingletonS2ContainerFactory.getContainer(); ComponentDef cd = container.getComponentDef(beanName); Object component = cd.getComponent(); BeanDesc beanDesc = BeanDescFactory.getBeanDesc(cd.getComponentClass()); importProperties(component, container, beanDesc); return container.getComponent(beanName); } private void importProperties(Object component, S2Container container, BeanDesc beanDesc) { for (int i = 0; i < beanDesc.getPropertyDescSize(); i++) { PropertyDesc propertyDesc = beanDesc.getPropertyDesc(i); importProperty(component, container, propertyDesc); } } private static Map primitiveMap = new HashMap(); static { primitiveMap.put(Character.TYPE, Character.class); primitiveMap.put(Short.TYPE, Short.class); primitiveMap.put(Integer.TYPE, Integer.class); primitiveMap.put(Long.TYPE, Long.class); primitiveMap.put(Double.TYPE, Double.class); primitiveMap.put(Float.TYPE, Float.class); primitiveMap.put(Boolean.TYPE, Boolean.class); } private Class getPrimitiveWrappedClass(Class primitiveClass) { return (Class) primitiveMap.get(primitiveClass); } private void importProperty(Object action, S2Container container, PropertyDesc propertyDesc) { if (!propertyDesc.hasWriteMethod()) { return; } String propertyName = propertyDesc.getPropertyName(); Object value = getValue(container, propertyName); if (value == null) { return; } Class propertyType = propertyDesc.getPropertyType(); if (propertyType.isPrimitive()) { propertyType = getPrimitiveWrappedClass(propertyType); } if (propertyType.isInstance(value)) { propertyDesc.setValue(action, value); } } private Object getValue(S2Container container, String name) { Object var = RequestUtil.getValue(container.getRequest(), name); if (var != null) { return var; } if (container.hasComponentDef(name)) { return container.getComponent(name); } return null; } }
importPropertiesの部分は、HttpServletRequestとSessionのコンポーネントをDIするために、S2StrutsのBindingUtilを参考に追加しています。
このcreatorをWEB-INF直下のdwr.xmlに登録します。
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <init> <creator id="s2" class="sample.dwr.S2Creator"/> </init> <allow> <convert converter="bean" match="sample.dto.Sample1Dto"/> <create creator="s2" javascript="Sample1" scope="request"> <param name="beanName" value="sample1Action"/> <include method="findSample1"/> </create> <convert converter="bean" match="sample.dto.Sample2Dto"/> <create creator="s2" javascript="Sample2" scope="request"> <param name="beanName" value="sample2Action"/> <include method="findSample2List"/> </create> </allow> </dwr>
Sample1ActionとSample2Actionは、S2にコンポーネントを登録しておきます。
Sample1Action.java
package sample.action.dwr; import sample.dto.Sample1Dto; public interface Sample1Action { public Sample1Dto findSample1(String cd); }
Sample2Action.java
package sample.action.dwr; import java.util.List; public interface Sample2Action { public List findSample2List(String cd); }
このコンポーネントを呼び出すJSPは、下記のようになります。
sample.jsp
<script type="text/javascript" src="../dwr/engine.js"></script> <script type="text/javascript" src="../dwr/util.js"></script> <script type="text/javascript" src="../dwr/interface/Sample1.js"></script> <script type="text/javascript" src="../dwr/interface/Sample2.js"></script> <script type="text/javascript"> <!-- function updateSample1(cd) { Sample1.findSample1(getSample1, cd); } function getSample1(sample1) { DWRUtil.setValue("cd", sample1.cd); DWRUtil.setValue("name", sample1.name); } function updateSample2(cd) { Sample2.findSample2List(getSample2List, cd); } function getSample2List(sample2List) { DWRUtil.removeAllOptions("sample2"); DWRUtil.addOptions("sample2", sample2List, "cd", "name"); } //--> </script> <input type="text" name="cd" value=""> <input type="text" name="name" value=""> <input type="button" onclick="updateSample1();"> <select name="sample2" id="sample2" onchange="updateSample2(this.value);"> <option value="01">テスト01</option> <option value="02">テスト02</option> <option value="03">テスト03</option> <option value="04">テスト04</option> </select>