Using Struts With Java™ Data Objects 
Persistence/Web Framework 
  
“学习如何使用Struts和Java™ Data Objects(JDO)来建构可升级、模块化的WEB应用程序。” 
  
本文从以下几个方面逐一阐述: 
1.  Struts Key Concepts 
2.  JDO Key Concepts 
3.  初始化Servlet 
4.  在Actions中方问持久层数据 
5.  缺陷和误区 
6.  概要 
7.  原文作者 
  
下面逐一分析: 
1.Struts Key Concepts 
1)  Struts Controller(ActionServlet) 
l         Model-View-Controller 模式 
l         Model=(Persistent data)可以持久化的数据; 
View=显示层 (JSP™ page) 
Controller=控制层{Servlet(Struts ActionServlet)} 
-Controller接受HTTP请求 
-Controller用action form来封装来自的client端的数据,并调用formbean中的validate()方法来对封装的数据进行校验,如果校验中发现错误可以进行回写。 
-Controller调度action去处理校验过的form bean. 
  2)struts key concepts 
 
   
3)Struts Actions Classes 
开发员可以开发自己的ApplicationAction,只要其继承Struts Action class 
       -Action 处理逻辑事务或者移交给专门处理业务逻辑的类模块。 
       -Action 返回业务对象继续处理其他的事务或者直接返回client端通常为 JSP™  page. 
       - 
4)Srevlet Filter 
       -每一个请求都要经过Filter 
       -可以定制Filter来访问特定的资源 
       -调用其他的Filter或者Struts ActionServlet 
       -注意捕获异常 
  
2.JDO Key Concepts 
    2.1 Java™ Data Objects Key Concepts 
1)      PersistenceManagerFactory 
-工厂方法来创建PersistenceManager 
2)      PersistenceManager 
        -create/delete 持久对象 
          -Query factory 
3)      Query 
        -根据不同的查询条件来得到持久对象集合 
4)      Transaction 
       -Begin,commit,rollback 
5)      Query返回持久对象的集合 
6)      持久对象就是你的应用程序中的Plain Old Java™ Objects,如:Customer、Order、OrderLine、Part等等 
7)      Use methods on instances without regard for struts,Web container,HTTP 
8)      持久化的数据的更新有JDO产品隐藏处理 
  2.2  JDOFilter 
   
public class JDOFilter implements javax.servlet.filter{ 
   private PersistenceManagerFactory pmf; 
  public void init(FilterConfig fc){ 
     initializePMF(fc); 
} 
public void doFilter(…) throws IOException,ServletException{ 
       PersistenceManager pm=null; 
    Try{ 
       Pm=initializePM(); 
       Chain.doFilter(…); 
              FinalizePM(pm); 
}finally{ 
   abnormalPM(pm); 
} 
} 
….. 
} 
  3. 初始化Servlet 
       3.1 
l         Container 调用Filter.init() 来初始化PersistenceManagerFactory 
-查找/创建 PersistenceManagerFactory 
   -通过JndiName(如果容器支持JNDI) 
-J2EE™ Application Server environment 
-通过ResourceName(if not) 
    -ResourceName 标示特定的拥有配置信息的properties文件 
l         存储PersistenceManagerFactory到filter实例中 
  
3.2 Filter 配置信息 
   
  [添加到web.xml中] 
   
  <filter> 
    <filter-name>MediaManiaPMF</filter-name> 
  <filter-class> 
        com.mediamain.appservre.JDOFilter 
</filter-class> 
<init-param> 
       <param-name>path</param-name> 
       <param-value> 
             /WEB-INF/jdoMovies.properties 
</param-value> 
</init-param> 
</filter> 
  
  3.3 jdoMovies.properties 
   
[放在应用程序包web-inf下] 
  
下面的内容跟原文不同,在此处我使用另外一种JDO产品:JDOGenie(http://www.hemtech..co.za) 
jdoMovies.properties的内容如下: 
  
# Server name (must be unique on a machine) 
server=jdogenie1 
remote.access=false 
remote.pm=false 
hyperdrive=true 
  
# JDO Genie version 
version=1.4.10 (04 Jul 2003) 
  
# Data stores 
storeCount=1 
store0.name=main 
store0.type=jdbc 
store0.driver=com.microsoft.jdbc.sqlserver.SQLServerDriver 
store0.url=jdbc\:microsoft\:sqlserver\://localhost 
store0.db=mssql 
store0.user=song 
store0.password=song 
store0.properties=DatabaseName\=jdotest;SelectMethod\=cursor 
store0.maxActive=5 
store0.maxIdle=2 
store0.init.sql= 
store0.wait.for.con.on.startup=false 
store0.validate.sql= 
store0.test.on.alloc=false 
store0.test.on.release=false 
store0.validate.mapping.on.startup=false 
store0.test.on.exception=true 
store0.retry.interval.ms=1000 
store0.retry.count=10 
store0.pscache.max= 
store0.ext.jdbc-key-generator=- 
store0.jdbc.namegen=- 
  
# .jdo resources 
jdoFileCount=1 
jdo0=system.jdo 
  
# Properties for JDOHelper.getPersistenceManagerFactory(...) 
javax.jdo.PersistenceManagerFactoryClass=za.co.hemtech.jdo.client.BootstrapPMF 
javax.jdo.option.Optimistic=true 
javax.jdo.option.RetainValues=false 
javax.jdo.option.RestoreValues=false 
javax.jdo.option.IgnoreCache=false 
javax.jdo.option.NontransactionalRead=false 
javax.jdo.option.NontransactionalWrite=false 
javax.jdo.option.Multithreaded=false 
  
# Event logging 
event.logging=- 
  
# Cache settings 
cache.enabled=true 
cache.maxobjects=10000 
cache.listener=- 
query.cache.enabled=true 
query.cache.max.queries=10000 
  
# Data store 0 mappings 
store0.jdbc.type.count=0 
store0.jdbc.javatype.count=0 
  
# JDO Genie Meta Data Editor properties (not used at runtime) 
  
mdedit.classPathCount=4 
mdedit.cp0=E\:/rms15/lib/mssqlserver.jar 
mdedit.cp1=classes 
mdedit.cp2=E\:/rms15/lib/msbase.jar 
mdedit.cp3=E\:/rms15/lib/msutil.jar 
  
# JDO Genie Class Diagrams (not used at runtime) 
diagram.count=1 
  
diagram0.name=Diagram 1 
diagram0.legend=600,460 
diagram0.general=13,Y,Y 
diagram0.class=Y,N,Y,N,N,Y,N,Y,N,N,N,N,N,N,N,N,N 
diagram0.field=Y,Y,N,N,N,N 
diagram0.class.count=0 
  
{别怕他长,JDOGenie自带的可视化工具可以帮助你完成} 
  
3.4 PersistenceManagerFactory Initialization 
  
       ……接上 JDOFilter代码…… 
  
      protected void initializePMF(FilterConfig fc){ 
              String propsname=(String)fc.getInitParameter(“path”); 
              Properties props=loadProperties(propsname); 
              Pmf=JDOHelper.getPersistenceManagerFactory(props); 
} 
protected Properties loadProperties(String pathName){ 
       ……. 
} 
  
3.5 PersistenceManager Initialization 
      ……接上 JDOFilter代码…… 
       protected PersistenceManager initializePM(){ 
              PersistenceManager pm=pmf.getPersistenceManager(); 
              Request.setAttribute(“jdo.PM”,pm); 
              Return pm; 
} 
protected void finalizePM(PersistenceManager pm){ 
       pm.close(); 
       request.removeAttribute(“jdo.PM”); 
} 
protected void abnormalPM(PersistenceManager pm){ 
       if(pm.currentTransaction().isActive()){ 
              pm.currentTransaction.rollback(); 
} 
pm.close(); 
request.removeAttribute(“jdo.PM”); 
} 
4.。在Actions中方问持久层数据 
        
l         Action 或者 JSP™  page都可以访问持久性数据 
l         从Request中获得PersistenceManager 
l         使用PersistenceManager 就象两层结构一样:Action整合query,然后授权相应的业务组件来具体处理应用程序的业务逻辑。 
l         持久性数据通过Request传递 
l         “一个请求一个PersistenceManager”(“PersistenceManager per Request”)模式 
4.1 Action 处理实例 
       class LookupMovieAction extends Action{ 
       protected ActionForward execute(….){ 
       PersistenceManager pm=(PersistenceManager)request.getAttribute(“jdo.PM”); 
       Query q=pm.newQuery(Movie.class,”genre==param1”); 
       q.declareParameters(“String param1”); 
       String movieName=(String)request.getParameter(“movieGenre”); 
       Object movies=q.execute(movieName); 
       Request.setAttribute(“Movies”,movies); 
       Return (mapping,findFoward(“displayMovies”)); 
} 
} 
  
4.2 事务 
l         大多的Actions 都不需要掺杂事务在里面 
-Insert,delete,update需要进行事务处理 
-其他的用nontransactional来处理 
l         JSP™ pages通常不需要事务处理 
l         如果必须进行事务处理,那么begin()和commit()将需要在Action execute()中调用 
l         如果要使用多个PersistenceManagers,那么事务将不能被调节 
-如果必须要控制事务,那么考虑使用EJB架构 
5.缺陷和误区 
  
l         不要再Action/JSP™ page中关闭PersistenceManager 
              -持久性对象是“有生命”的,关闭PersistenceManager相当于“杀死”他们。 
l         如果使用事务,那么一定要在业务方法中使用try/catch,而且要在catch或者finally中调用事务的回滚rollback(). 
l         不要在一个action中开启一个事务而在另一个action关闭它。 
l         如果要使用多个PersistenceManagers,那么必须定义多个JDOFiltes 
  
6.        略 
7.        原文作者: 
Craig Russell :the Specification Lead for Java™ Data Objects(JSR 12) at Sun Microsystems,最新的一版《Java Data Objects》的其中一位作者 
Craig McClanahan:the author and chief evangelist for the Struts framework(挑我们最熟悉的说,和和。。。) 
Amy Roh is a developer on the JSP™/Servlet team working on Tomcat 
  
原文连接: 
http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3368.pdf 
  
    不能算是翻译,如果你英文可以的话请直接阅读原文。 
   
 
  |