WaveSun

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            17 隨筆 :: 0 文章 :: 3 評(píng)論 :: 0 Trackbacks

          2009年6月8日 #

               摘要: 這個(gè)滑動(dòng)條(拖動(dòng)條)效果,一開(kāi)始是參考了BlueDestiny的slider和Apple產(chǎn)品展示的樣式,做了程序的原 型。 在做了拖放效果之后,我想應(yīng)該可以做一個(gè)更好的了,所以重做一遍,完善和擴(kuò)展了一些功能。 礙于時(shí)間沒(méi)有做得很強(qiáng)大,都是一些基本功能,希望各位多提意見(jiàn)! 效果預(yù)覽 0){ this._IsMin = false; }else{ if(!this._IsMin)...  閱讀全文
          posted @ 2010-03-22 15:31 WaveSun 閱讀(615) | 評(píng)論 (0)編輯 收藏

          Spring入門

          Spring是一個(gè)非常優(yōu)秀的輕量級(jí)框架,通過(guò)Spring的IoC容器,我們的關(guān)注點(diǎn)便放到了需要實(shí)現(xiàn)的業(yè)務(wù)邏輯 上。對(duì)AOP的支持則能讓我們動(dòng)態(tài)增強(qiáng)業(yè)務(wù)方法。編寫(xiě)普通的業(yè)務(wù)邏輯Bean是非常容易而且易于測(cè)試的,因?yàn)樗苊撾xJ2EE容器(如 Servlet,jsp環(huán)境)單獨(dú)進(jìn)行單元測(cè)試。最后的一步便是在Spring框架中將這些業(yè)務(wù)Bean以XML配置文件的方式組織起來(lái),它們就按照我們 預(yù)定的目標(biāo)正常工作了!非常容易!

          本文將給出一個(gè)基本的Spring入門示例,并演示如何使用Spring的AOP將復(fù)雜的業(yè)務(wù)邏輯分離到每個(gè)方面中。

          1.開(kāi)發(fā)環(huán)境配置2.編寫(xiě)B(tài)ean接口及其實(shí)現(xiàn)3.在Spring中配置Bean并獲得Bean的實(shí)例4.編寫(xiě)Advisor以增強(qiáng) ServiceBean5.總結(jié)

          1.開(kāi)發(fā)環(huán)境配置

          首先,需要正確配置Java環(huán)境。推薦安裝JDK1.4.2,并正確配置環(huán)境變量:

          JAVA_HOME=<JDK安裝目錄>CLASSPATH=.Path=%JAVA_HOME%"bin;……

          我們將使用免費(fèi)的Eclipse 3.1作為IDE。新建一個(gè)Java Project,將Spring的發(fā)布包spring.jar以及commons-logging-1.0.4.jar復(fù)制到Project目錄下,并在 Project > Properties中配置好Java Build Path:

          Spring入門(圖一)

          點(diǎn)擊查看大圖 2.編寫(xiě)B(tài)ean接口及其實(shí)現(xiàn)

          我們實(shí)現(xiàn)一個(gè)管理用戶的業(yè)務(wù)Bean。首先定義一個(gè)ServiceBean接口,聲明一些業(yè)務(wù)方法:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          /** * Interface of service facade. *  * @author Xuefeng */public interface ServiceBean {    void addUser(String username, String passWord);    void deleteUser(String username);    boolean findUser(String username);    String getPassword(String username);}

          然后在MyServiceBean中實(shí)現(xiàn)接口:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 *  * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          import java.util.*;

          public class MyServiceBean implements ServiceBean {

              private String dir;    private Map map = new HashMap();

              public void setUserDir(String dir) {        this.dir = dir;        System.out.println("Set user dir to: " + dir);    }

              public void addUser(String username, String password) {        if(!map.containsKey(username))            map.put(username, password);        else            throw new RuntimeException("User already exist.");    }

              public void deleteUser(String username) {        if(map.remove(username)==null)            throw new RuntimeException("User not exist.");    }

              public boolean findUser(String username) {        return map.containsKey(username);    }

              public String getPassword(String username) {        return (String)map.get(username);    }}


          為了簡(jiǎn)化邏輯,我們使用一個(gè)Map保存用戶名和口令。

          現(xiàn)在,我們已經(jīng)有了一個(gè)業(yè)務(wù)Bean。要測(cè)試它非常容易,因?yàn)榈侥壳盀橹梗覀冞€沒(méi)有涉及到Spring容器,也沒(méi)有涉及到任何Web容器(假定這 是一個(gè)Web應(yīng)用程序關(guān)于用戶管理的業(yè)務(wù)Bean)。完全可以直接進(jìn)行Unit測(cè)試,或者,簡(jiǎn)單地寫(xiě)個(gè)main方法測(cè)試:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          public class Main {

              public static void main(String[] args) throws Exception {        ServiceBean service = new MyServiceBean();        service.addUser("bill", "hello");        service.addUser("tom", "goodbye");        service.addUser("tracy", "morning");        System.out.println("tom's password is: " + service.getPassword("tom"));        if(service.findUser("tom")) {            service.deleteUser("tom");        }    }}

          執(zhí)行結(jié)果:Spring入門(圖二)

          3.在Spring中配置Bean并獲得Bean的實(shí)例

          我們已經(jīng)在一個(gè)main方法中實(shí)現(xiàn)了業(yè)務(wù),不過(guò),將對(duì)象的生命周期交給容器管理是更好的辦法,我們就不必為初始化對(duì)象和銷毀對(duì)象進(jìn)行硬編碼,從而獲 得更大的靈活性和可測(cè)試性。

          想要把ServiceBean交給Spring來(lái)管理,我們需要一個(gè)XML配置文件。新建一個(gè)beans.xml,放到src目錄下,確保在 classpath中能找到此配置文件,輸入以下內(nèi)容:

          <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans>    <bean id="service" class="com.crackj2ee.example.spring.MyServiceBean" /></beans>

          以上XML聲明了一個(gè)id為service的Bean,默認(rèn)地,Spring為每個(gè)聲明的Bean僅創(chuàng)建一個(gè)實(shí)例,并通過(guò)id來(lái)引用這個(gè) Bean。下面,我們修改main方法,讓Spring來(lái)管理業(yè)務(wù)Bean:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.ClassPathResource;

          public class Main {

              public static void main(String[] args) throws Exception {        // init factory:        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));        // use service bean:        ServiceBean service = (ServiceBean)factory.getBean("service");        service.addUser("bill", "hello");        service.addUser("tom", "goodbye");        service.addUser("tracy", "morning");        System.out.println("tom's password is """ + service.getPassword("tom") + """");        if(service.findUser("tom")) {            service.deleteUser("tom");        }        // close factory:        factory.destroySingletons();    }}


          執(zhí)行結(jié)果: Spring入門(圖三)

          由于我們要通過(guò)main方法啟動(dòng)Spring環(huán)境,因此,首先需要初始化一個(gè)BeanFactory。紅色部分是初始化Spring的 BeanFactory的典型代碼,只需要保證beans.xml文件位于classpath中。

          然后,在BeanFactory中通過(guò)id查找,即可獲得相應(yīng)的Bean的實(shí)例,并將其適當(dāng)轉(zhuǎn)型為合適的接口。

          接著,實(shí)現(xiàn)一系列業(yè)務(wù)操作,在應(yīng)用程序結(jié)束前,讓Spring銷毀所有的Bean實(shí)例。

          對(duì)比上一個(gè)版本的Main,可以看出,最大的變化是不需要自己管理Bean的生命周期。另一個(gè)好處是在不更改實(shí)現(xiàn)類的前提下,動(dòng)態(tài)地為應(yīng)用程序增加 功能。

          4.編寫(xiě)Advisor以增強(qiáng)ServiceBean

          所謂AOP即是將分散在各個(gè)方法處的公共代碼提取到一處,并通過(guò)類似攔截器的機(jī)制實(shí)現(xiàn)代碼的動(dòng)態(tài)織入。可以簡(jiǎn)單地想象成,在某個(gè)方法的調(diào)用前、返回 前、調(diào)用后和拋出異常時(shí),動(dòng)態(tài)插入自己的代碼。在弄清楚Pointcut、Advice之類的術(shù)語(yǔ)前,不如編寫(xiě)一個(gè)最簡(jiǎn)單的AOP應(yīng)用來(lái)體驗(yàn)一下。

          考慮一下通常的Web應(yīng)用程序都會(huì)有日志記錄,我們來(lái)編寫(xiě)一個(gè)LogAdvisor,對(duì)每個(gè)業(yè)務(wù)方法調(diào)用前都作一個(gè)記錄:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;

          public class LogAdvisor implements MethodBeforeAdvice {    public void before(Method m, Object[] args, Object target) throws Throwable {        System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");    }}

          然后,修改beans.xml:

          <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

          <beans>    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />

              <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />

              <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>        <property name="target"><ref local="serviceTarget"/></property>        <property name="interceptorNames">            <list>                <value>logAdvisor</value>            </list>        </property>    </bean></beans>

          注意觀察修改后的配置文件,我們使用了一個(gè)ProxyFactoryBean作為service來(lái)與客戶端打交道,而真正的業(yè)務(wù)Bean即 MyServiceBean被聲明為serviceTarget并作為參數(shù)對(duì)象傳遞給ProxyFactoryBean,proxyInterfaces 指定了返回的接口類型。對(duì)于客戶端而言,將感覺(jué)不出任何變化,但卻動(dòng)態(tài)加入了LogAdvisor,關(guān)系如下: Spring入門(圖四)


          運(yùn)行結(jié)果如下,可以很容易看到調(diào)用了哪些方法: Spring入門(圖五)

          要截獲指定的某些方法也是可以的。下面的例子將修改getPassword()方法的返回值:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;

          public class PasswordAdvisor implements MethodInterceptor {    public Object invoke(MethodInvocation invocation) throws Throwable {        Object ret = invocation.proceed();        if(ret==null)            return null;        String password = (String)ret;        StringBuffer encrypt = new StringBuffer(password.length());        for(int i=0; i<password.length(); i++)            encrypt.append('*');        return encrypt.toString();    }}

          這個(gè)PasswordAdvisor將截獲ServiceBean的getPassword()方法的返回值,并將其改為"***"。繼續(xù) 修改beans.xml:

          <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans>    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />

              <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />

              <bean id="passwordAdvisorTarget" class="com.crackj2ee.example.spring.PasswordAdvisor" />

              <bean id="passwordAdvisor" class="org.springframework.aop.support.RegeXPMethodPointcutAdvisor">        <property name="advice">            <ref local="passwordAdvisorTarget"/>        </property>        <property name="patterns">            <list>                <value>.*getPassword</value>            </list>        </property>    </bean>

              <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>        <property name="target"><ref local="serviceTarget"/></property>        <property name="interceptorNames">            <list>                <value>logAdvisor</value>                <value>passwordAdvisor</value>            </list>        </property>    </bean></beans>


          利用Spring提供的一個(gè)RegexMethodPointcutAdvisor可以非常容易地指定要截獲的方法。運(yùn)行結(jié)果如下,可以看到返回結(jié)果變 為"******": Spring入門(圖六)

          還需要繼續(xù)增強(qiáng)ServiceBean?我們編寫(xiě)一個(gè)ExceptionAdvisor,在業(yè)務(wù)方法拋出異常時(shí)能做一些處理:

          /** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

          import org.springframework.aop.ThrowsAdvice;

          public class ExceptionAdvisor implements ThrowsAdvice {    public void afterThrowing(RuntimeException re) throws Throwable {        System.out.println("[Exception] " + re.getMessage());    }}

          將此Advice添加到beans.xml中,然后在業(yè)務(wù)Bean中刪除一個(gè)不存在的用戶,故意拋出異常:

          service.deleteUser("not-exist");

          再次運(yùn)行,注意到ExceptionAdvisor記錄下了異常: Spring入門(圖七)

          5.總結(jié)

          利用Spring非常強(qiáng)大的IoC容器和AOP功能,我們能實(shí)現(xiàn)非常靈活的應(yīng)用,讓Spring容器管理業(yè)務(wù)對(duì)象的生命周期,利用AOP增強(qiáng)功能, 卻不影響業(yè)務(wù)接口,從而避免更改客戶端代碼。

          為了實(shí)現(xiàn)這一目標(biāo),必須始終牢記:面向接口編程。而Spring默認(rèn)的AOP代理也是通過(guò)Java的代理接口實(shí)現(xiàn)的。雖然Spring也可以用 CGLIB實(shí)現(xiàn)對(duì)普通類的代理,但是,業(yè)務(wù)對(duì)象只要沒(méi)有接口,就會(huì)變得難以擴(kuò)展、維護(hù)和測(cè)試。

          歡迎來(lái)信與作者交流:asklxf@163.com

          可以從此處下載完整的Eclipse工程:

          springbasic.rar

          (出處:http://www.jzwiki.com/article_1215945431010.shtml#)

          posted @ 2010-03-09 13:00 WaveSun 閱讀(261) | 評(píng)論 (0)編輯 收藏


          當(dāng)你在客戶端用view source看JSP生成的代碼時(shí),會(huì)發(fā)現(xiàn)有很多空行,他們是由<%...%>后的回車換行而生成的,也就是說(shuō)每一行 由<%...%>包含的JSP代碼到客戶端都變成一個(gè)空行,雖然不影響瀏覽,但還是希望能把他們刪掉

          辦法如下:(網(wǎng)上收集整理)

          1. 支持JSP 2.1+ ,在每個(gè)要去空行的頁(yè)面里包含下面代碼:

            

          <%@ page trimDirectiveWhitespaces="true" %>

          在 Tomcat 6.0.14下測(cè)試成功


          2. 支持servlet 2.5+, 即 web.xml的 XSD版本為2.5,在web.xml中加入如下代碼

            

          <jsp-config>
                
          <jsp-property-group>
                  
          <url-pattern>*.jsp</url-pattern>
                  
          <trim-directive-whitespaces>true</trim-directive-whitespaces>
                
          </jsp-property-group>
              
          </jsp-config>

          在tomcat 6.0.14下測(cè)試成功


          3. Tomcat 5.5.x+,在Tomcat安裝目錄/conf/web.xml中找到名叫"jsp"的servlet,添加下面一段代碼:

          <init-param>
                  
          <param-name>trimSpaces</param-name>
                  
          <param-value>true</param-value>
              
          </init-param>


           

          本人沒(méi)測(cè)過(guò),不過(guò)tomcat中web.xml文件的幫助這么說(shuō)的

          trimSpaces          Should white spaces in template text between  actions or directives be trimmed?  [false]

          所以應(yīng)該可行 

          發(fā)表于 @ 2008年05月23日 11:40:00 | 評(píng)論( 3 ) | 舉報(bào)| 收藏

          mcoldice 發(fā) 表于2009年2月23日 16:56:39  舉 報(bào)回復(fù)
          關(guān)于第三條:
          1 確實(shí)有效
          2 5.0也同樣有效,所以不時(shí)必須要5.5.x+
          mcoldice 發(fā) 表于2009年2月23日 16:56:53  舉 報(bào)回復(fù)
          關(guān)于第三條:
          1 確實(shí)有效
          2 5.0也同樣有效,所以不時(shí)必須要5.5.x+
          xuhaiyang 發(fā) 表于2009年2月23日 17:55:25  舉 報(bào)回復(fù)
          因 為沒(méi)用5.0測(cè)過(guò),所以就沒(méi)寫(xiě)出來(lái)。
          謝謝你的補(bǔ)測(cè)。
          原文地址:http://blog.csdn.net/xuhaiyang/archive/2008/05/23/2472591.aspx
          posted @ 2010-03-09 10:08 WaveSun 閱讀(990) | 評(píng)論 (0)編輯 收藏

          關(guān)鍵字: jsp <jsp-config>
          <jsp-config> 包括 <taglib> <jsp-property-group> 兩個(gè)子元素。其中<taglib> 元素在JSP 1.2 時(shí)就已經(jīng)存在;而<jsp-property-group>JSP 2.0 新增的元素。<jsp-property-group> 元素主要有八個(gè)子元素,它們分別為:
          1.<description>:設(shè)定的說(shuō)明
          2.<display-name>:設(shè)定名稱
          3.<url-pattern>:設(shè)定值所影響的范圍,如: /CH2 /*.jsp
          4.<el-ignored>:若為 true,表示不支持 EL 語(yǔ)法
          5.<scripting-invalid>:若為 true,表示不支持 <% scripting %>語(yǔ)法
          6.<page-encoding>:設(shè)定 JSP 網(wǎng)頁(yè)的編碼
          7.<include-prelude>:設(shè)置 JSP 網(wǎng)頁(yè)的抬頭,擴(kuò)展名為 .jspf
          8.<include-coda>:設(shè)置 JSP 網(wǎng)頁(yè)的結(jié)尾,擴(kuò)展名為 .jspf

          一個(gè)簡(jiǎn)單的<jsp-config> 元素完整配置:

          Xml代碼
          1. <jsp-config>     
          2.   <taglib>     
          3.     <taglib-uri>Taglib</taglib-uri>     
          4.     <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>     
          5.   </taglib>     
          6.   <jsp-property-group>     
          7.     <description>Special property group for JSP Configuration JSP example.</description>     
          8.     <display-name>JSPConfiguration</display-name>     
          9.     <url-pattern>/jsp/* </url-pattern>     
          10.     <el-ignored>true</el-ignored>     
          11.     <page-encoding>GB2312</page-encoding>     
          12.     <scripting-invalid>true</scripting-invalid>     
          13.     <include-prelude>/include/prelude.jspf</include-prelude>     
          14.     <include-coda>/include/coda.jspf</include-coda>     
          15.   </jsp-property-group>     
          16. </jsp-config>  
           
          對(duì)于Web 應(yīng)用程式來(lái)說(shuō),Scriptlet 是個(gè)不樂(lè)意被見(jiàn)到的東西,因?yàn)樗鼤?huì)使得HTMLJava 程式碼交相混雜,對(duì)于程式的維護(hù)來(lái)說(shuō)相當(dāng)?shù)穆闊匾臅r(shí)候,您可以在web.xml 中加上<script-invalid> 標(biāo)簽,設(shè)定所有的JSP 網(wǎng)頁(yè)都不可以使用Scriptlet ,例如:
          Xml代碼
          1. <web-app ..>  
          2.     ....  
          3.     <jsp-config>  
          4.         <jsp-property-group>  
          5.             <url-pattern>*.jsp</url-pattern>  
          6.             <script-invalid>true</script-invalid>  
          7.         </jsp-property-group>  
          8.     </jsp-config>  
          9. ....  
          10. </web-app>  
           
          原文地址:http://janwer.javaeye.com/blog/150217
          posted @ 2010-03-09 09:51 WaveSun 閱讀(609) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-16 12:02 WaveSun 閱讀(273) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-16 11:54 WaveSun 閱讀(243) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-09 18:38 WaveSun 閱讀(230) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-09 11:22 WaveSun 閱讀(229) | 評(píng)論 (0)編輯 收藏



          posted @ 2009-06-08 16:44 WaveSun 閱讀(224) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-08 10:56 WaveSun 閱讀(1208) | 評(píng)論 (0)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-08 10:14 WaveSun 閱讀(642) | 評(píng)論 (1)編輯 收藏

               摘要:   閱讀全文
          posted @ 2009-06-08 10:05 WaveSun 閱讀(291) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 石门县| 新河县| 金坛市| 沈阳市| 汤原县| 和平县| 离岛区| 安多县| 根河市| 聂荣县| 沧州市| 高碑店市| 太白县| 调兵山市| 自治县| 喀什市| 利辛县| 东兴市| 阳西县| 进贤县| 洪泽县| 石柱| 城固县| 佛教| 彰化县| 玉林市| 固安县| 榆中县| 株洲县| 双辽市| 邹平县| 盐城市| 吴川市| 秀山| 石楼县| 夏邑县| 陇川县| 历史| 山东| 丽水市| 佳木斯市|