[[FrontPage]]

* Spring-MVC用archeTypeプラグイン [#x1699a79]
Spring-MVC用archeTypeプラグインによって生成されるファイルについて説明します。

** java/example/test/domain/Member.java [#h69b6255]
example.test.domainパッケージには、モデルとなるクラスを定義します。

''モデルクラスは、必ずprivate Integer id;のフィールドを定義する必要があります''。

Member.javaの内容は、完全なPOJOです。
#pre{{
package example.test.domain;

/**
 * Member
 *
 */
public class Member {
	private Integer	id;
	private String		name;
	private String		address;
	// Eclipse で自動生成されたgetter/setter
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
}}

** java/example/test/service/IMember.java [#f069ba91]
example.test.serviceパッケージには各種サービスを定義します。
IMember.javaは、MemberDaoのインタフェースが定義されています。

IMember.javaの定義は以下の通りです。通常のDaoと違うところはprintメソッドを
定義しているところです。これがあるとテストの時にオブジェクトの比較が簡単に
なるので、重宝しています。

#pre{{
package example.test.service;

import example.test.domain.Member;

public interface IMember {
	void 		saveOrUpdate(Member member);
	void		delete(Member member);
	Member 		findById(Integer id);
	Member[]	findAll();
	String		print(Member member);	
}
}}

** java/example/test/service/MemberManager.java(更新されない) [#jaef5287]
MemberManager.javaは、MemberDaoのサブクラスとして定義してあり、Dao以外のサービスを定義するために生成してあります。このファイルは、GenMVCプラグインでは更新されません。

MemberManager.javaの定義は以下の通りです。
#pre{{
package example.test.service;

import example.test.service.stub.MemberDao;

public class MemberManager extends MemberDao {

}
}}

** java/example/test/service/stub/MemberDao.java [#wab68a48]
IMemberを実装したDaoです。printメソッドのために、DbHelper を使っています。

MemberDao.javaの定義は以下の通りです。HibernateDaoSupportを使っているため、非常にシンプルになっています。
#pre{{
package example.test.service.stub;

import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import jp.co.pwv.utils.DbHelper;

import example.test.domain.Member;
import example.test.service.IMember;

public class MemberDao extends HibernateDaoSupport implements IMember {
	private DbHelper helper = new DbHelper(Member.class);
	public void saveOrUpdate(Member member) {
		getHibernateTemplate().saveOrUpdate(member);
	}
	public void delete(Member member) {
		getHibernateTemplate().delete(member);
	}
	public Member findById(Integer id) {
		return (Member)getHibernateTemplate().get(Member.class, id);
	}
	public Member[] findAll() {
		List list = getHibernateTemplate().loadAll(Member.class);
		return (Member[])list.toArray(new Member[list.size()]);
	}
	public String print(Member member) {
		return (helper.toString(member));
	}	
}
}}

** java/example/test/web/EditMemberController.java(更新されない) [#l0aadaf0]
example.test.webパッケージにはSpringのWebコントローラを定義します。

EditMemberController.javaは、SimpleFormControllerのサブクラスで、編集画面へのデータをセットしたり、DBに値を保存する処理をします。一カ所だけトリッキーなことをしているのが、addリンクを押したときにidなしの要求をだします、この時 MissingServletRequestParameterException 例外が発生するのでそのタイミングで新規オブジェクトを生成し、DBに登録しています。


EditMemberController.javaの定義は以下の通りです。
#pre{{
package example.test.web;

import javax.servlet.http.HttpServletRequest;
import example.test.domain.Member;
import example.test.service.MemberManager;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.mvc.SimpleFormController;

public class EditMemberController extends SimpleFormController {
    private MemberManager manager;

    public void setManager(MemberManager manager) {
        this.manager = manager;
    }
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
    	try {
            int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
            Member member = manager.findById(new Integer(id));
            return member;
    	}
    	catch (MissingServletRequestParameterException e) {
    		// idが無い場合には新しいRecipeを生成し、idを割り付ける
    		Member member = new Member();
    		manager.saveOrUpdate(member);
    		return member;
    	}
    }
    protected void doSubmitAction(Object object) throws Exception {
    	Member member = (Member) object;
    	manager.saveOrUpdate(member);
    }
}
}}

** java/example/test/web/MemberOpsController.java(更新されない) [#p02f1d97]
MemberOpsControllerは、MultiActionControllerのサブクラスとして定義されています。
Memberに対する新しいWeb要求を定義するときにその名前のメソッドを定義するだけでWeb要求を
提供することができます。MemberOpsControllerでは、list, add, deleteを定義しています。

MemberOpsController.javaの定義を以下に示します。
#pre{{
package example.test.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import example.test.domain.Member;
import example.test.service.MemberManager;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class MemberOpsController extends MultiActionController {
	private MemberManager manager;

    public void setManager(MemberManager manager) {
        this.manager = manager;
    }

    public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return new ModelAndView().addObject(manager.findAll());
    }

    public ModelAndView add(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	ModelAndView modelAndView = new ModelAndView();
    	modelAndView.setViewName("editMemmber.htm");
        return modelAndView;
    }
    
    public ModelAndView delete(HttpServletRequest request, HttpServletResponse response) throws Exception {
        int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
        Member member = manager.findById(new Integer(id));
        manager.delete(member);
    	ModelAndView modelAndView = new ModelAndView();
    	modelAndView.addObject(manager.findAll());
    	modelAndView.setViewName("memberops/list");
        return modelAndView;
    }
}
}}

** webapp/WEB-INF/hbm-dir/Member.hbm.xml [#vadf217c]
Member.hbm.xmlは、Hibernateが使用するMember.javaとデータベースのテーブルを関係を定義したファイルです。テーブル間の関連を定義するときにはこのファイルを修正します。しかしGenMVCの自動生成で上書きされるので注意してください。

Member.hbm.xmlの内容は以下の通りです。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class 
		name="example.test.domain.Member"
		table="T_MEMBER">
		<id name="id">
			<generator class="increment"/>
		</id>
		<property name="address"/>
		<property name="name"/>
	</class>
</hibernate-mapping>
}}

** webapp/WEB-INF/hsqlDB/test.script [#g1bc66ae]
test.scriptは、HsqlDBのデータベース定義ファイルです。

** webapp/WEB-INF/sql/createTable.sql [#o3319a60]
createTable.sqlは、テーブル作成用のSQL文です。

** webapp/WEB-INF/tldは省略します [#p128cdea]

** webapp/WEB-INF/velocity/editMember_stub.vm [#e8f306a9]
webapp/WEB-INF/velocity以下には、Htmlを生成するためのVelocityテンプレートが定義されます。

editMember_stub.vmは、Memberの編集画面を生成するテンプレートです。
editMember_stub.vmの内容は以下の通りです。
#pre{{
<html>
<head>
	<title>Members</title>
</head>

<body>
Edit Member
	<form method="post" action="#springUrl("/editmember.htm")">
		#springFormHiddenInput( "member.id" "" )
		<table>
	        <tr>
	            <td>address:</td>
	            <td>#springFormInput( "member.address" "" )</td>
	            <td>
				#springBind("member.address")
				<font color="red">${status.errorMessage}</font>
			    </td>
	        <tr>
	            <td>name:</td>
	            <td>#springFormInput( "member.name" "" )</td>
	            <td>
				#springBind("member.name")
				<font color="red">${status.errorMessage}</font>
			    </td>
	        <tr>
	            <td colspan="3">
	                <input type="submit" value="Save Changes"/>
	            </td>
	        </tr>
		</table>
	</form>
</html>
</body>
}}

** webapp/WEB-INF/velocity/editMember.vm(更新されない) [#n069895b]
editMember.vmは、editMember_stub.vmをインクルードしているだけです。
自動生成の影響を受けないようにするためには、このファイルに最終的なテンプレートを定義するにはeditMember_stub.vmをコピーして手で修正することをお勧めします。

editMember.vmの定義は以下の通りです。
#pre{{
#parse ( "editMember_stub.vm" )
}}

* webapp/WEB-INF/velocity/memberops/list_stub.vm [#q7832aa1]
webapp/WEB-INF/velocity/memberopsには、MemberOpsControllerのメソッド名に対応した名前のテンプレートを定義します。
list_stub.vmは、list.vmのためのスタブです。

list_stub.vmの定義は以下の通りです。
#pre{{
<html>
  <head>
  	<title>Member</title>
  </head>
  <body>
    <table>
	#foreach (${member} in ${memberList})
		<tr>
			<td>${member.id}</td>
	        <td>${member.address}</td>
	        <td>${member.name}</td>
			#set( $editLink = "/editmember.htm?id=${member.id}" )
            <td><a href="#springUrl(${editLink})">[edit]</a></td>
            #set( $deleteLink = "/memberops/delete.htm?id=${member.id}" )
            <td><a href="#springUrl(${deleteLink})">[delete]</a></td>
        </tr>
	#end
    </table>
    <a href='#springUrl("/editmember.htm")'>add</a>
  </body>
</html>
}}

** webapp/WEB-INF/velocity/memberops/list.vm(更新されない) [#a539b79b]
list.vmは、list_stub.vmをインクルードしているだけです。

** webapp/WEB-INF/applicationContext.xml [#j48028e7]
applicationContext.xmlにはデータベースのテーブル作成用Beanの定義とMemberManagerのBeanを定義します。

#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="sqlUtils" class="jp.co.pwv.utils.TryToCreateTables" init-method="tryToCreateTalbles">
		<property name="sessionFactory" ref="sessionFactory" /> 
		<property name="sqls">
			<list>
				<value>CREATE TABLE T_MEMBER(ID INTEGER NOT NULL PRIMARY KEY,ADDRESS VARCHAR,NAME VARCHAR);</value>
			</list>
		</property>
	</bean>
	
    <bean id="memberManager" class="example.test.service.MemberManager">
		<property name="sessionFactory" ref="sessionFactory" /> 
    </bean>
</beans>
}}

** webapp/WEB-INF/custom-editor.xml(更新されない) [#t9b3a595]
custom-editor.xmlには、SimpleFormControllerの内部で使用するデータのプロパティエディタを登録するcustomEditorRegistrarを定義しています。
ここでは、java.util.Dateとjava.lang.Stringの変換のために、Springの提供するCustomDateEditorを使っています。

custom-editor.xmの定義は以下の通りです。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="dateFormat" class="java.text.SimpleDateFormat">
		<constructor-arg index="0" type="java.lang.String" value="yyyy-MM-dd" />
	</bean>
	
	<bean id="customEditorRegistrar" class="jp.co.pwv.utils.CustomPropertyEditorRegistrar">
	  <property name="customEditors">
	    <map>
	      <entry key="java.util.Date">
	        <bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
				<constructor-arg index="0">
					<ref bean="dateFormat" />
				</constructor-arg>
				<constructor-arg  index="1" type="boolean" value="true"/>
	        </bean>
	      </entry>
	    </map>
	  </property>
	</bean>
</beans>
}}

** webapp/WEB-INF/db-def.xml(更新されない) [#sb6d1b0f]
db-def.xmlには、Hibernateがデータベースにアクセスするための定義があります。

ここでは、HsqlDbを使用していますが、36行目の
#pre{{
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
}}
を変更することで他のDBが利用できます。
定義の説明は、http://www.pwv.co.jp/take_public_html/di-aop/docs/diaop.html#doc1_464 を参照してください。

** webapp/WEB-INF/jdbc.properties(更新されない) [#fc458ab3]
jdbc.propertiesには、データベースを定義します。
HsqlDbでは、jdbc:hsqldb:データベース定義ファイルのパスを指定することでデータベースサーバを起動しないでデータベース機能を提供することができます。

また、db.url=jdbc:hsqldb:hsql://localhostとすることでHsqlDbのサーバにアクセスすることもできます。

#pre{{
# サーバとして使用する場合
#db.url=jdbc:hsqldb:hsql://localhost
# スタンドアローンで使用する場合
db.url=jdbc:hsqldb:/Users/take/local/tomcat/webapps/test/WEB-INF/hsqlDb/test
db.driver=org.hsqldb.jdbcDriver
db.username=sa
db.password=
}}

** webapp/WEB-INF/servlet-def.xml(更新されない) [#q58e9ae4]
servlet-def.xmlではサーブレットの定義をしています。
ここで注目する部分は、propsのencodingの指定
#pre{{
	<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> 
	  <property name="resourceLoaderPath" value="WEB-INF/velocity/" /> 
		<property name="velocityProperties">
		<props>
		<prop key="input.encoding">UTF-8</prop>
		<prop key="output.encoding">UTF-8</prop>
		</props>
		</property>
	</bean> 
}}
とcontentTypeの定義です。
#pre{{
    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver"> 
		<property name="contentType" value="text/html;charset=UTF-8" />
}}

ただし、これだけでは日本語は正しく処理できず、web.xmlにCharacterEncodingFilterを定義する必要があります。

servlet-def.xmlの定義は以下の通りです。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

    <!-- maps request URLs to Controller names -->
    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

    <!-- this bean with the well known name generates view names for us -->
    <!-- not strictly required since we just want to accept the defaults-->
    <bean id="viewNameTranslator" class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator"/>

	<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> 
	  <property name="resourceLoaderPath" value="WEB-INF/velocity/" /> 
		<property name="velocityProperties">
		<props>
		<prop key="input.encoding">UTF-8</prop>
		<prop key="output.encoding">UTF-8</prop>
		</props>
		</property>
	</bean> 
	
    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver"> 
		<property name="contentType" value="text/html;charset=UTF-8" />
		<property name="suffix" value=".vm" /> 
		<property name="dateToolAttribute"> 
		  <value>dateTool</value> 
		</property> 
		<property name="numberToolAttribute"> 
		  <value>numberTool</value> 
		</property> 	
	</bean> 
</beans>
}}

** webapp/WEB-INF/servlet-stub.xml [#m623de09]
servlet-stub.xmlでは、MemberOpsController, EditMemberControllerへのDIを定義します。
#pre{{
		<property name="propertyEditorRegistrars">
			<list>
				<ref bean="customEditorRegistrar"/>
			</list>
		</property>
}}
で、カスタムエディタが有効になるようにしています。

servlet-stub.xmlの定義は以下の通りです。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

    <bean id="baseMemberController" abstract="true">
        <property name="manager" ref="memberManager"/>
    </bean>

    <!-- Controller names are not important when using the above HandlerMapping implementation -->
    <bean class="example.test.web.MemberOpsController"
          parent="baseMemberController"/>

    <bean class="example.test.web.EditMemberController"
          parent="baseMemberController">
        <property name="commandName" value="member"/>
        <property name="commandClass" value="example.test.domain.Member"/>
        <property name="formView" value="editMember"/>
        <property name="successView" value="redirect:memberops/list.htm"/>
		<property name="propertyEditorRegistrars">
			<list>
				<ref bean="customEditorRegistrar"/>
			</list>
		</property>
    </bean>

    <bean id="baseScheduleController" abstract="true">
        <property name="manager" ref="scheduleManager"/>
    </bean>

</beans>
}}

** webapp/WEB-INF/web.xml(更新されない) [#l57f5422]
web.xmlは、サーブレットの定義を行います。

web.xmlの定義は以下の通りです。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
		
	<listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

	<context-param> 
	  <param-name>contextConfigLocation</param-name> 
	  <param-value> 
		/WEB-INF/custom-editor.xml
	    /WEB-INF/db-def.xml
		/WEB-INF/applicationContext.xml
	  </param-value> 
	</context-param> 
	
	<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/servlet-def.xml,/WEB-INF/servlet-stub.xml</param-value>
		</init-param>
	</servlet>

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <jsp-config>
        <taglib>
            <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
            <taglib-location>/WEB-INF/tld/c.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
            <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location>
        </taglib>
    </jsp-config>

</web-app>
}}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc