隨筆-72  評論-63  文章-0  trackbacks-0
          Appfuse應用的核心在于ant build任務的靈活應用和xdoclet模板的修改與使用。重要的工具是其提供的appgen,通過對ant build任務和appgen xdocet模板的修改將appfuse與自己的項目進行融合、與IDE進行融合。所以要用appfuse,學習ant工具和xdoclet是必不可少的第一步。
          前提所需的軟件
          jdk1.4.2.6
          tomcat5.0.28
          ant1.6.2
          appfuse1.82
          mysql4.x

          以上軟件請訪問
          http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuseQuickStart_zh
          根據相關提示下載
          同時對以上變量,都設置相關的HOME變量及路徑。

          下面開始一步步操作完成appfuse的布署工作

          1,解壓appfuse1.8.2(或更高版本),會產生一個appfuse的目錄。
          2,打開eclipse3.0或eclipse3.1,選擇菜單,“新建工程”-->"Java Project"---->工程名"appfuse"后,指定一個工程目錄后,完成。
          3,先復制第一步中appfuse目錄下所有文件,然后右鍵點擊"appfuse"工程名,選擇“粘貼”,把appfuse的所有的文件導入到appfuse工程中。
          4,在eclipse下選擇"windows"菜單--->"Preference"菜單--->"ant"--->"Runtime"---->點“ant????? home”按鈕,設備ant-home目錄,同時復制junit.jar到ant安裝目錄下的lib目錄里
          5,在安裝mysql服務器后,如果設置了密碼的話,要點,windows菜單--->show views---> ant 。出現(xiàn)ant工具界面,在界面上,點add buildfiles圖標,把appfuse工程根目錄下的build.xml文件中附加進來,然后再打開properties.xml文件,修改里面的root用戶的密碼為你的mysql數據庫訪問時的密碼。然后在ant菜單界面中展開target列表,選擇,setup目錄安裝所有裝備工作,
          詳細ant任務可以參照http://www.kingbit.com/appfuse/index.php上所描述的ant任務詳解。
          運行ant setup-tomcat 然后再運行,ant start-tomcat
          然后在瀏覽器中打http://localhost:8080/appfuse
          看看有沒有出現(xiàn)界面
          操作用戶名及密碼是tomcat tomcat
          6,當上面都配置正確后,我們就來開始寫一個新的操作了,先寫個dao類下的model類
          在eclipse下,展開src/dao文檔結構,在org.appfuse.model下面,建個Person.java文件,
          內容如下圖:

          /*
          ?* Created on 2006-5-22
          ?*
          ?* TODO To change the template for this generated file go to
          ?* Window - Preferences - Java - Code Style - Code Templates
          ?*/
          package org.appfuse.model;

          /**
          ?* @author Administrator
          ?*
          ?* TODO To change the template for this generated type comment go to
          ?* Window - Preferences - Java - Code Style - Code Templates
          ?* @hibernate.class table="person"
          ?*/
          public class Person? extends BaseObject{
          ?private Long id;
          ?private String first_name;
          ?
          ?/**
          ? * @return Returns the id.
          ? * @hibernate.id column="id"? generator-class="increment"
          ???? *??????????????
          ? */
          ?public Long getId() {
          ??return id;
          ?}
          ?/**
          ? * @param id The id to set.
          ? */
          ?public void setId(Long id) {
          ??this.id = id;
          ?}
          ?/* (non-Javadoc)
          ? * @see org.appfuse.model.BaseObject#toString()
          ? */
          ?
          ?public String toString() {
          ??// TODO Auto-generated method stub
          ??return null;
          ?}
          ?/* (non-Javadoc)
          ? * @see org.appfuse.model.BaseObject#equals(java.lang.Object)
          ? */
          ?public boolean equals(Object o) {
          ??// TODO Auto-generated method stub
          ??return false;
          ?}
          ?/* (non-Javadoc)
          ? * @see org.appfuse.model.BaseObject#hashCode()
          ? */
          ?public int hashCode() {
          ??// TODO Auto-generated method stub
          ??return 0;
          ?}
          ?
          ?/**
          ? * @return Returns the first_name.
          ? * @hibernate.property column="first_name" not-null="true"
          ? */
          ?public String getFirst_name() {
          ??return first_name;
          ?}
          ?/**
          ? * @param first_name The first_name to set.
          ? * @spring.validator type="required" //該字段需要驗證,用Spring的校驗機制
          ? */
          ?public void setFirst_name(String first_name) {
          ??this.first_name = first_name;
          ?}
          }


          在以上代碼中注釋javadoc區(qū)域中添加上xdoclet在生成hibernate所用到的XML文件的一些O/R映射信息。

          建好上以Person.java后,我們就開始利用xdoclet工具,配合ant任務,生成我們所需用到了數據庫表結構了,
          點ant db-create 后,可以在控制臺下看到一系列建表的語句,同時可以到mysql控制臺查看到相關信息.
          表建好后,我們就開始利用appgen自動生成appfuse所需要的其它dao操作類,manage業(yè)務類,controller控制器類及Person.hbm.xml等相關文件
          。操作過程如下,到dos命令行模式下,找到工程所在的根目錄下\extras\appgen目錄,點運行ant install-detailed
          會根據提示,建Person及person相關文件。Build成功后,再回到eclipse下,右鍵點工程文件名appfuse,選擇Refresh ,再運行ant deploy命令,再重新啟TOMCAT,這樣一個Person的添加,刪除操作功能模塊就完成了,開發(fā)就是這么easy and fast!!^_^
          @spring.validator type="required" 是另外附

          appgen生成的類文件如下:

          PersonDAO接口類
          PersonDAOHibernate接口實現(xiàn)類
          PersonManager業(yè)務接口類
          PersonManagerImpl.java業(yè)務接口實現(xiàn)類
          PersonController.java控制器類(根據客戶端提交的請求,顯示的是信息列表)
          PersonFormController頁面控制器類(根據客戶端提交的請求,修改,添加,刪除操作控制類)


          注意在生成dao接口類的時候,appgen會根據Person類中的hibernate的注釋標記,生成對應的Person.hbm.xml文件
          修改org.appfuse.dao.hibernate.applicationContext-hibernate.xml文件,
          追加
          ?<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          ??????? <property name="dataSource" ref="dataSource"/>
          ??????? <property name="mappingResources">
          ??????????? <list>
          ??????????????? <value>org/appfuse/model/Role.hbm.xml</value>
          ??????????????? <value>org/appfuse/model/User.hbm.xml</value>
          ??????????????? <value>org/appfuse/model/UserCookie.hbm.xml</value>
          ??????????????? <value>org/appfuse/model/Person.hbm.xml</value>
          ??<value>org/appfuse/model/Book.hbm.xml</value>????
          ??????????? </list>
          ??????? </property>
          ??????? <!-- The property below is commented out b/c it doesn't work when run via
          ???????????? Ant in Eclipse.? It works fine for individual JUnit tests and in IDEA ??
          ??????? <property name="mappingJarLocations">
          ??????????? <list><value>file:dist/appfuse-dao.jar</value></list>
          ??????? </property>
          ??????? -->
          ??????? <property name="hibernateProperties">
          ??????? <props>
          ??????????? <prop key="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
          ??????????? <!-- Create/update the database tables automatically when the JVM starts up
          ??????????? <prop key="hibernate.hbm2ddl.auto">update</prop> -->
          ??????????? <!-- Turn batching off for better error messages under PostgreSQL
          ??????????? <prop key="hibernate.jdbc.batch_size">0</prop> -->
          ??????? </props>
          ??????? </property>
          ??? </bean>
          ??? 同時指定動態(tài)指定接口的實現(xiàn)類
          <!--Person-START-->
          ??? <bean id="personDAO" class="org.appfuse.dao.hibernate.PersonDAOHibernate" autowire="byName"/>
          ??? <!--Person-END-->
          注意在業(yè)務接口類操作時,要運用SPRING的IOC進行對業(yè)務邏輯的處理,
          修改org.appfuse.service目錄下的,applicationContext-service.xml文件

          追加以下配置

          <!--Person-START-->
          ??? <bean id="personManager" parent="txProxyTemplate">
          ??????? <property name="target">
          ??????????? <bean class="org.appfuse.service.impl.PersonManagerImpl" autowire="byName"/>
          ??????? </property>
          ??? </bean>
          ??? <!--Person-END-->
          在personManagerImpl.java文件中裝PersonDao接口的Instance注入到personManager容器中。

          ?

          PersonDAO接口類


          package org.appfuse.dao;

          import java.util.List;

          import org.appfuse.model.Person;

          public interface PersonDAO extends DAO {

          ??? /**
          ???? * Retrieves all of the persons
          ???? */
          ??? public List getPersons(Person person);

          ??? /**
          ???? * Gets person's information based on primary key. An
          ???? * ObjectRetrievalFailureException Runtime Exception is thrown if
          ???? * nothing is found.
          ???? *
          ???? * @param id the person's id
          ???? * @return person populated person object
          ???? */
          ??? public Person getPerson(final Long id);

          ??? /**
          ???? * Saves a person's information
          ???? * @param person the object to be saved
          ???? */?
          ??? public void savePerson(Person person);

          ?/**
          ???? * Removes a person from the database by id
          ???? * @param id the person's id
          ???? */
          ??? public void removePerson(final Long id);
          }

          PersonDAOHibernate接口實現(xiàn)類


          package org.appfuse.dao.hibernate;

          import java.util.List;

          import org.appfuse.model.Person;
          import org.appfuse.dao.PersonDAO;

          import org.springframework.orm.ObjectRetrievalFailureException;

          public class PersonDAOHibernate extends BaseDAOHibernate implements PersonDAO {

          ??? /**
          ???? * @see org.appfuse.dao.PersonDAO#getPersons(org.appfuse.model.Person)
          ???? */
          ??? public List getPersons(final Person person) {
          ??????? return getHibernateTemplate().find("from Person");

          ??????? /* Remove the line above and uncomment this code block if you want
          ?????????? to use Hibernate's Query by Example API.
          ??????? if (person == null) {
          ??????????? return getHibernateTemplate().find("from Person");
          ??????? } else {
          ??????????? // filter on properties set in the person
          ??????????? HibernateCallback callback = new HibernateCallback() {
          ??????????????? public Object doInHibernate(Session session) throws HibernateException {
          ??????????????????? Example ex = Example.create(person).ignoreCase().enableLike(MatchMode.ANYWHERE);
          ??????????????????? return session.createCriteria(Person.class).add(ex).list();
          ??????????????? }
          ??????????? };
          ??????????? return (List) getHibernateTemplate().execute(callback);
          ??????? }*/
          ??? }

          ??? /**
          ???? * @see org.appfuse.dao.PersonDAO#getPerson(Long id)
          ???? */
          ??? public Person getPerson(final Long id) {
          ??????? Person person = (Person) getHibernateTemplate().get(Person.class, id);
          ??????? if (person == null) {
          ??????????? log.warn("uh oh, person with id '" + id + "' not found...");
          ??????????? throw new ObjectRetrievalFailureException(Person.class, id);
          ??????? }

          ??????? return person;
          ??? }

          ??? /**
          ???? * @see org.appfuse.dao.PersonDAO#savePerson(Person person)
          ???? */???
          ??? public void savePerson(final Person person) {
          ??????? getHibernateTemplate().saveOrUpdate(person);
          ??? }

          ??? /**
          ???? * @see org.appfuse.dao.PersonDAO#removePerson(Long id)
          ???? */
          ??? public void removePerson(final Long id) {
          ??????? getHibernateTemplate().delete(getPerson(id));
          ??? }
          }

          ?


          PersonManager業(yè)務接口類

          package org.appfuse.service;

          import java.util.List;

          import org.appfuse.model.Person;
          import org.appfuse.dao.PersonDAO;

          public interface PersonManager extends Manager {

          ??? /**
          ???? * Setter for DAO, convenient for unit testing
          ???? */
          ??? public void setPersonDAO(PersonDAO personDAO);

          ??? /**
          ???? * Retrieves all of the persons
          ???? */
          ??? public List getPersons(Person person);

          ??? /**
          ???? * Gets person's information based on id.
          ???? * @param id the person's id
          ???? * @return person populated person object
          ???? */
          ??? public Person getPerson(final String id);

          ??? /**
          ???? * Saves a person's information
          ???? * @param person the object to be saved
          ???? */
          ??? public void savePerson(Person person);

          ??? /**
          ???? * Removes a person from the database by id
          ???? * @param id the person's id
          ???? */
          ??? public void removePerson(final String id);
          }


          PersonManagerImpl業(yè)務接口實現(xiàn)類

          package org.appfuse.service.impl;

          import java.util.List;

          import org.appfuse.model.Person;
          import org.appfuse.dao.PersonDAO;
          import org.appfuse.service.PersonManager;

          public class PersonManagerImpl extends BaseManager implements PersonManager {
          ??? private PersonDAO dao;

          ??? /**
          ???? * Set the DAO for communication with the data layer.
          ???? * @param dao
          ???? */
          ??? public void setPersonDAO(PersonDAO dao) {
          ??????? this.dao = dao;
          ??? }

          ??? /**
          ???? * @see org.appfuse.service.PersonManager#getPersons(org.appfuse.model.Person)
          ???? */
          ??? public List getPersons(final Person person) {
          ??????? return dao.getPersons(person);
          ??? }

          ??? /**
          ???? * @see org.appfuse.service.PersonManager#getPerson(String id)
          ???? */
          ??? public Person getPerson(final String id) {
          ??????? return dao.getPerson(new Long(id));
          ??? }

          ??? /**
          ???? * @see org.appfuse.service.PersonManager#savePerson(Person person)
          ???? */
          ??? public void savePerson(Person person) {
          ??????? dao.savePerson(person);
          ??? }

          ??? /**
          ???? * @see org.appfuse.service.PersonManager#removePerson(String id)
          ???? */
          ??? public void removePerson(final String id) {
          ??????? dao.removePerson(new Long(id));
          ??? }
          }


          PersonController控制器類
          注意在產生這個控制器類的作用是為了將PersonManager接口通過IOC注入并Instance
          能夠調用dao類取得的數據結果集返回給客戶瀏覽器的請求。請求的mappingUrl地址又是在WEB/WEB-INF目錄下action-servlet.xml
          文件下進行配置的
          <!--Person-BEAN-START-->
          ??<bean id="personController" class="org.appfuse.webapp.action.PersonController" autowire="byName"/>

          ??? <bean id="personFormController" class="org.appfuse.webapp.action.PersonFormController" autowire="byName">
          ??????? <property name="commandName" value="person"/>
          ??????? <property name="commandClass" value="org.appfuse.model.Person"/>
          ??????? <property name="validator" ref="beanValidator"/>
          ??????? <property name="formView" value="personForm"/>
          ??????? <property name="successView" value="redirect:persons.html"/>
          ??? </bean>
          ??? <!--Person-BEAN-END-->

          ??? <!--Person-URL-START-->
          ??????????????? <prop key="/persons.html">personController</prop>
          ??????????????? <prop key="/editPerson.html">personFormController</prop>
          ??????????????? <!--Person-URL-END-->
          package org.appfuse.webapp.action;

          import java.util.List;

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

          import org.apache.commons.logging.Log;
          import org.apache.commons.logging.LogFactory;
          import org.apache.commons.beanutils.BeanUtils;

          import org.appfuse.Constants;
          import org.appfuse.model.Person;
          import org.appfuse.service.PersonManager;

          import org.springframework.web.servlet.ModelAndView;
          import org.springframework.web.servlet.mvc.Controller;

          public class PersonController implements Controller {
          ??? private final Log log = LogFactory.getLog(PersonController.class);
          ??? private PersonManager personManager = null;

          ??? public void setPersonManager(PersonManager personManager) {
          ??????? this.personManager = personManager;
          ??? }

          ??? public ModelAndView handleRequest(HttpServletRequest request,
          ????????????????????????????????????? HttpServletResponse response)
          ??? throws Exception {
          ??????? if (log.isDebugEnabled()) {
          ??????????? log.debug("entering 'handleRequest' method...");
          ??????? }

          ??????? Person person = new Person();
          ??????? // populate object with request parameters
          ??????? BeanUtils.populate(person, request.getParameterMap());

          ??????? List persons = personManager.getPersons(person);

          ??????? return new ModelAndView("personList", Constants.PERSON_LIST, persons);
          ??? }
          }


          PersonFormController添加修改刪除操作控制器類。

          package org.appfuse.webapp.action;

          import java.util.Locale;

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

          import org.apache.commons.lang.StringUtils;
          import org.appfuse.model.Person;
          import org.appfuse.service.PersonManager;
          import org.springframework.validation.BindException;
          import org.springframework.web.servlet.ModelAndView;

          public class PersonFormController extends BaseFormController {
          ??? private PersonManager personManager = null;

          ??? public void setPersonManager(PersonManager personManager) {
          ??????? this.personManager = personManager;
          ??? }

          ??? protected Object formBackingObject(HttpServletRequest request)
          ??? throws Exception {
          ??????? String id = request.getParameter("id");
          ??????? Person person = null;

          ??????? if (!StringUtils.isEmpty(id)) {
          ??????????? person = personManager.getPerson(id);
          ??????? } else {
          ??????????? person = new Person();
          ??????? }

          ??????? return person;
          ??? }

          ??? public ModelAndView onSubmit(HttpServletRequest request,
          ???????????????????????????????? HttpServletResponse response, Object command,
          ???????????????????????????????? BindException errors)
          ??? throws Exception {
          ??????? if (log.isDebugEnabled()) {
          ??????????? log.debug("entering 'onSubmit' method...");
          ??????? }

          ??????? Person person = (Person) command;
          ??????? boolean isNew = (person.getId() == null);
          ??????? Locale locale = request.getLocale();

          ??????? if (request.getParameter("delete") != null) {
          ??????????? personManager.removePerson(person.getId().toString());

          ??????????? saveMessage(request, getText("person.deleted", locale));
          ??????? } else {
          ??????????? personManager.savePerson(person);

          ??????????? String key = (isNew) ? "person.added" : "person.updated";
          ??????????? saveMessage(request, getText(key, locale));

          ??????????? if (!isNew) {
          ??????????? ?return new ModelAndView("redirect:editPerson.html", "id", person.getId());
          ??????????? }
          ??????? }

          ??????? return new ModelAndView(getSuccessView());
          ??? }
          }


          在布署公司的產品過程中,mine的WAR應用,在執(zhí)行ant compile-dao過程中,會報一個,找不到org.eclipse.jta的錯誤,
          這是由于ant找不到eclipse的關于jta的插件的原因!解決辦法是,在ant架包中,把eclipse 安裝目錄下的plugns目錄下的org.eclipse.jdt.core_3.0.
          (E:\eclipse\plugins\org.eclipse.jdt.core_3.0.0\)目錄中兩個jar文件加入到ant的lib目錄下!

          xdoclet在執(zhí)行ant的deploy的任務時,有時候生成的XML文件格式會出現(xiàn)小小的問題,解決的辦法是修改相關的JAVA文件,然后運行deploy腳本重新利用
          xdoclet來生成相關的xml文件!直至成功!

          首頁登錄在調用loginServlet時候,login.jsp頁面能正確顯示出來,但是提交到服務器的/authorize的action映射找不到,也就是找不到服務,
          這是由于tomcat是啟動在8080端口的服務,而程序中,用戶登錄的校驗是根據properties.xml文件中,配置的
          <property name="http.port" value="8080"/>這個端口號,默認的是80端口,可以通過把TOMCAT啟動時監(jiān)聽80端口或,修改properties.xml文件中
          http.port的value="8080",就可以找到服務器響應。注意,這里/authorize的映射,不是通過spring的IOC操作的,而是通過在web.xml文件中加入一個
          ?<filter>
          ? <filter-name>securityFilter</filter-name>
          ? <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
          - <init-param>
          ? <param-name>targetClass</param-name>
          ? <param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>
          ? </init-param>
          ? </filter>
          <filter-mapping>
          ? <filter-name>securityFilter</filter-name>
          ? <url-pattern>/j_security_check</url-pattern>
          ? </filter-mapping>

          來實現(xiàn)的

          但是一定要記得,文件net.sf.acegisecurity.util.FilterChainProxy是在acegi-security-x.x.x.jar包里面的,調用前一定要記得放在應用的WEB-INF/lib/目錄下才能正常使用。

          當系統(tǒng)啟動時會自動加載spring配置文件中所聲明的類,在appfuse中這一聲明是放在action-servlet.xml中的,因此必須將這個文件同其他的applicationContext.xml一起在web.xml中聲明為contextConfigLocation的內容,如下:

          ?? <context-param>
          ? <param-name>contextConfigLocation</param-name>
          ? <param-value>classpath*:META-INF/applicationContext-*.xml /WEB-INF/applicationContext-*.xml /WEB-INF/schedulingContext-timer.xml</param-value>
          ? </context-param>

          ?

          在action-servlet.xml中定義如下(這個文件必須符合spring-beans.dtd的規(guī)范):

          <beans>???
          ???
          ??? <bean id="userAction" class="com.mywap.webwork.action.UserAction" singleton="false">
          ??????? <property name="userManager"><ref bean="userManager"/></property>
          ??? </bean>
          ???
          ??? <!-- Add additional actions here -->
          </beans>

          ?


          acegi出了0.8,改動還真不少,原先0.7的應用,改了一個多小時才完全升級成功。備忘一下:

          1 最貼心的改變莫過于 filter chains可以放在spring 容器中加載了,再也不用在Web.XML中聲明長長的一串filter了。例如:

          ?<bean id="filterChainProxy" class="net.sf.aceGISecurity.util.FilterChainProxy">
          ????? <property name="filterInvocationDefinitionSource">
          ???????? <value>
          ???????? CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
          ????????? PATTERN_TYPE_APACHE_ANT
          ??????????? /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,......
          ???????? </value>
          ????? </property>
          ??? </bean>

          2 HttpSessionIntegrationFilter 已經消失,使用net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter取而代之,如:
          ??? <bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
          ????? <property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>
          ??? </bean>

          這個"context"屬性不可不設喲。

          3 新增了一個功能,可以在web.xml中聲明一個HttpSessionEventPublisher context listener,想想Spring的現(xiàn)在還不很成熟的消息發(fā)布機制(AOP),主要是用來記日志。我暫時還沒用到這個功能。

          ?

          mine在通過ant deploy任務到TOMCAT下,會把hibernate的表映射文件,連同持久化的類文件,打包成一個,mine-dao.jar架包,放到web-inf/lib私有目錄下

          posted on 2006-07-02 17:35 船長 閱讀(861) 評論(0)  編輯  收藏 所屬分類: 開源相關
          主站蜘蛛池模板: 浦江县| 洪江市| 明水县| 太康县| 兴文县| 防城港市| 名山县| 隆林| 马龙县| 广元市| 鄂伦春自治旗| 镇江市| 苏尼特左旗| 门头沟区| 永丰县| 榆树市| 东兴市| 静乐县| 巴东县| 吉木萨尔县| 巴青县| 娱乐| 金门县| 威宁| 丰台区| 晋州市| 绍兴县| 洱源县| 和顺县| 永泰县| 商丘市| 三明市| 杭州市| 乌兰浩特市| 金山区| 遵化市| 新丰县| 南昌县| 东丰县| 平谷区| 西平县|