- 追加された行はこの色です。
- 削除された行はこの色です。
[[FrontPage]]
#contents
2008/01/11からのアクセス回数 &counter;
* Spring-MVC用archeTypeプラグイン [#x1699a79]
Spring-MVC用archeTypeプラグインによって生成されるファイルについて説明します。
** GenMVCプラグインがサポートするデータタイプ [#kdc7dafe]
データベースのテーブルに対応づけられるフィールドの型は、
|CENTER: Javaクラス |CENTER: テーブルカラム型 |
| java.lang.Integer | INTEGER |
| java.lang.Double | DOUBLE |
| java.lang.String | VARCHAR |
| java.lang.Boolean | BIT |
| java.util.Date | DATE |
| java.sql.Date | DATE |
| java.sql.Timestamp | TIMESTAMP |
です。また、volatile宣言された属性はテーブルには含まれません。
** 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>
}}
** コメント [#ycc056b2]
この記事は、
#vote(おもしろかった,そうでもない,わかりずらい)
#vote(おもしろかった[1],そうでもない[0],わかりずらい[0])
皆様のご意見、ご希望をお待ちしております。
#comment_kcaptcha