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に登録します。

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>