● AppFuse建立应用程序过程复习
Ø 利用AppFuse生成应用程序5步曲
(1) 采用hibernate建立持久层的POJO对象。
i)建立POJO
src/dao/**/model目录下建立一个简单的Person对象,这个对象包括id、firstName
和lastName属性。
package org.appfuse.model;
//该类继承BaseObject,提供必须的equals(), hashCode()和toString()方法
public class Person extends BaseObject {
private Long id;
private String firstName;
private String lastName;
//getter and Setter method
}
ii)增加XDolcet标记,用来产生hibernate的映射文件
/**
* @hibernate.class table="person"
*/
public class Person extends BaseObject
/**
* @hibernate.id column="id"
* generator-class="increment" unsaved-value="null"
*/
public Long getId() {
//注意所有的@hibernate.*标签必须在getters'的Javadocs里面。
return this.id;
}
(2) 运行ant setup-db产生映射文件和数据库表
<target name="setup-db" depends="db-create,db-prepare,db-load"/>
i) ant db-create,执行metadata/sql/mysql-create.sql脚本,建立数据库和用户。
create database if not exists dudu;
grant all privileges on dudu.* to test@"%" identified by "test";
grant all privileges on dudu.* to test@localhost identified by "test";
ii) ant db-prepare任务
<target name="db-prepare" depends="clean,package-dao"/>
Ø ant clean:
[delete] Deleting directory E:\app\appfuse\build
[delete] Deleting directory E:\app\appfuse\dist
[delete] Deleting: E:\app\appfuse\database.properties
Ø <target name="package-dao" depends="prepare,compile-dao"/>
Ø <target name="compile-dao" depends="hibernatedoclet"/>
Ø compile-dao中调用ant hibernatedoclet任务
该任务使用xdoclet.modules.hibernate.HibernateDocletTask工具,根据POLO
生成对应的hibernate映射文件
Ødb-prepare任务
使用net.sf.hibernate.tool.hbm2ddl.SchemaExportTas工具根据hibernate
映射文件建立数据库表和表关系。
iii) ant db-load任务根据使用dbunit工具metadata/sql/sample-data.xml往数据库表中插入测试数据。
(3) 创建Struts所需的PersonForm对象
Ø 为POJO添加Form对象需要的XDoclet标记
@struts.form include-all="true" extends="BaseForm"
Ø 执行ant gen-forms生成struts所需的Form Bean
<target name="gen-forms" depends="prepare" unless="webdoclet.uptodate"
description="Generates ActionForms from POJOs">
<taskdef name="xdoclet" classname="xdoclet.DocletTask"
classpathref="xdoclet.classpath"/>
<!-- generate struts forms -->
<xdoclet destdir="${build.dir}/web/gen"
excludedtags="@version,@author"
addedtags="@xdoclet-generated at ${TODAY}"
force="${xdoclet.force}"
mergedir="metadata/web">
<fileset dir="src/dao"/>
<!-- generate struts forms -->
<actionform templateFile="metadata/templates/struts_form.xdt">
<packageSubstitution packages="model"
substituteWith="webapp.form"/>
</actionform>
</xdoclet>
</target>
(4) 利用AppGen工具,使用XDoclet自动创建文件
ant install -Dmodel.name=Person -Dmodel.name.lowercase=person
该命令会生成所需的文件,并将这些文件拷贝到主项目中。
Ø 利用该工具生成的文件:
i) 自动生成的DAO接口
public interface PersonDAO extends DAO {
public List getPersons(Person person);
public Person getPerson(final Long id);
public void savePerson(Person person);
public void removePerson(final Long id);
}
ii) 自动生成的DAO的Hibernate实现类
public class PersonDAOHibernate extends BaseDAOHibernate implements PersonDAO {
public List getPersons(Person person) {
return getHibernateTemplate().find("from Person");
}
public Person getPerson(final Long id) {
Person person =
(Person) getHibernateTemplate().get(Person.class, id);
return person;
}
public void savePerson(final Person person) {
getHibernateTemplate().saveOrUpdate(person);
}
public void removePerson(final Long id) {
getHibernateTemplate().delete(getPerson(id));
}
}
iii) 自动生成DAO的Spring配置文件
<bean id="personDAO" class="org.dudu.dao.hibernate.PersonDAOHibernate"
autowire="byName"/>
</beans>
iv) 自动生成Manager接口
public interface PersonManager extends Manager {
public void setPersonDAO(PersonDAO personDAO);
public List getPersons(Person person);
public Person getPerson(final String id);
public void savePerson(Person person);
public void removePerson(final String id);
}
v) 自动生成的Manager实现类
public class PersonManagerImpl extends BaseManager implements
PersonManager {
private PersonDAO dao;
public void setPersonDAO(PersonDAO dao) {
this.dao = dao;
}
public List getPersons(final Person person) {
return dao.getPersons(person);
}
public Person getPerson(final String id) {
return dao.getPerson(new Long(id));
}
public void savePerson(final Person person) {
dao.savePerson(person);
}
public void removePerson(final String id) {
dao.removePerson(new Long(id));
}
}
vi) 自动生成Manager实现类的Spring配置信息
<bean id="personManager" parent="txProxyTemplate">
<property name="target">
<bean class="org.dudu.service.impl.PersonManagerImpl"
autowire="byName"/>
</property>
</bean>
</beans>
vii) 自动生成的全局常量
public static final String PERSON_KEY = "personForm";
public static final String PERSON_LIST = "personList";
}
viii) 自动生成的详细信息Action
/**
* Action class to handle CRUD on a Person object
* @struts.action name="personForm" path="/persons" scope="request"
* validate="false" parameter="method" input="mainMenu"
* @struts.action name="personForm" path="/editPerson" scope="request"
* validate="false" parameter="method" input="list"
* @struts.action name="personForm" path="/savePerson" scope="request"
* validate="true" parameter="method" input="edit"
* @struts.action-forward name="edit"path="/WEB-INF/pages/personForm.jsp"
* @struts.action-forward name="list"path="/WEB-INF/pages/personList.jsp"
*/
public final class PersonAction extends BaseAction {
public ActionForward cancel(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
return search(mapping, form, request, response);
}
public ActionForward edit(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
PersonForm personForm = (PersonForm) form;
if (personForm.getId() != null) {
PersonManager mgr = (PersonManager) getBean("personManager");
Person person = mgr.getPerson(personForm.getId());
personForm = (PersonForm) convert(person);
updateFormBean(mapping, request, personForm);
}
… …
}
ix) 自动生成测试用数据库记录
<table name='person'>
<column>id</column>
<column>first_name</column>
<column>last_name</column>
<row>
<value>1</value>
<value>firstName</value>
<value>lastName</value>
</row>
<row>
<value>2</value>
<value>firstName</value>
<value>lastName</value>
</row>
<row>
<value>3</value>
<value>firstName</value>
<value>lastName</value>
</row>
</table>
</dataset>
x) 自动生成JSP文件
<%@ include file="/common/taglibs.jsp"%>
<title><fmt:message key="personDetail.title"/></title>
<content tag="heading"><fmt:message key="personDetail.heading"/></content>
<html:form action="editPerson" method="post" styleId="personForm"
focus="" onsubmit="return validatePersonForm(this)">
<table class="detail">
<html:hidden property="id"/>
<tr>
<th>
<dudu:label key="personForm.firstName"/>
</th>
<td>
<html:text property="firstName" styleId="firstName"/>
<html:errors property="firstName"/>
</td>
</tr>
<tr>
<th>
<dudu:label key="personForm.lastName"/>
</th>
<td>
<html:text property="lastName" styleId="lastName"/>
<html:errors property="lastName"/>
</td>
</tr>
<tr>
<td></td>
<td class="buttonBar">
<html:submit styleClass="button" property="method"
onclick="bCancel=false">
<fmt:message key="button.save"/>
</html:submit>
<html:submit styleClass="button" property="method"
onclick="bCancel=true; return
confirmDelete('Person')">
<fmt:message key="button.delete"/>
</html:submit>
<html:cancel styleClass="button" property="method"
onclick="bCancel=true">
<fmt:message key="button.cancel"/>
</html:cancel>
</td>
</tr>
</table>
</html:form>
<!—这段代码测试时需要删除-->
<!—否则会报javax.servlet.jsp.JspException: No form found under 'personForm' in locale 'zh_CN'错误-->
<html:javascript formName="personForm" cdata="false"
dynamicJavascript="true" staticJavascript="false"/>
<script type="text/javascript"
src="<html:rewrite page="/scripts/validator.jsp"/>"></script>
xi) DAO Test
xii) Manager Test
xiii) Action Test
xiv) Canoo测试代码
xv) 自动生成资源配置文件信息
xvi) 自动生成Strtus Menu配置信息
xvii) 自动生成Struts Menu Jsp
(5) 执行ant deploy生成web应用,修改web应用,以符合你的应用需要,测试.
注:
ant install -Dmodel.name=Person -Dmodel.name.lowercase=person
该命令合并Constants.java文件、sample-data.xml文件、web-tests.xml文件ApplicationResources_en.properties文件,合并struts menu文件,将生成所有文件拷贝到注项目中。
AppGen生成的Jsp文件首字母是大写的,(关键)执行完以上命令后,应该将AppGen生成的struts所需的Jsp文首字母改为小写字母。这是AppFuse帮助文件中没有提及的,如果不执行这样步骤,web容器测试时,struts Action会因为forward所指jsp文件首字母是大写的而无法执行。