<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-75  評論-193  文章-5  trackbacks-0
     
         摘要:     前段時間對Spring的事務(wù)配置做了比較深入的研究,在此之間對Spring的事務(wù)配置雖說也配置過,但是一直沒有一個清楚的認(rèn)識。通過這次的學(xué)習(xí)發(fā)覺Spring的事務(wù)配置只要把思路理清,還是比較好掌握的。     總結(jié)如下:     Spring配置文件中關(guān)于事務(wù)配置總是由三個組成部分,分別是Data...  閱讀全文
    posted @ 2009-04-05 16:38 The Matrix 閱讀(332571) | 評論 (85)編輯 收藏

    今天在Javaeye的新聞頻道看到一個界面原型繪制工具,叫做“wireframesketcher”,下載試了試,感覺有如下幾個好處:

    1、使用方便,可以很容易的做tree和table,比visio中的tree和table好用

    2、集成在eclipse中,對于開發(fā)人員來說用起來更直接

    3、其界面原型文件為xml格式,可以使用比較工具比較

    唯一的缺點(diǎn):

    不是免費(fèi)開源的工具,但是現(xiàn)在可以申請免費(fèi)的license

     

    隨便畫了一個圖,如下:

    temp

     

    感興趣的兄弟姐妹們可以到如下地址看看:

    http://wireframesketcher.com/index.html

    posted @ 2009-03-28 21:55 The Matrix 閱讀(4605) | 評論 (1)編輯 收藏

    由于要寫一個Spring的培訓(xùn)教材,要做Spring的事務(wù)樣例,于是開始寫樣例,寫好了一測,控制臺有SQL輸出,數(shù)據(jù)庫卻查詢不到數(shù)據(jù),查亞查亞,花了一個多小時,原來是獲取的Service不是經(jīng)過代理的Service,自然事務(wù)不起作用,數(shù)據(jù)庫里就沒有數(shù)據(jù)了,鄙視一下自己。

    配置文件樣例如下(已經(jīng)修改了dao和service的命名,減少了寫錯的可能性,以后命名問題一定要注意):

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context
    ="http://www.springframework.org/schema/context"
        xmlns:aop
    ="http://www.springframework.org/schema/aop"
        xmlns:tx
    ="http://www.springframework.org/schema/tx"
        xsi:schemaLocation
    ="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
    >

       
    <context:annotation-config />
       
    <context:component-scan base-package="com.*" />

       
    <bean id="sessionFactory" 
                class
    ="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
           
    <property name="configLocation" value="classpath:hibernate.cfg.xml" /> 
           
    <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
       
    </bean> 

       
    <!-- 定義事務(wù)管理器(聲明式的事務(wù)) --> 
       
    <bean id="transactionManager"
            class
    ="org.springframework.orm.hibernate3.HibernateTransactionManager">
           
    <property name="sessionFactory" ref="sessionFactory" />
       
    </bean>
       
       
    <!-- 配置DAO -->
       
    <bean id="generatorDaoTarget" class="com.*.spring.dao.GeneratorDaoImpl">
           
    <property name="sessionFactory" ref="sessionFactory" />
       
    </bean>
       
       
    <bean id="generatorDao" 
            class
    ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
           
    <!-- 配置事務(wù)管理器 --> 
           
    <property name="transactionManager"><ref bean="transactionManager" /></property> 
           
    <property name="target"><ref bean="generatorDaoTarget" /></property> 
           
    <property name="proxyInterfaces"><value>com.*.spring.dao.GeneratorDao</value></property>
           
    <!-- 配置事務(wù)屬性 --> 
           
    <property name="transactionAttributes"> 
               
    <props> 
                   
    <prop key="*">PROPAGATION_REQUIRED</prop>
               
    </props> 
           
    </property> 
       
    </bean> 

       
    <bean id="plantDaoTarget" class="com.*.spring.dao.PlantDaoImpl">
           
    <property name="sessionFactory" ref="sessionFactory" />
       
    </bean>
       
       
    <bean id="plantDao" 
            class
    ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
              
    <!-- 配置事務(wù)管理器 --> 
           
    <property name="transactionManager"><ref bean="transactionManager" /></property>    
           
    <property name="target"><ref bean="plantDaoTarget" /></property> 
           
    <property name="proxyInterfaces"><value>com.*.spring.dao.PlantDao</value></property>          
           
    <!-- 配置事務(wù)屬性 --> 
           
    <property name="transactionAttributes"> 
               
    <props> 
                   
    <prop key="*">PROPAGATION_REQUIRED</prop>
               
    </props> 
           
    </property> 
       
    </bean>
       
       
    <!-- 配置Service -->
       
    <bean id="plantGeneratorServiceTarget" 
            class
    ="com.*.spring.service.PlantGeneratorServiceImpl"> 
           
    <property name="plantDao"> 
               
    <ref bean="plantDao" /> 
           
    </property> 
           
    <property name="generatorDao"> 
               
    <ref bean="generatorDao" /> 
           
    </property> 
       
    </bean>       
       
       
    <bean id="plantGeneratorService" 
            class
    ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
              
    <!-- 配置事務(wù)管理器 --> 
              
    <property name="transactionManager"><ref bean="transactionManager" /></property>    
           
    <property name="target"><ref bean="plantGeneratorServiceTarget" /></property> 
           
    <property name="proxyInterfaces"><value>com.*.spring.service.PlantGeneratorService</value></property>
           
    <!-- 配置事務(wù)屬性 --> 
           
    <property name="transactionAttributes"> 
               
    <props> 
                   
    <prop key="*">PROPAGATION_REQUIRED</prop> 
               
    </props> 
           
    </property> 
       
    </bean> 
    </beans>
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
    >

    <hibernate-configuration>

    <session-factory>

       
    <!-- 各屬性的配置-->
       
    <!-- 為true表示將Hibernate發(fā)送給數(shù)據(jù)庫的sql顯示出來 -->
       
    <property name="hibernate.show_sql">true</property>
       
    <property name="hibernate.hbm2ddl.auto">none</property> 

       
    <!-- SQL方言,這邊設(shè)定的是MySQL -->
       
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
       
    <!--連接數(shù)據(jù)庫的Driver-->
       
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
       
    <!--數(shù)據(jù)庫連接url-->
       
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property>

       
    <!--用戶名-->
       
    <property name="connection.username">root</property>
       
    <!--密碼-->
       
    <property name="connection.password">123456</property>

       
    <!-- 映射文件  -->
       
    <mapping class="com.*.spring.domain.Generator" />
       
    <mapping class="com.*.spring.domain.Plant" />
    </session-factory>
    </hibernate-configuration>
    public interface GeneratorDao {

       
    /**
         * 獲取所有機(jī)組數(shù)據(jù)
         *
    @return
        
    */
       
    public List<Generator> listGenerators();
       
       
    /**
         * 保存機(jī)組數(shù)據(jù)
         *
    @param generator 機(jī)組數(shù)據(jù)
        
    */
       
    public void save(Generator generator);   
    }
    public class GeneratorDaoImpl extends HibernateDaoSupport implements GeneratorDao {
          
        @SuppressWarnings(
    "unchecked")
       
    public List<Generator> listGenerators() {
           
    return this.getSession().createQuery("from Generator").list();
        }

       
    public void save(Generator generator) {
           
    this.getSession().save(generator);   
        }
    }
    posted @ 2009-03-16 22:24 The Matrix 閱讀(1550) | 評論 (0)編輯 收藏

        給自己做的這個程序起了個名字叫EasyWork,代碼可以從Google Code上下載,具體地址如下:

      http://easywork.googlecode.com/svn/trunk/

      由于時間關(guān)系,這個程序還存在不少問題,所以只能供大家參考,有問題不要罵我就行了:)

      簡要使用說明:

      1、開發(fā)環(huán)境+運(yùn)行環(huán)境:MyEclipse6.0,JDK1.5,Tomcat6.0.14,MySQL5.0

      2、準(zhǔn)備好上述環(huán)境后,使用下載代碼sql目錄中的easywork_init.sql腳本創(chuàng)建數(shù)據(jù)庫表和初始數(shù)據(jù)。

      3、將項(xiàng)目導(dǎo)入Eclipse后,運(yùn)行Tomcat(此過程就不詳細(xì)描述了)。

      4、使用http://localhost/easywork/system/login.jsp訪問登錄頁面,目前還沒有做index.html,默認(rèn)用戶名/密碼:admin/1。

     

      存在問題如下:

      1、任務(wù)管理功能還沒有完全完成,日志記錄還沒有做。

      2、超時或者沒有登錄訪問頁面時,只是報(bào)不能訪問的異常,沒有轉(zhuǎn)入登錄頁面。

      3、對資源類型(菜單、URL、字段、操作)的訪問限制還沒有做。

      4、很多界面的輸入信息校驗(yàn)沒有做。

      5、基本沒有美工。

      6、總而言之,目前這個項(xiàng)目中的代碼只能做Struts2 + ExtJS如何使用的借鑒:)

    posted @ 2009-03-01 11:03 The Matrix 閱讀(6285) | 評論 (28)編輯 收藏

        很近沒有更新BLog了,這一陣子忙著學(xué)習(xí)Struts2和ExtJS,使用這兩者做了一個小程序,使用RBAC實(shí)現(xiàn)了基本的權(quán)限管理功能,還做了一個任務(wù)管理和日志記錄,任務(wù)管理用于記錄當(dāng)前需要處理的事情,日志記錄用于記錄每天的工作情況。

        用下來Struts2和ExtJS還是挺好用的。先貼幾張圖,后續(xù)再把學(xué)習(xí)過程中遇到的問題整理出來。

    任務(wù)管理

    task

    添加組

    addgroup

    添加權(quán)限

    addprivilege

    添加角色

     addrole

    posted @ 2009-02-26 07:14 The Matrix 閱讀(4333) | 評論 (15)編輯 收藏

        由于前段時間使用JSF做了一個項(xiàng)目,不少使用JSF的兄弟們對JSF評價(jià)并不好,因此在學(xué)習(xí)的過程中一直在想,JSF究竟是不是應(yīng)該繼續(xù)學(xué)習(xí)繼續(xù)研究使用下去,在看完Seam In Action的第三章后,這個星期又對Struts2簡單學(xué)習(xí)了一下,終于決定結(jié)束JSF和JBoss Seam的學(xué)習(xí)了。

        因?yàn)閺腏SF的學(xué)習(xí)和Struts2的學(xué)習(xí)對比中明顯覺得JSF復(fù)雜,對于一個技術(shù)力量不是非常強(qiáng)的項(xiàng)目組來說,使用JSF當(dāng)你遇到一些問題時,絕對是一件痛苦的事情。

        從自己的實(shí)踐中覺得JSF至少有兩個致命傷:

        1、覺得JSF貌似把簡單的事情搞得復(fù)雜化了,在傳統(tǒng)的MVC框架如Struts中,從request中獲取param很容易,也可以將param封裝為對象,在JSF中,希望將這一切都模型化,一切都以組件為中心,類似于Swing的架構(gòu),但是http的無狀態(tài)以及web的本質(zhì),使得一般JSF只能將組件樹存放在服務(wù)端,同時又不能象CS程序那樣方便的查看組件的狀態(tài)、屬性等信息。對于通常情況來說,JSF將其封裝的很好,不用我們開發(fā)者操心,但是當(dāng)遇到一些問題時,對于開發(fā)者想去調(diào)試查看問題時,問題就顯得很復(fù)雜了。

        2、JSF的自定義組件感覺超復(fù)雜,難度應(yīng)該比當(dāng)年自定義JSP標(biāo)簽更要高,試想一下,如果哪個組件不合意了,想改一下,還是比較困難的,除非對JSF組件有相當(dāng)?shù)纳钊肓私狻?/p>

        順便把項(xiàng)目中遇到的一個RichFaces的缺點(diǎn)列出來:

        RichFaces在生成組件的html時,大量使用了Div,曾經(jīng)有過一個頁面有1千多行(在一個table中),頁面上還有一個RichFaces的下拉菜單,從而導(dǎo)致菜單響應(yīng)非常之慢,后來只有將rich:datatable換為普通的html:table,就沒有問題了。

        再看看Seam In Action中總結(jié)的JSF的缺點(diǎn):

        1、在JSF中初次請求的處理流程太過簡單,而后續(xù)請求則執(zhí)行了完整的復(fù)雜的處理流程。在JSF中假設(shè)第一個調(diào)用應(yīng)該是在頁面被渲染后執(zhí)行,但實(shí)際中有時我們需要在第一次請求時就執(zhí)行某些操作。在JSF中缺少象Struts中的Controller。

        2、所有的請求都是POST。瀏覽器處理POST請求是比較草率,當(dāng)用戶執(zhí)行了一個JSF Action操作后,點(diǎn)擊瀏覽器的刷新按鈕時,瀏覽器會詢問用戶是否重新提交,這會令用戶非常困惑。

        3、僅僅擁有簡單基礎(chǔ)的頁面導(dǎo)向機(jī)制。

        4、過度復(fù)雜的生命周期。

        JBossSeam宣稱對于JSF存在的缺點(diǎn)都提供了解決方法,但是有一種更復(fù)雜的感覺。

        在Seam中,生成選擇的項(xiàng)目時,有EAR和WAR的選項(xiàng),如果選擇了EAR選項(xiàng),那么Seam會生成四個項(xiàng)目,分別為war、ear、ejb、test四個類型的項(xiàng)目。有一次我將生成的項(xiàng)目從一個目錄拷貝到另一個目錄,切換了Eclipse的workspace,此時問題來了,ejb項(xiàng)目提示編譯錯誤,提示無法找到某些class,找來找去找來找去......后來將項(xiàng)目關(guān)閉了一下,再打開錯誤提示就沒有了。

        由這個問題我忽然想到,使用Seam集成JSF、EJB是不是太重量級了,如果采用EJB作為替代普通的POJO,對于一個小型的項(xiàng)目組來說,一般的規(guī)模就是三至五個人(我個人的理解),開發(fā)人員本來就不多,還要面對Seam劃分的四個項(xiàng)目,好像比較繁瑣,當(dāng)然采用war模式另當(dāng)別論。

        相比較而言,這個星期看了一些Struts2的資料,覺得Struts2的架構(gòu)非常清晰,易于理解。

        翻了很早之前的JavaEye上的一個帖子,提到JSF是面向開發(fā)工具的,如果能做到象VB那樣,就大有前途了,4年過去了,不要提JSF的開發(fā)工具了,就是Java各個方面的GUI開發(fā)工具,又有哪個能和VB相比呢,看來選擇JSF作為一個方向不是一個好選擇........還是及早放棄吧,哎...


        最后我覺得可以用這么一句話可以形容JSF,看起來很美,用起來不爽。

    posted @ 2008-12-25 23:35 The Matrix 閱讀(2329) | 評論 (6)編輯 收藏

    這個事情去年做過一次,不過沒有留下記錄,今天又要做一次,記錄下來,呵呵

    環(huán)境:

    Spring版本為1.2,Tomcat為5.5.26,JDK為Jdk1.5.0_11。

    1、下載Axis1.4,解壓后將其jar文件添加到web項(xiàng)目的lib目錄中。

    2、配置Axis Servlet,在web.xml文件中加入如下信息:

    <servlet>
       
    <servlet-name>AxisServlet</servlet-name>
       
    <servlet-class>
            org.apache.axis.transport.http.AxisServlet
       
    </servlet-class>
    </servlet>

    <servlet-mapping>
       
    <servlet-name>AxisServlet</servlet-name>
       
    <url-pattern>/servlet/AxisServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
       
    <servlet-name>AxisServlet</servlet-name>
       
    <url-pattern>*.jws</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
       
    <servlet-name>AxisServlet</servlet-name>
       
    <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

     
    3、編寫java類,樣例如下。

    接口:

    public interface InterchangeDataService {
       
    public String getMonthInterchange(String marketDate);
    }

    實(shí)現(xiàn)類:

    public class InterchangeDataServiceImpl extends ServletEndpointSupport implements InterchangeDataService {

       
    public InterchangeDataServiceImpl() {
        }

       
    public String getMonthInterchange(String marketDate) {
            
    return "getMonthInterchange";
        }

    }

    注意實(shí)現(xiàn)類需要繼承ServletEndpointSupport類,該類是由Spring提供的。


    4、配置service-config.wsdd。

    <?xml version="1.0" encoding="utf-8"?>
    <deployment xmlns="http://xml.apache.org/axis/wsdd/"
        xmlns:java
    ="http://xml.apache.org/axis/wsdd/providers/java">
       
    <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
       
    <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
       
    <service name="interchangeDataService" provider="java:RPC" style="rpc" use="literal">
           
    <parameter name="wsdlTargetNamespace" value="urn:soap.axisspring"/>
           
    <parameter name="className" value="com.ecgit.eccm.webservice.InterchangeDataServiceImpl"/>
           
    <parameter name="allowedMethods" value="*"/>
       
    </service>
       
    <transport name="http">
           
    <requestFlow>
               
    <handler type="URLMapper"/>
               
    <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
           
    </requestFlow>
           
    <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
           
    <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
           
    <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
       
    </transport>
       
    <transport name="local">
           
    <responseFlow>
               
    <handler type="LocalResponder"/>
           
    </responseFlow>
       
    </transport>
    </deployment>

     
    5、測試web service服務(wù),代碼如下。

    至項(xiàng)目的WEB-INF目錄下,執(zhí)行如下命令:

    Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/interchangeDataService?WSDL

    會在WEB-INF目錄中生成四個JAVA文件,它們分別是:

    • InterchangeDataServiceImpl.java   定義了Web服務(wù)接口,接口中的方法與InterchangeDataService中的方法一致。
    • InterchangeDataServiceImplService.java 定義了用于獲取Web服務(wù)接口的方法。
    • InterchangeDataServiceImplServiceLocator.java 接口InterchangeDataServiceImplService的具體實(shí)現(xiàn)。
    • InterchangeDataServiceImplSoapBindingStub.java Web服務(wù)客戶端樁,通過該類與服務(wù)器交互。

    最后編寫一個Main方法,調(diào)用如下方法即可進(jìn)行測試:

    InterchangeDataServiceImplServiceLocator serviceLocator = new InterchangeDataServiceImplServiceLocator();
    InterchangeDataServiceImpl service
    = serviceLocator.getinterchangeDataService();
    String monthSchedule
    = service.getMonthInterchange("2008-05-30");
    posted @ 2008-12-19 17:16 The Matrix 閱讀(3415) | 評論 (1)編輯 收藏

        上次使用Seam自動生成了一個CRUD的例子,后來想還是自己白手起家做一個例子看看,于是開始動手。

        首先使用JBossTools工具生成項(xiàng)目,在生成項(xiàng)目的向?qū)е校绻?xiàng)目類型選擇ear,則會生成四個項(xiàng)目,分別對應(yīng)war、ear、ejb、test,覺得這樣太過繁瑣,還是選擇war類型,又想要不使用tomcat作為運(yùn)行服務(wù)器吧,因?yàn)镴Boss也不太熟悉。沒想到這一試倒試出問題來了,如果完全使用向?qū)身?xiàng)目,選擇tomcat作為運(yùn)行服務(wù)器,則項(xiàng)目根本無法運(yùn)行起來,總是提示缺少這個jar,那個jar。好,又換回JBoss,沒問題了。仔細(xì)看了一下,原來在自動生成項(xiàng)目的WebContent/WEB-INF/lib目錄中,只有大概十幾個jar,連Hibernate的jar都沒有,而在JBoss的Server/default/lib目錄下則什么jar都有,怪不得不出錯。

    第一個教訓(xùn):還是先使用JBoss作為運(yùn)行環(huán)境,等整個Seam都搞熟了,再配一個Tomcat的運(yùn)行環(huán)境。

        繼續(xù),將原來項(xiàng)目中的一個通用DAO和一個UserService拷貝過來,代碼如下,啟動服務(wù)器報(bào)錯。分別為如下錯誤信息:

    第二個錯誤解決:Caused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao

        既然提示@PersistenceContext只能用在SessionBean中,因?yàn)樵瓉淼拇a是使用的Spring框架,想了好長時間,在WebContent/WEB-INF/component.xml中看到這么一段,那么是不是通過@In來注入entityManager呢,修改@PersistenceContext為@In,編輯器自動提示沒有發(fā)現(xiàn)名稱為em的Component(這點(diǎn)好像不錯),于是再修改為@In("entityManager") ,重啟服務(wù)器,該問題解決。

    <persistence:managed-persistence-context name="entityManager" auto-create="true" entity-manager-factory="#{testEntityManagerFactory}"/>

    第三個錯誤解決:Caused by org.jboss.seam.RequiredException with message: "@In attribute requires non-null value: userService.genericDao"

        將UserService中的@In修改為@In(create = true, required = true)解決此問題。

        解決上述幾個問題后,自己的例子終于運(yùn)行起來了 :-)

        下一篇關(guān)于Seam In Action中對JSF的介紹及Seam如何增強(qiáng)JSF。

    -------------------------------------------------------------------------------------------------

        項(xiàng)目生成的代碼被分為兩個目錄,分別為Action和Model目錄,檢查JBoss中項(xiàng)目部署的目錄,發(fā)覺Action目錄下的代碼編譯生成的class文件被存放至WEB-INF/dev目錄下,Model目錄下的代碼編譯生成的class文件被存放至WEB-INF/classes目錄下,google了一下,發(fā)現(xiàn)在Seam Reference中提到這是Seam的增量式重部署,支持對JavaBean組件的增量重部署,可以加快編輯/編譯/測試的速度。

    代碼如下:

    public interface GenericDao {
        public Object get(Class clazz, Serializable id);
        public
    void save(Object object);
        public
    void update(Object object);
        public
    void remove(Class clazz, Serializable id);
        public
    void remove(Object obj);
       
    }


    @Name("genericDao")
    public class GenericDaoImpl implements GenericDao {
        @PersistenceContext 
    ---->   @In("entityManager")
        private EntityManager em;

        public Object get(Class clazz, Serializable id) {
           
    if (id == nullreturn null;
           
    else return em.find(clazz, id);
        }
       
    }


    public interface UserService {
        public
    void findAllUsers();
    }

    @Name(
    "userService")
    public class UserServiceImpl implements UserService, SecurityUserService {

        @In
    ----> @In(create = true, required = true)
        protected GenericDao genericDao;
        private List
    <User> resultList = null;

        public List
    <User> getResultList() {
           
    if (resultList == null) {
               
    this.findAllUsers();
            }
           
    return resultList;
        }

        public
    void setResultList(List<User> resultList) {
           
    this.resultList = resultList;
        }


        public
    void findAllUsers() {
            String hql
    = "from User order by userCode";
            resultList
    = this.genericDao.query(hql);
        }
    }

    // 實(shí)體類
    @Entity
    @Table(name = "USER")
    public class User implements IUser, Serializable {
        // 用戶編碼
        @Id
        private String userCode;

        // 用戶姓名
        private String userName;
    }


    <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
        xmlns:s
    ="http://jboss.com/products/seam/taglib"
        xmlns:ui
    ="http://java.sun.com/jsf/facelets"
        xmlns:f
    ="http://java.sun.com/jsf/core"
        xmlns:h
    ="http://java.sun.com/jsf/html"
        xmlns:rich
    ="http://richfaces.org/rich"
        template
    ="layout/template.xhtml">

    <ui:define name="body">
       
    <rich:panel>
           
    <f:facet name="header">User Search Results</f:facet>
           
    <rich:dataTable id="userServiceTable"
                       
    var="user"
                      value
    ="#{userService.resultList}">
               
    <h:column>
                   
    <f:facet name="header">
                       
    <h:outputText value="UserCode"/>
                   
    </f:facet>
                   
    <h:outputText value="#{user.userCode}"/>
               
    </h:column>
               
    <h:column>
                   
    <f:facet name="header">
                       
    <h:outputText value="UserName"/>
                   
    </f:facet>
                   
    <h:outputText value="#{user.userName}"/>
               
    </h:column>
           
    </rich:dataTable>
          
    </rich:panel>
    </ui:define>
    </ui:composition>

    通過這個實(shí)踐,小結(jié)一下:

    1、發(fā)覺Seam確實(shí)簡化了JSF開發(fā),但由于它涉及的新東西相對較多,與傳統(tǒng)的SSH走的路線不太一致,還是覺得其學(xué)習(xí)曲線比較陡峭,需要對Seam熟練掌握后(包括開發(fā)環(huán)境的搭建等)才能真正提高開發(fā)效率。

    2、Seam提供了IOC的功能,有時需要跳出Spring,從一個新的角度去審視Seam。

    posted @ 2008-12-18 23:46 The Matrix 閱讀(2165) | 評論 (0)編輯 收藏

        這個星期的后半周主要搞了kettle的試驗(yàn),做了兩個例子出來,在后續(xù)工作中這兩個例子應(yīng)該也能派上用場,本來以為kettle的文檔不多,后來單獨(dú)下載了kettle的doc壓縮包,發(fā)覺里面的內(nèi)容還是不少的,真要將kettle搞熟的話,這些文檔還是需要仔細(xì)研讀一番的。另外kettle doc解壓后文檔目錄挺奇怪的,都是數(shù)字命名的目錄名,不知有啥具體含義。

        下周的學(xué)習(xí)重點(diǎn)還是要轉(zhuǎn)回到JBoss Seam中了 :-)

    posted @ 2008-12-14 22:13 The Matrix 閱讀(1277) | 評論 (3)編輯 收藏

    需求:

    kettletest1數(shù)據(jù)庫中有table_source數(shù)據(jù)表,結(jié)構(gòu)如下:

    1. Id                主鍵
    2. t_id             數(shù)據(jù)時間
    3. part_id        實(shí)例ID
    4. yg               數(shù)據(jù)字段1
    5. wg              數(shù)據(jù)字段2

    該表中的數(shù)據(jù)對于不同的實(shí)例ID,一分鐘一條數(shù)據(jù),t_id字段表示數(shù)據(jù)的時間,精確到分鐘。

    kettletest2數(shù)據(jù)庫中有table_target數(shù)據(jù)表,結(jié)構(gòu)如下:

    1. Id                     主鍵
    2. marketdate      數(shù)據(jù)日期,格式為 yyyy-MM-dd
    3. pointtime        時間,格式為 HH:mm
    4. pointnumber   時間的數(shù)字表示,00:01表示為1,00:00表示為1440
    5. plantcode        實(shí)例Code
    6. yg                    數(shù)據(jù)字段1
    7. wg                   數(shù)據(jù)字段2

    需定期將table_source表中的數(shù)據(jù)獲取至table_target表中,并進(jìn)行如下處理:

    1、將t_id數(shù)據(jù)時間字段拆分為三個字段,分別為marketdate、pointtime、pointnumber。

            a、marketdate取t_id的日期部分。
            b、pointtime取t_id的時間部分。
            c、pointnumber為時間的數(shù)字表示,等于hour*60+minute。
            d、但當(dāng)t_id的時間為某日的00:00時,需將其轉(zhuǎn)化為24:00,并且marketdate需取日期的前一天。如t_id為2008-12-04 00:00,則marketdate為2008-12-03,pointtime為24:00,pointnumber為1440。

    2、將part_id字段映射為plantcode字段,并根據(jù)如下規(guī)則進(jìn)行轉(zhuǎn)換:
            part_id                 plantcode
             3206                        P01
             3207                        P02
             3208                        P03

    測試中使用的數(shù)據(jù)庫均為mysql數(shù)據(jù)庫。

    實(shí)戰(zhàn):

    整個轉(zhuǎn)換工作共分為三個步驟,如下圖:

    job

    1、定義需獲取的數(shù)據(jù)的日期

    trans1

    2、刪除table_target表中已有數(shù)據(jù),注意一定要將“執(zhí)行SQl語句”面板中的“變量替換”要選上,否則SQL語句中的變量不會被替換,我剛開始沒注意到這個地方,找問題找了半天。

    trans2

    3、獲取table_source中的數(shù)據(jù),并將其插入table_target表

    trans3

            3-1、獲取table_source表的數(shù)據(jù)

    trans3-1

            3-2、值映射

    trans3-2

            3-3、字段選擇

    trans3-3

            3-4、對t_id字段進(jìn)行處理,增加了pointnumber字段。在這一步驟中發(fā)現(xiàn)kettle的一個bug,就是不能在JavaScript中使用str2date函數(shù),錯誤的具體信息參見:http://jira.pentaho.com/browse/PDI-1827。這個問題也折騰了好長時間,剛開始怎么也想不通這個函數(shù)使用時怎么會報(bào)錯呢,后來只好從字符串中截取年、月、日信息。

           該步驟中還存在另外一個使人困惑的問題,就是點(diǎn)擊“測試腳本”按鈕,會報(bào)錯,但是執(zhí)行job和transformation時則不會報(bào)錯。

    trans3-4

            3-5、增加pointnumber字段至輸出結(jié)果中

    trans3-5

            3-6、插入數(shù)據(jù)至table_target表

    trans3-6

     

    3-4步驟中的JavaScript代碼如下:

    var pointTimeStr = pointtime.getString();
    var pointnumber = 1;

    if (pointTimeStr == "00:00") {

       
    var marketDateStr = marketdate.getString();
       
    var marketDateYear = substr(marketDateStr, 0, 4);
       
    var marketDateMonth = str2num(substr(marketDateStr, 5, 2))-1;
       
    var marketDateDay = substr(marketDateStr, 8, 2);

       
    var date = new Date();
        date.setYear(marketDateYear);
        date.setMonth(marketDateMonth);
        date.setDate(marketDateDay);

       
    var temp1 = dateAdd(date, "d", -1);
        marketdate.setValue(date2str(temp1,
    "yyyy-MM-dd"));
        pointtime.setValue(
    "24:00");

        pointnumber
    = 1440;
    }
    else {   
       
    var hourStr = pointTimeStr.substr(0, 2);
       
    var hour = str2num(hourStr);
       
    var minuteStr = pointTimeStr.substr(3, 5);
       
    var minute = str2num(minuteStr);
       
        pointnumber
    = hour * 60 + minute;
    }

     

    至此,整個轉(zhuǎn)換工作完成,小結(jié)一下:

        如果對kettle等etl工具比較熟悉的話,使用etl工具進(jìn)行數(shù)據(jù)轉(zhuǎn)換、抽取等事情還是比較方便的,比起寫程序還是有優(yōu)勢的。但是這個轉(zhuǎn)換過程中遇到的kettle的兩個bug比較讓人頭疼,覺得kettle好像還不是很穩(wěn)定。

    posted @ 2008-12-14 21:55 The Matrix 閱讀(34331) | 評論 (5)編輯 收藏

    這個實(shí)踐其實(shí)不難,主要是有一個地方要注意,就是文件名通配符的寫法,如果文件名格式為“TRANS_yyyymmdd.txt”,如TRANS_20081101.txt。如果想匹配所有以TRANS開頭的文本文件,在kettle中要寫成這樣:TRANS_.*[0-9].txt。

    最后在windows操作系統(tǒng)中配置定時任務(wù)就可以定期執(zhí)行該Job了。

    Job的圖:

    total

    FTP配置信息:

    get ftp config put ftp config

    posted @ 2008-12-12 15:20 The Matrix 閱讀(17069) | 評論 (0)編輯 收藏

    一定要給SQL Server2000打上sp3a補(bǔ)丁,打上補(bǔ)丁后,使用telnet訪問1433端口一切正常。

    另外學(xué)了一個查詢SQL Server版本的語句:select @@version

    posted @ 2008-12-12 12:07 The Matrix 閱讀(1446) | 評論 (1)編輯 收藏

    DATE_FORMAT(date,format)
    根據(jù)format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December)
    %W 星期名字(Sunday……Saturday)
    %D 有英語前綴的月份的日期(1st, 2nd, 3rd, 等等。)
    %Y 年, 數(shù)字, 4 位
    %y 年, 數(shù)字, 2 位
    %a 縮寫的星期名字(Sun……Sat)
    %d 月份中的天數(shù), 數(shù)字(00……31)
    %e 月份中的天數(shù), 數(shù)字(0……31)
    %m 月, 數(shù)字(01……12)
    %c 月, 數(shù)字(1……12)
    %b 縮寫的月份名字(Jan……Dec)
    %j 一年中的天數(shù)(001……366)
    %H 小時(00……23)
    %k 小時(0……23)
    %h 小時(01……12)
    %I 小時(01……12)
    %l 小時(1……12)
    %i 分鐘, 數(shù)字(00……59)
    %r 時間,12 小時(hh:mm:ss [AP]M)
    %T 時間,24 小時(hh:mm:ss)
    %S 秒(00……59)
    %s 秒(00……59)
    %p AM或PM
    %w 一個星期中的天數(shù)(0=Sunday ……6=Saturday )
    %U 星期(0……52), 這里星期天是星期的第一天
    %u 星期(0……52), 這里星期一是星期的第一天
    %% 一個文字“%”。

    posted @ 2008-12-10 09:18 The Matrix 閱讀(737) | 評論 (0)編輯 收藏

            看了Seam的例子,也看了Seam的簡介,禁不住手癢,還是先做一個例子吧,遵照《seam_reference》第三章中的指導(dǎo),使用JBossTool生成了自己的第一個例子,過程如下:

    1、生成Sem web項(xiàng)目

    step1

    2、輸入項(xiàng)目的相關(guān)信息,如下圖:

    step2

          注意,如果是第一次使用Eclipse,需要配置Target Runtime和Target Server。

    3、然后一路next,到最后一步時,如果是第一次使用,也要注意配置Seam Runtime和Connection Profile,如下圖。最后點(diǎn)擊finish按鈕,即可創(chuàng)建Seam項(xiàng)目。

    step3

    4、生成項(xiàng)目后,在Eclipse中共出現(xiàn)了四個項(xiàng)目,如下:

    • seamfirst (web項(xiàng)目)
    • seamfirst-ear (ear項(xiàng)目,集成web和ejb)
    • seamfirst-jar (ejb項(xiàng)目)
    • seamfirst-test (測試項(xiàng)目,進(jìn)行單元測試)

          此時運(yùn)行JBossServer服務(wù)器,訪問http://localhost:8080/seamfirst鏈接,出現(xiàn)如下圖頁面,此時Seam幫我們生成了一個框架,包含了基本的登錄和退出功能,還有一個首頁。

    step5

    5、繼續(xù)!使用Seam生成單表的CRUD操作。本步驟前提,有一個mysql數(shù)據(jù)庫,數(shù)據(jù)庫中有一個Customer表,該表有ID(int類型)、customername(varchar2類型)、customerdesc(varchar2類型)、createdate(date類型)、email(varchar2類型)五個字段。在seamfirst項(xiàng)目上點(diǎn)擊右鍵,選擇Seam Generate Entities菜單,彈出界面如下圖:

    step6

    step7

          單擊finish按鈕后,再運(yùn)行JBoss Server服務(wù)器,訪問http://localhost:8080/seamfirst,發(fā)覺菜單欄上多了一個Customer List菜單,單擊此鏈接,即可進(jìn)行Customer的添加、刪除、修改、查詢操作,雖然生成的界面不是很好看,也不是很符合我自己的操作習(xí)慣,但是功能倒是完備。

          以后若是修改了Seam提供的代碼自動生成的模板,然后再使用該功能,想必生成的頁面就符合自己的項(xiàng)目要求了,記下一筆,先不管它。

     

    生成的代碼分析:

    生成的代碼主要有兩部分,一部分為Java代碼,一部分為頁面代碼。

    Java代碼包括如下三個類:

    • Customer.java ---- 實(shí)體類,映射到數(shù)據(jù)庫中的Customer表。
    • CustomerHome.java ---- SessionBean,提供了Customer類的創(chuàng)建、更新、刪除功能。繼承了org.jboss.seam.framework.EntityHome類,EntityHome類中提供創(chuàng)建、更新、刪除等基本功能。
    • CustomerList.java ---- SessionBean,提供了Customer類的查詢功能。繼承了org.jboss.seam.framework.EntityQuery類,EntityQuery類中提供了查詢功能。

          CustomerHome和CustomerList類中都使用了@Name annotation,這樣在頁面中就可以直接訪問Session Bean中的方法了,達(dá)到了Seam將表現(xiàn)層和業(yè)務(wù)層直接融合的目標(biāo)。

    頁面代碼包括如下文件:

    • Customer.xhtml
    • Customer.page.xml
    • CustomerEdit.xhtml
    • CustomerEdit.page.xml
    • CustomerList.xhtml
    • CustomerList.page.xml

          剛開始看這段代碼時,困惑我的有兩個地方

    • 一個是CustomerList.xhtml中rich:dataTable的value為"#{customerList.resultList}",customerList我明白指的是CustomerList SessionBean,但是我看遍了其代碼,也沒有發(fā)現(xiàn)有resultList屬性,后來仔細(xì)一看,才發(fā)覺該屬性在其父類EntityQuery中。
    • 另一個是每一個xhtml文件都有一個對應(yīng)的page.xml文件,想了半天也沒整明白這是怎么回事,后來只好繼續(xù)看Seam in Action的第三章,看著看著終于明白了,原來這是Seam對JSF的一個擴(kuò)展,增強(qiáng)了JSF的功能,具體含義后面詳細(xì)解釋。

    至此第一個使用JBossTools生成的Seam例子完成了,好像很簡單 :-)

    posted @ 2008-12-09 22:40 The Matrix 閱讀(2137) | 評論 (1)編輯 收藏

    需求:Oracle的數(shù)據(jù)庫文件都存放在C盤,由于數(shù)據(jù)文件越來越大,所以想把一些數(shù)據(jù)文件移至D盤

    環(huán)境:Oracle9i

    操作步驟:

    1. sqlplus /nolog
    2. connect / as sysdba;
    3. shutdown immediate;
    4. startup mount;
    5. alter database rename file 'c:\ora92\oradata\trans\trans.dbf' to 'd:\ora92\oradata\trans\trans.dbf';
    6. alter database open;
    注意點(diǎn):
    • temp表空間的數(shù)據(jù)文件不能移動

     

    附Oracle的幾種啟動方式

    1、startup nomount

      非安裝啟動,這種方式啟動下可執(zhí)行:重建控制文件、重建數(shù)據(jù)庫。

      讀取init.ora文件,啟動instance,即啟動SGA和后臺進(jìn)程,這種啟動只需要init.ora文件。

    2、startup mount dbname

      安裝啟動,這種方式啟動下可執(zhí)行:數(shù)據(jù)庫日志歸檔、數(shù)據(jù)庫介質(zhì)恢復(fù)、使數(shù)據(jù)文件聯(lián)機(jī)或脫機(jī)、重新定位數(shù)據(jù)文件、重做日志文件。

      執(zhí)行“nomount”,然后打開控制文件,確認(rèn)數(shù)據(jù)文件和聯(lián)機(jī)日志文件的位置,但此時不對數(shù)據(jù)文件和日志文件進(jìn)行校驗(yàn)檢查。

    3、startup open dbname

      先執(zhí)行“nomount”,然后執(zhí)行“mount”,再打開包括Redo log文件在內(nèi)的所有數(shù)據(jù)庫文件,這種方式下可訪問數(shù)據(jù)庫中的數(shù)據(jù)。

    4、startup,等于以下三個命令

      startup nomount

      alter database mount

      alter database open

    posted @ 2008-12-09 10:16 The Matrix 閱讀(2767) | 評論 (1)編輯 收藏

    用JBossTools生成項(xiàng)目,生成CRUD的代碼,然后訪問就報(bào)了如下異常:

    Exception during request processing:

    Caused by java.lang.IllegalStateException with message: "No phase id bound to current thread (make sure you do not have two SeamPhaseListener instances installed)"

    org.jboss.seam.contexts.PageContext.getPhaseId(PageContext.java:163)
    org.jboss.seam.contexts.PageContext.isBeforeInvokeApplicationPhase(PageContext.java:175)
    org.jboss.seam.contexts.PageContext.getCurrentWritableMap(PageContext.java:91)
    org.jboss.seam.contexts.PageContext.remove(PageContext.java:105)
    org.jboss.seam.Component.newInstance(Component.java:2102)
    org.jboss.seam.Component.getInstance(Component.java:1987)
    org.jboss.seam.Component.getInstance(Component.java:1966)
    org.jboss.seam.Component.getInstance(Component.java:1960)
    org.jboss.seam.Component.getInstance(Component.java:1933)
    org.jboss.seam.Component.getInstance(Component.java:1928)
    org.jboss.seam.faces.FacesPage.instance(FacesPage.java:92)
    org.jboss.seam.core.ConversationPropagation.restorePageContextConversationId(ConversationPropagation.java:84)
    org.jboss.seam.core.ConversationPropagation.restoreConversationId(ConversationPropagation.java:57)
    org.jboss.seam.jsf.SeamPhaseListener.afterRestoreView(SeamPhaseListener.java:389)
    org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:228)
    org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:194)
    com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:175)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:114)
    com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
    com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
    org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
    org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
    org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
    org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
    org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:54)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
    org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
    java.lang.Thread.run(Thread.java:619)
    Google了一下,有人講是JBoss4.2.3GA版本的BUG,趕緊下載了JBoss4.2.2GA,再測試一切正常!
    不知還會不會有其它莫名的BUG了......
    posted @ 2008-12-07 22:03 The Matrix 閱讀(1028) | 評論 (0)編輯 收藏

            把環(huán)境配好之后,Seam的例子也運(yùn)行起來了,看了seam_reference第一章中如下幾個例子講解:

    • the registration example
    • the messages example
    • the todo list example
    • the numberguess example

            又在滿江紅的網(wǎng)站上找了seam_reference2.0的中文文檔,主要看了《the contextual component model》一章,看完以后感覺Seam最核心的地方就是其contextual component model了,不過看完這一章以后只是對Seam有個大概的了解,對其具體的內(nèi)容,細(xì)節(jié)還缺乏進(jìn)一步的了解,對其優(yōu)點(diǎn)、缺點(diǎn)也缺乏進(jìn)一步的認(rèn)識。

            然后又找到了《Seam in Action》的電子書,看了一點(diǎn)之后還是覺得這本電子書寫得好,內(nèi)容組織的很好,不象seam_reference后面的章節(jié)僅僅是羅列seam的各項(xiàng)功能。

            今天把Seam in Action的第一章草草看了一遍,將第一章講述的內(nèi)容總結(jié)如下:

    1、什么是Seam

            在Seam in Action中,沒有將Seam稱之為web framework,而是將其稱為application stack。Seam將Java EE中的EJB3、JSF、JPA/Hibernate、JAAS等技術(shù)融合在一起,提供了更容易使用的方式,比如conversation、page flows、buisness precesses、rule-based security、JavaScript(Ajax) remoting、PDF rendering、email組合、charting、file uploads、Groovy integration等,用以簡化web開發(fā)。

    2、Seam的目標(biāo)

            簡化web開發(fā)

    3、Seam如何集成各類技術(shù)

        selected Seam集成了JSF、JPA和POJO Component

    selected1 在Seam中將EJB3.0中的Session Bean作為JSF的managed bean,直接將表現(xiàn)層和業(yè)務(wù)層銜接在一起,使得Session Bean可以直接訪問web相關(guān)數(shù)據(jù),比如request、session、application、JSF的FacesMessage、Component Tree等。而在不使用Seam時,一般都是使用JSF back bean來作為表現(xiàn)層和業(yè)務(wù)層之間的中介。

    selected1 使用annotation中的@Name標(biāo)注替代了JSF的faces-config.xml中關(guān)于managed bean的配置。

    selected1 Seam不一定必須使用EJB和JPA,也可以使用POJO、Hibernate作為替代。如下圖:

    seam 

        selected 上下文相關(guān)的組件模型(Seam中的核心概念)

    selected1 Seam提供了7種類型的上下文,其中屬于Seam特有的兩種上下文類型分別為:Conversation Context、Business process Context。

    selected1 Seam提供了統(tǒng)一的組件注冊、annotation、異常配置、方法攔截、統(tǒng)一的EL表達(dá)式等功能。其中Seam對其管理的組件攔截過程如下圖:

    seam1

    4、Seam的核心競爭力

        selected 更好的JSF

    selected1 增強(qiáng)的JSF

    • Seam對JSF最被認(rèn)可的改進(jìn)就是消除了在配置文件中聲明managed bean。
    • Prerender page actions
    • Managed request parameters (for a given page)
    • Intelligent stateless and stateful navigation
    • Transparent JSF data model and data model selection handling
    • Fine-grained exception handling
    • Page-level security (per view ID)
    • 基于Annotation的表單驗(yàn)證
    • Bookmarkable command links (solving the “everything is a POST” problem)
    • Entity converter for pick lists
    • Conversation controls
    • Support for preventing lazy initialization exceptions and nontransactional data access in the view

    selected1 消除了連接Bean(ELIMINATING CONNECTOR BEANS)

          用一幅圖可以很好的說明這句話的含義

    seam2

    selected1 引入了有狀態(tài)的變量范圍(INTRODUCING STATEFUL VARIABLE SCOPES)

    seam3

    selected1 擴(kuò)展的Persistence Context

          Spring中提供了The Session In View Filter,使得persistence manage可以在一個請求中存在,避免了常見的LazyInitializationException。在Seam中,擴(kuò)展的Persistence Context可以跨越多個請求。其實(shí)擴(kuò)展的Persistence Context是Conversation Context、Business Process Context的基礎(chǔ)。

        selected get rich quick

            Seam提供了兩種方式將Ajax集成到Seam應(yīng)用中,一種是使用具有Ajax特性的JSF組件,如RichFaces和ICEFaces,另一種是可以在瀏覽器中使用JavaScript直接調(diào)用服務(wù)端的組件。

            Seam還提供了另外一種意義上的Rich,即將PDF、mail等功能集成到Seam應(yīng)用中。

        selected 提供了一個快速開發(fā)環(huán)境

    selected1 代碼自動生成

    selected1 熱部署

    selected1 Seam調(diào)試頁面

    selected1 不部署即可以進(jìn)行單元測試

            

    從目前我個人的理解來看,Seam的作用與能力如下:

    • Seam將EJB3與JSF整合在一起,消除了JSF與業(yè)務(wù)代碼之間的間隙,直接將表現(xiàn)層與業(yè)務(wù)層銜接在一起
    • Seam提出了Conversation Context的概念,將Stateful EJB引入到web開發(fā)中,直接與Conversation Context對應(yīng)
    • Seam提供了與Jbpm、itext、mail等一系列開源框架的整合,對于需要使用的相關(guān)功能的用戶來說,提供了便利性
    • 提供了開發(fā)工具的整合(Seam Gen與IDE),還可以自動生成部分代碼

            但由于Seam整合了如此多的框架,帶來的一個最大的缺點(diǎn):學(xué)習(xí)曲線陡峭,在SSH非常流行的今天,需要面對很多新技術(shù)(JSF、EJB3、JPA等),對于一個新手來說難度比較大,如果想使Seam被更多的開發(fā)人員使用,必須加強(qiáng)它的文檔,目前的文檔還是太少了。

    posted @ 2008-12-06 23:51 The Matrix 閱讀(2283) | 評論 (0)編輯 收藏

            今天早上在網(wǎng)上看到了kettle發(fā)布了最新的版本,忽然想起最近其實(shí)做了不少工作應(yīng)該是ETL工具的拿手好戲,趕緊下載下來看看,看是否能夠在實(shí)際的工作中應(yīng)用起來。

            順便講一下,為啥看到kettle會兩眼發(fā)光。

            最近寫了好幾個小程序,用于從一個ftp去獲取數(shù)據(jù),然后轉(zhuǎn)發(fā)至另一個ftp去,或者是從一個數(shù)據(jù)庫獲取數(shù)據(jù)然后保存至本地的數(shù)據(jù)庫中,使用的是jdk中的Timer實(shí)現(xiàn)的定時調(diào)度,本來也沒什么問題,連續(xù)運(yùn)行幾個月都不會出錯。

            可是最近網(wǎng)絡(luò)不是太好,周期性抽風(fēng),ping包時,每5分鐘大概會丟7-8個包,從而導(dǎo)致程序也會假死,過一段時間后就不正常干活了,估計(jì)是因?yàn)橛昧藬?shù)據(jù)庫連接池的問題,要是每次發(fā)起數(shù)據(jù)庫連接可能就不會有問題了,偷懶也不想改了,因?yàn)榫W(wǎng)絡(luò)最終肯定是會修好的 :-) 但是想試試ETL工具,因?yàn)楹竺孢€有一些類似的東西要處理,不想寫代碼了,用別人的輪子感覺比較好,呵呵

            首先下載了kettle的最新版,kettle3.1,解壓后即可運(yùn)行,一般的開發(fā)人員稍微摸索一下,看看例子簡單的轉(zhuǎn)換還是會做的,今天小試了一把,有幾個注意點(diǎn)記下來。

    1. 使用資源庫(repository)登錄時,默認(rèn)的用戶名和密碼是admin/admin
    2. 當(dāng)job是存放在資源庫(一般資源庫都使用數(shù)據(jù)庫)中時,使用Kitchen.bat執(zhí)行job時,需使用如下的命令行:
      Kitchen.bat /rep kettle /user admin /pass admin /job job名
    3. 當(dāng)job沒有存放在資源庫而存放在文件系統(tǒng)時,使用Kitchen.bat執(zhí)行job時,需使用如下的命令行:
      Kitchen.bat /norep /file user-transfer-job.kjb
    4. 可以使用命令行執(zhí)行job后,就可以使用windows或linux的任務(wù)調(diào)度來定時執(zhí)行任務(wù)了

            在一開始使用命令行方式執(zhí)行job時,總是報(bào)如下的錯誤,琢磨了好長時間總算整明白正確的方式了。

    Unexpected error during transformation metadata load
    No repository defined!

            下一步準(zhǔn)備按照實(shí)際情況定制Job,做好了再寫小結(jié)。

    posted @ 2008-12-04 22:48 The Matrix 閱讀(10358) | 評論 (13)編輯 收藏

            JBoss Envers目的是根據(jù)對實(shí)體的設(shè)置,提供記錄執(zhí)行數(shù)據(jù)變更歷史的功能(數(shù)據(jù)變更版本)。Envers的配置非常簡單,如果需要對某個實(shí)例進(jìn)行歷史數(shù)據(jù)版本記錄,只需要在實(shí)例上配置@Versioned annotation即可。針對每個實(shí)體的版本的歷史數(shù)據(jù),Envers都會創(chuàng)建一個單獨(dú)的數(shù)據(jù)表進(jìn)行存儲。

            目前Envers支持Hibernate和Hibernate-entitymanager(JPA實(shí)現(xiàn)).

            這個特點(diǎn)在需要對歷史數(shù)據(jù)進(jìn)行存檔時很實(shí)用,而且目前Envers已經(jīng)合并到Hibernate的新版本中去了,使用起來更方便,具體Hibernate哪個不太清楚。

            留個印記..............

    posted @ 2008-12-04 09:04 The Matrix 閱讀(298) | 評論 (0)編輯 收藏

    準(zhǔn)備深入學(xué)習(xí)JBossSeam,好好研究研究,具體學(xué)習(xí)路線基本遵循jboss-seam-2.1.1.CR1中的<<seam_reference.pdf>>。

    學(xué)習(xí)JBossSeam之前最好對相關(guān)技術(shù)有一定的了解,比如:

    • JSF
    • EJB3.0
    • JPA

    然后下載相關(guān)的軟件,如下:

    • jboss-seam-2.1.1.CR1
    • jboss-4.2.3.GA
    • JBossTools-3.0.0.Beta1-R200810311334-ALL-win32(開發(fā)環(huán)境)
    • eclipse-jee-ganymede-SR1-win32(開發(fā)環(huán)境)
    • apache-ant-1.7.0
    • jdk1.6.0_06

    環(huán)境的配置都比較簡單,基本都是解壓即可,有如下注意事項(xiàng):

    • 在系統(tǒng)的環(huán)境變量中設(shè)置JAVA_HOME、ANT_HOME
    • JBossTools解壓后需拷貝至eclipse解壓后的目錄中。
    • jboss-seam-2.1.1.CR1解壓后,需設(shè)置其bulid目錄下的default.build.properties文件中的jboss.home為JBOSS_HOME(假定為jboss-4.2.3GA的安裝目錄)。

    上述配置好后,啟動JBoss Server,然后至SEAM_HOME(假定為Seam的安裝目錄)/examples/registration目錄下,運(yùn)行ant explode命令,即可編譯部署registration應(yīng)用至JBoss Server中,最后訪問:http://localhost:8080/seam-registration 即可體驗(yàn)Seam提供的第一個example程序 :-)

    posted @ 2008-12-03 23:03 The Matrix 閱讀(964) | 評論 (0)編輯 收藏
    僅列出標(biāo)題
    共4頁: 上一頁 1 2 3 4 下一頁 
    主站蜘蛛池模板: 中文字幕亚洲日本岛国片| 免费国产成人高清在线观看网站| 亚洲成a人片在线观看老师| 亚洲日韩精品无码专区| 成年性午夜免费视频网站不卡| 亚洲伊人久久大香线蕉影院| 精品国产sm捆绑最大网免费站| a级毛片毛片免费观看久潮喷 | 亚洲AV永久无码精品放毛片| 日本一道高清不卡免费| 亚洲Av永久无码精品黑人| 免费人成无码大片在线观看| 一级特黄特色的免费大片视频| 亚洲一级特黄大片在线观看| a毛片在线还看免费网站| 亚洲AV日韩精品久久久久久| 99精品视频免费在线观看| 亚洲国产成人久久77| 永久免费观看的毛片的网站| 国产亚洲精品第一综合| 国产亚洲成人在线播放va| 久久免费观看国产精品88av| 亚洲图片校园春色| 国产人妖ts在线观看免费视频| 一本一道dvd在线观看免费视频| 亚洲成A人片在线观看无码不卡| 久久久久免费看成人影片| 久久亚洲精品国产亚洲老地址| 国产免费人成在线视频| 最近免费中文字幕中文高清| 亚洲大尺码专区影院| 亚洲va中文字幕无码| 午夜理伦剧场免费| 亚洲AV无码国产剧情| 亚洲精品亚洲人成在线观看| 日本人的色道免费网站| 日韩在线一区二区三区免费视频 | 中文字幕免费观看全部电影| 18gay台湾男同亚洲男同| 在线观看国产情趣免费视频| 国产成人免费AV在线播放|