posts - 7,comments - 5,trackbacks - 0

          http://www.aygfsteel.com/deng947/archive/2006/04/14/41139.html
          HTML Basic

          Image 標(biāo)簽 <IMG src="../images/03.gif" border="0"> 所有屬性包括

          Basic 屬性包括

           alt

                 Class

                 Id

                 Long

                 Longdesc

                 Name

                 Src

                 Title

                 Usemap

          Display 屬性包括

                 Align

                 Border

                 Dir

                 Height

                 Hspace

                 Ismap

                 Mapfile

                 Style

                 Vspace

                 Width

          Events 屬性包括

                 Onclick

          Ondbclick

          Onhelp

          Onkeydown

          Onkeypress

          Onkeyup

          Onmounsedown

          Onmousemove

          Onmouseout

          Onmouseover

          Onmouseup

          二、 HTML-Form

           Image Button<INPUT type="image" src="../images/03.gif" />

          Basic 屬性包括

           Accept

           Accesskey

           Alt

          Checked

                 Class

                 Disabled

                 Id

                 Long

                 Maxlength

                 Name

                 readonly

                 Src

                 Tabindex

                 Title

                 Type

                 Usemap

                 Value

          Display 屬性包括

                 Align

                 Border

                 Dir

                 Height

                 Ismap

          Isstyle

          Size

                 Style

                 Width

          Events 屬性包括

                 Onblur

                 Onchange

          Onclick

          Ondbclick

          Onfocus

          Onhelp

          Onkeydown

          Onkeypress

          Onkeyup

          Onmounsedown

          Onmousemove

          Onmouseout

          Onmouseover

          Onmouseup

                 Onselect

          三、 Struts Basic

          Image <html:img page="/images/03.gif" border="0" />

          Basic 屬性包括

           Action

          Alt

           AltKey

           Bundle

           imageName

           locale

           lowsrc

                 Name

                 Page

          PageKey

          Paramname

          Paramproperty

          Paramscope

                 Src

                 SrcKey

                 Title

                 titleKey

                 Usemap

          Display 屬性包括

                 Align

                 Border

                 Height

                 Hsapce

                 Ismap

                 Style

                 StyleClass

                 StyleId

                 Vsapce

                 Width

          Events 屬性包括

          Onclick

          Ondbclick

          Onkeydown

          Onkeypress

          Onkeyup

          Onmounsedown

          Onmousemove

          Onmouseout

          Onmouseover

          Onmouseup

          Other 屬性包括

                 contextRealtive

                 module

                 paramId

                 useLocalEncoding

          四、 Struts-Form

          Image Button <html:image page="/images/03.gif" />

          Basic 屬性包括

          Accesskey

           Alt

           altKey

          bundle

                  Disabled

                 Indexed

                 Locale

                 Page

          pageKey

          property

                 Src

                 SrcKey

                 Tabindex

                 Title

                 titleKey

                 Value

          Display 屬性包括

                 Align

                 Border

                 Style

                 styleClass

                 styleId

          Events 屬性包括

                 Onblur

                 Onchange

          Onclick

          Ondbclick

          Onfocus

          Onkeydown

          Onkeypress

          Onkeyup

          Onmounsedown

          Onmousemove

          Onmouseout

          Onmouseover

          Onmouseup

            Struts 必須使用 Struts Basic 下的 Image 標(biāo)簽 Struts-Form 下的 Image Button 按鈕。其中可以使用 servlet 隨機(jī)生成的圖片,或者 jsp 文件。 JSP 下的彩色驗(yàn)證碼的解決:

          隨機(jī)驗(yàn)證圖片的生成文件

          <%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>

          <%!

          Color getRandColor(int fc,int bc){// 給定范圍獲得隨機(jī)顏色

                  Random random = new Random();

                  if(fc>255) fc=255;

                  if(bc>255) bc=255;

                  int r=fc+random.nextInt(bc-fc);

                  int g=fc+random.nextInt(bc-fc);

                  int b=fc+random.nextInt(bc-fc);

                  return new Color(r,g,b);

                  }

          %>

          <%

          // 設(shè)置頁(yè)面不緩存

          response.setHeader("Pragma","No-cache");

          response.setHeader("Cache-Control","no-cache");

          response.setDateHeader("Expires", 0);

          // 在內(nèi)存中創(chuàng)建圖象

          int width=60, height=20;

          BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

          // 獲取圖形上下文

          Graphics g = image.getGraphics();

          // 生成隨機(jī)類(lèi)

          Random random = new Random();

          // 設(shè)定背景色

          g.setColor(getRandColor(200,250));

          g.fillRect(0, 0, width, height);

          // 設(shè)定字體

          g.setFont(new Font("Times New Roman",Font.PLAIN,18));

          // 畫(huà)邊框

          //g.setColor(new Color());

          //g.drawRect(0,0,width-1,height-1);

          // 隨機(jī)產(chǎn)生 155 條干擾線,使圖象中的認(rèn)證碼不易被其它程序探測(cè)到

          g.setColor(getRandColor(160,200));

          for (int i=0;i<155;i++)

          {

                  int x = random.nextInt(width);

                  int y = random.nextInt(height);

                  int xl = random.nextInt(12);

                  int yl = random.nextInt(12);

                  g.drawLine(x,y,x+xl,y+yl);

          }

          // 取隨機(jī)產(chǎn)生的認(rèn)證碼 (4 位數(shù)字 )

          String sRand="";

          for (int i=0;i<4;i++){

              String rand=String.valueOf(random.nextInt(10));

              sRand+=rand;

              // 將認(rèn)證碼顯示到圖象中

              g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));// 調(diào)用函數(shù)出來(lái)的顏色相同,可能是因?yàn)榉N子太接近,所以只能直接生成

              g.drawString(rand,13*i+6,16);

          }

          // 將認(rèn)證碼存入 SESSION

          session.setAttribute("rand",sRand);

          // 圖象生效

          g.dispose();

          // 輸出圖象到頁(yè)面

          ImageIO.write(image, "JPEG", response.getOutputStream());

          %>

          使用頁(yè)面:

          <%@ page contentType="text/html;charset=gb2312" %>

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

          <html>

          <head>

          <title> 認(rèn)證碼輸入頁(yè)面 </title>

          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

          <META HTTP-EQUIV="Pragma" CONTENT="no-cache">

          <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">

          <META HTTP-EQUIV="Expires" CONTENT="0">

          </head>

          <body>

          <form method=post action="check.jsp">

          <table>

          <tr>

          <td align=left> 系統(tǒng)產(chǎn)生的認(rèn)證碼: </td>

          <td><img border=0 src="image.jsp"></td>

          </tr>

          <tr>

          <td align=left> 輸入上面的認(rèn)證碼: </td>

          <td><input type=text name=rand maxlength=4 value=""></td>

          </tr>

          <tr>

          <td colspan=2 align=center><input type=submit value=" 提交檢測(cè) "></td>

          </tr>
          </table>

          </form>

          posted @ 2009-04-23 19:58 心路 閱讀(851) | 評(píng)論 (0)編輯 收藏
          unsupported major.minor version 解決方法

                  一直以來(lái)都是用jdk1.5,這次重返電信由于其系統(tǒng)是在jdk1.4上編譯的,編譯的時(shí)候出現(xiàn)了unsupported major.minor version49.0的錯(cuò)誤,上網(wǎng)查看了一下還是一個(gè)很普遍的錯(cuò)誤,搗鼓了兩天終于搗鼓出一些東西,現(xiàn)分享給大家。

               何謂 major.minor,且又居身于何處呢?先感性認(rèn)識(shí)并找到 major.minor 來(lái)。順便寫(xiě)一段 代碼,然后用 JDK 1.5 的編譯器編譯成class,用UltraEdit或者其他能打開(kāi)非十進(jìn)制文件的軟件打開(kāi)此class,見(jiàn)下圖:        

           

                 從上圖中我們看出來(lái)了什么是 major.minor version 了,它相當(dāng)于一個(gè)軟件的主次版本號(hào),只是在這里是標(biāo)識(shí)的一個(gè) Java Class 的主版本號(hào)和次版本號(hào),同時(shí)我們看到 minor_version 為 0x0000,major_version 為 0x0031,轉(zhuǎn)換為十制數(shù)分別為0 和 49,即 major.minor 就是 49.0 了。

                現(xiàn)在不妨從 JDK 1.1 到 JDK 1.7 編譯器編譯出的 class 的默認(rèn) minor.major version 吧。(又走到 Sun 的網(wǎng)站上翻騰出我從來(lái)都沒(méi)用過(guò)的古董來(lái))
               

          JDK 編譯器版本 target 參數(shù) 十六進(jìn)制 minor.major 十進(jìn)制 minor.major
          jdk1.1.8 不能帶 target 參數(shù) 00 03 00 2D 45.3
          jdk1.2.2 不帶(默認(rèn)為 -target 1.1) 00 03 00 2D 45.3
          jdk1.2.2 -target 1.2 00 00   00 2E 46.0
          jdk1.3.1_19 不帶(默認(rèn)為 -target 1.1) 00 03 00 2D 45.3
          jdk1.3.1_19 -target 1.3 00 00   00 2F 47.0
          j2sdk1.4.2_10 不帶(默認(rèn)為 -target 1.2) 00 00   00 2E 46.0
          j2sdk1.4.2_10 -target 1.4 00 00   00 30 48.0
          jdk1.5.0_11 不帶(默認(rèn)為 -target 1.5) 00 00   00 31 49.0
          jdk1.5.0_11 -target 1.4 -source 1.4 00 00   00 30 48.0
          jdk1.6.0_01 不帶(默認(rèn)為 -target 1.6) 00 00   00 32 50.0
          jdk1.6.0_01 -target 1.5 00 00   00 31 49.0
          jdk1.6.0_01 -target 1.4 -source 1.4 00 00   00 30 48.0
          jdk1.7.0 不帶(默認(rèn)為 -target 1.6) 00 00   00 32 50.0
          jdk1.7.0 -target 1.7 00 00   00 33 51.0
          jdk1.7.0 -target 1.4 -source 1.4 00 00   00 30 48.0
          Apache Harmony 5.0M3 不帶(默認(rèn)為 -target 1.2) 00 00   00 2E 46.0
          Apache Harmony 5.0M3 -target 1.4 00 00   00 30 48.0

           

                 當(dāng)然你也可以用其他方法查看版本號(hào),比如javap -verbose XXXX(class名)。

                  那么現(xiàn)在如果碰到這種問(wèn)題該知道如何解決了吧,還會(huì)像我所見(jiàn)到有些兄弟那樣,去找個(gè) 1.4 的 JDK 下載安裝,然后用其重新編譯所有的代碼嗎?且不說(shuō)這種方法的繁瑣,而且web應(yīng)用程序還不一定能成功,其實(shí)大可不必如此費(fèi)神,我們一定還記得 javac 還有個(gè) -target 參數(shù),對(duì)啦,可以繼續(xù)使用 1.5 JDK,編譯時(shí)帶上參數(shù) -target 1.4 -source 1.4 就 OK 啦,不過(guò)你一定要對(duì)哪些 API 是 1.5 JDK 加入進(jìn)來(lái)的了如指掌,不能你的 class 文件拿到 JVM 1.4 下就會(huì) method not found。目標(biāo) JVM 是 1.3 的話,編譯選項(xiàng)就用 -target 1.3 -source 1.3 了。

                相應(yīng)的如果使用 ant ,它的 javac 任務(wù)也可對(duì)應(yīng)的選擇 target 和 source

          <javac target="1.4" source="1.4" ............................/>

          如果是在開(kāi)發(fā)中,可以肯定的是現(xiàn)在真正算得上是 JAVA IDE 對(duì)于工程也都有編譯選項(xiàng)設(shè)置目標(biāo)代碼的。例如 Eclipse 的項(xiàng)目屬性中的 Java Compiler 設(shè)置,如圖:

                  

                  其實(shí)理解 major.minor 就像是我們可以這么想像,同樣是微軟件的程序,32 位的應(yīng)用程序不能拿到 16 位系統(tǒng)中執(zhí)行那樣。

          如果我們發(fā)布前了解到目標(biāo) JVM 版本,知道怎么從 java class 文件中看出 major.minor 版本來(lái),就不用等到服務(wù)器報(bào)出異常才著手去解決,也就能預(yù)知到可能發(fā)生的問(wèn)題。

          其他時(shí)候遇到這個(gè)問(wèn)題應(yīng)具體解決,總之問(wèn)題的根由是低版本的 JVM 無(wú)法加載高版本的 class 文件造成的,找到高版本的 class 文件處理一下就行了。

          posted @ 2009-04-23 11:31 心路 閱讀(68616) | 評(píng)論 (5)編輯 收藏

              概述
              各種企業(yè)應(yīng)用幾乎都會(huì)碰到任務(wù)調(diào)度的需求,就拿論壇來(lái)說(shuō):每隔半個(gè)小時(shí)生成精華文章的RSS文件,每天凌晨統(tǒng)計(jì)論壇用戶(hù)的積分排名,每隔30分鐘執(zhí)行鎖定用戶(hù)解鎖任務(wù)。對(duì)于一個(gè)典型的MIS系統(tǒng)來(lái)說(shuō),在每月1號(hào)凌晨統(tǒng)計(jì)上個(gè)月各部門(mén)的業(yè)務(wù)數(shù)據(jù)生成月報(bào)表,每半個(gè)小時(shí)查詢(xún)用戶(hù)是否已經(jīng)有快到期的待處理業(yè)務(wù)…… 

              Quartz 是開(kāi)源任務(wù)調(diào)度框架中的翹首,它提供了強(qiáng)大任務(wù)調(diào)度機(jī)制,同時(shí)保持了使用的簡(jiǎn)單性。Quartz 允許開(kāi)發(fā)人員靈活地定義觸發(fā)器的調(diào)度時(shí)間表,并可以對(duì)觸發(fā)器和任務(wù)進(jìn)行關(guān)聯(lián)映射。此外,Quartz提供了調(diào)度運(yùn)行環(huán)境的持久化機(jī)制,可以保存并恢復(fù)調(diào)度現(xiàn)場(chǎng),即使系統(tǒng)因故障關(guān)閉,任務(wù)調(diào)度現(xiàn)場(chǎng)數(shù)據(jù)并不會(huì)丟失。此外,Quartz還提供了組件式的偵聽(tīng)器、各種插件、線程池等功能。

              Spring為創(chuàng)建Quartz的Scheduler、Trigger和JobDetail提供了便利的FactoryBean類(lèi),以便能夠在Spring 容器中享受注入的好處。此外Spring還提供了一些便利工具類(lèi)直接將Spring中的Bean包裝成合法的任務(wù)。Spring進(jìn)一步降低了使用Quartz的難度,能以更具Spring風(fēng)格的方式使用Quartz。概括來(lái)說(shuō)它提供了兩方面的支持: 

          1)為Quartz的重要組件類(lèi)提供更具Bean風(fēng)格的擴(kuò)展類(lèi); 
          2)提供創(chuàng)建Scheduler的BeanFactory類(lèi),方便在Spring環(huán)境下創(chuàng)建對(duì)應(yīng)的組件對(duì)象,并結(jié)合Spring容器生命周期進(jìn)行啟動(dòng)和停止的動(dòng)作。

           
              創(chuàng)建JobDetail 
              可以直接使用Quartz的JobDetail在Spring中配置一個(gè)JobDetail Bean,但是JobDetail使用帶參的構(gòu)造函數(shù),對(duì)于習(xí)慣通過(guò)屬性配置的Spring用戶(hù)來(lái)說(shuō)存在使用上的不便。為此Spring通過(guò)擴(kuò)展JobDetail提供了一個(gè)更具Bean風(fēng)格的JobDetailBean。此外,Spring提供了一個(gè)MethodInvokingJobDetailFactoryBean,通過(guò)這個(gè)FactoryBean可以將Spring容器中Bean的方法包裝成Quartz任務(wù),這樣開(kāi)發(fā)者就不必為Job創(chuàng)建對(duì)應(yīng)的類(lèi)。
              JobDetailBean
              JobDetailBean擴(kuò)展于Quartz的JobDetail。使用該Bean聲明JobDetail時(shí),Bean的名字即是任務(wù)的名字,如果沒(méi)有指定所屬組,即使用默認(rèn)組。除了JobDetail中的屬性外,還定義了以下屬性:
              ● jobClass:類(lèi)型為Class,實(shí)現(xiàn)Job接口的任務(wù)類(lèi);
              ● beanName:默認(rèn)為Bean的id名,通過(guò)該屬性顯式指定Bean名稱(chēng),對(duì)應(yīng)任務(wù)的名稱(chēng);
              ● jobDataAsMap:類(lèi)型為Map,為任務(wù)所對(duì)應(yīng)的JobDataMap提供值。之所以需要提供這個(gè)屬性,是因?yàn)槌悄闶止ぷ?cè)一 個(gè)編輯器,你不能直接配置JobDataMap類(lèi)型的值,所以Spring通過(guò)jobDataAsMap設(shè)置JobDataMap的值;
              ●applicationContextJobDataKey:你可以將Spring ApplicationContext的引用保存到JobDataMap中,以便在Job的代碼中訪問(wèn)ApplicationContext。為了達(dá)到這個(gè)目的,你需要指定一個(gè)鍵,用以在jobDataAsMap中保存ApplicationContext,如果不設(shè)置此鍵,JobDetailBean就不將ApplicationContext放入到JobDataMap中;
              ●jobListenerNames:類(lèi)型為String[],指定注冊(cè)在Scheduler中的JobListeners名稱(chēng),以便讓這些監(jiān)聽(tīng)器對(duì)本任務(wù)的事件進(jìn)行監(jiān)聽(tīng)。
           下面配置片斷使用JobDetailBean在Spring中配置一個(gè)JobDetail:

          <bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
              <property name="jobClass" value="com.baobaotao.quartz.MyJob" />
              <property name="jobDataAsMap">
                  <map>
                      <entry key="size" value="10" />
                  </map>
              </property>
              <property name="applicationContextJobDataKey" value="applicationContext"/>
          </bean>
             JobDetailBean封裝了MyJob任務(wù)類(lèi),并為Job對(duì)應(yīng)JobDataMap設(shè)置了一個(gè)size的數(shù)據(jù)。此外,通過(guò)指定applicationContextJobDataKey讓Job的JobDataMap持有Spring ApplicationContext的引用。這樣,MyJob在運(yùn)行時(shí)就可以通過(guò)JobDataMap訪問(wèn)到size和ApplicationContext了。來(lái)看一下MyJob的代碼: 
            MyJob
          import org.quartz.Job;
          import org.quartz.JobExecutionContext;
          import org.quartz.JobExecutionException;
          import org.springframework.context.ApplicationContext;
          public class MyJob implements Job {
          public void execute(JobExecutionContext jctx) throws JobExecutionException {
          Map dataMap 
          = jctx.getJobDetail().getJobDataMap();  ①獲取JobDetail關(guān)聯(lián)的JobDataMap
          String size 
          =(String)dataMap.get("size");  ②
          ApplicationContext ctx 
          = (ApplicationContext)dataMap.get("applicationContext");  ③
          System.out.println(
          "size:"+size);
          dataMap.put(
          "size",size+"0");  ④對(duì)JobDataMap所做的更改是否被會(huì)持久,取決于任務(wù)的類(lèi)型
          //do sth 
          }
          }

              在②處獲取size值,在③處還可以根據(jù)鍵“applicationContext”獲取ApplicationContext,有了ApplicationContext的引用,Job就可以毫無(wú)障礙訪問(wèn)Spring容器中的任何Bean了。MyJob可以在execute()方法中對(duì)JobDataMap進(jìn)行更改,如④所示。如果MyJob實(shí)現(xiàn)Job接口,這個(gè)更改對(duì)于下一次執(zhí)行是不可見(jiàn)的,如果MyJob實(shí)現(xiàn)StatefulJob接口,這種更改對(duì)下一次執(zhí)行是可見(jiàn)的。

          MethodInvokingJobDetailFactoryBean
              通常情況下,任務(wù)都定義在一個(gè)業(yè)務(wù)類(lèi)方法中。這時(shí),為了滿(mǎn)足Quartz Job接口的規(guī)定,還需要定義一個(gè)引用業(yè)務(wù)類(lèi)方法的實(shí)現(xiàn)類(lèi)。為了避免創(chuàng)建這個(gè)只包含一行調(diào)用代碼的Job實(shí)現(xiàn)類(lèi),Spring為我們提供了MethodInvokingJobDetailFactoryBean,借由該FactoryBean,我們可以將一個(gè)Bean的某個(gè)方法封裝成滿(mǎn)足Quartz要求的Job。來(lái)看一個(gè)具體的例子:

          <bean id="jobDetail_1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
              <property name="targetObject" ref="myService" />   ① 引用一個(gè)Bean
              <property name="targetMethod" value="doJob" />   ② 指定目標(biāo)Bean的方法
              <property name="concurrent" value="false" />   ③ 指定最終封裝出的任務(wù)是否有狀態(tài)

          <bean id="myService" class="com.baobaotao.service.MyService"/>

              jobDetail_1將MyService#doJob()封裝成一個(gè)任務(wù),同時(shí)通過(guò)concurrent屬性指定任務(wù)的類(lèi)型,默認(rèn)情況下封裝為無(wú)狀態(tài)的任務(wù),如果希望目標(biāo)封裝為有狀態(tài)的任務(wù),僅需要將concurrent設(shè)置為false就可以了。Spring通過(guò)名為concurrent的屬性指定任務(wù)的類(lèi)型,能夠更直接地描述到任務(wù)執(zhí)行的方式(有狀態(tài)的任務(wù)不能并發(fā)執(zhí)行,無(wú)狀態(tài)的任務(wù)可并發(fā)執(zhí)行)。
              MyService服務(wù)類(lèi)擁有一個(gè)doJob()方法,它的代碼如下所示:

          public class MyService {
              public void doJob(){①被封裝成任務(wù)的目標(biāo)方法
                  System.out.println(
          "in MyService.dojob().");
              }
          }

              doJob()方法即可以是static也可以是非static的,但不能擁有方法入?yún)ⅰMㄟ^(guò)MethodInvokingJobDetailFactoryBean產(chǎn)生的JobDetail不能被序列化,所以不能被持久化到數(shù)據(jù)庫(kù)中的,如果希望使用持久化任務(wù),則你只能創(chuàng)建正規(guī)的Quartz的Job實(shí)現(xiàn)類(lèi)了。

              創(chuàng)建Trigger
              Quartz中另一個(gè)重要的組件就是Trigger,Spring按照相似的思路分別為SimpleTrigger和CronTrigger提供了更具Bean風(fēng)格的SimpleTriggerBeanCronTriggerBean擴(kuò)展類(lèi),通過(guò)這兩個(gè)擴(kuò)展類(lèi)更容易在Spring中以Bean的方式配置Trigger。

              SimpleTriggerBean
              默認(rèn)情況下,通過(guò)SimpleTriggerBean配置的Trigger名字即為Bean的名字,并屬于默認(rèn)組Trigger組。SimpleTriggerBean在SimpleTrigger的基礎(chǔ)上,新增了以下屬性:
              ● jobDetail:對(duì)應(yīng)的JobDetail;
              ● beanName:默認(rèn)為Bean的id名,通過(guò)該屬性顯式指定Bean名稱(chēng),它對(duì)應(yīng)Trigger的名稱(chēng);
              ● jobDataAsMap:以Map類(lèi)型為T(mén)rigger關(guān)聯(lián)的JobDataMap提供值;
              ● startDelay:延遲多少時(shí)間開(kāi)始觸發(fā),單位為毫秒,默認(rèn)為0;
              ● triggerListenerNames:類(lèi)型為String[],指定注冊(cè)在Scheduler中的TriggerListener名稱(chēng),以便讓這些監(jiān)聽(tīng)器對(duì)本觸發(fā)器的事件進(jìn)行監(jiān)聽(tīng)。
              下面的實(shí)例使用SimpleTriggerBean定義了一個(gè)Trigger,該Trigger和jobDetail相關(guān)聯(lián),延遲10秒后啟動(dòng),時(shí)間間隔為20秒,重復(fù)執(zhí)行100次。此外,我們還為T(mén)rigger設(shè)置了JobDataMap數(shù)據(jù):

          <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
              <property name="jobDetail" ref="jobDetail" />
              <property name="startDelay" value="1000" />
              <property name="repeatInterval" value="2000" />
              <property name="repeatCount" value="100" />
              <property name="jobDataAsMap"> ①
                  <map>
                      <entry key="count" value="10" />
                  </map>
              </property>
          </bean>

             需要特別注意的是,①處配置的JobDataMap是Trigger的JobDataMap,任務(wù)執(zhí)行時(shí)必須通過(guò)以下方式獲取配置的值:

          public class MyJob implements StatefulJob {
              public void execute(JobExecutionContext jctx) throws JobExecutionException {
                  Map dataMap 
          = jctx.getTrigger().getJobDataMap();  ①獲取Trigger的JobDataMap
                  String count 
          = dataMap.get("count");
                  dataMap.put("count","
          30");   ② 對(duì)JobDataMap的更改不會(huì)被持久,不影響下次的執(zhí)行
                  …
              }
          }

              CronTriggerBean
              CronTriggerBean擴(kuò)展于CronTrigger,觸發(fā)器的名字即為Bean的名字,保存在默認(rèn)組中。在CronTrigger的基礎(chǔ)上,新增的屬性和SimpleTriggerBean大致相同,配置的方法也和SimpleTriggerBean相似,下面給出一個(gè)簡(jiǎn)單的例子:

          <bean id="checkImagesTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
              <property name="jobDetail" ref="jobDetail "/>
              <property name="cronExpression" value="0/5 * * * * ?"/>
          </bean>
             
               創(chuàng)建Scheduler 
              Quartz的SchedulerFactory是標(biāo)準(zhǔn)的工廠類(lèi),不太適合在Spring環(huán)境下使用。此外,為了保證Scheduler能夠感知Spring容器的生命周期,完成自動(dòng)啟動(dòng)和關(guān)閉的操作,必須讓Scheduler和Spring容器的生命周期相關(guān)聯(lián)。以便在Spring容器啟動(dòng)后,Scheduler自動(dòng)開(kāi)始工作,而在Spring容器關(guān)閉前,自動(dòng)關(guān)閉Scheduler。為此,Spring提供SchedulerFactoryBean,這個(gè)FactoryBean大致?lián)碛幸韵碌墓δ埽?nbsp;
          1)以更具Bean風(fēng)格的方式為Scheduler提供配置信息; 
          2)讓Scheduler和Spring容器的生命周期建立關(guān)聯(lián),相生相息; 
          3)通過(guò)屬性配置部分或全部代替Quartz自身的配置文件。 
              來(lái)看一個(gè)SchedulerFactoryBean配置的例子: 
              SchedulerFactoryBean配置
          <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
              <property name="triggers"> ①注冊(cè)多個(gè)Trigger
                  <list>
                      <ref bean="simpleTrigger" />
                  </list>
              </property>
              <property name="schedulerContextAsMap"②以Map類(lèi)型設(shè)置SchedulerContext數(shù)據(jù)
                  <map>
                      <entry key="timeout" value="30" />
                  </map>
              </property>
             ③顯式指定Quartz的配置文件地址
             <property name="configLocation" value="classpath:com/baobaotao/quartz/quartz.properties" /> 
          </bean>

              SchedulerFactoryBean的triggers屬性為T(mén)rigger[]類(lèi)型,可以通過(guò)該屬性注冊(cè)多個(gè)Trigger,在①處,我們注冊(cè)了一個(gè)Trigger。Scheduler擁有一個(gè)類(lèi)似于ServletContext的SchedulerContext。SchedulerFactoryBean允許你以Map的形式設(shè)置SchedulerContext的參數(shù)值,如②所示。默認(rèn)情況下,Quartz在類(lèi)路徑下查詢(xún)quartz.properties配置文件,你也可以通過(guò)configLocation屬性顯式指定配置文件位置,如③所示。
           
              除了實(shí)例中所用的屬性外,SchedulerFactoryBean還擁有一些常見(jiàn)的屬性:
              ●calendars:類(lèi)型為Map,通過(guò)該屬性向Scheduler注冊(cè)Calendar;
              ●jobDetails:類(lèi)型為JobDetail[],通過(guò)該屬性向Scheduler注冊(cè)JobDetail;
              ●autoStartup:SchedulerFactoryBean在初始化后是否馬上啟動(dòng)Scheduler,默認(rèn)為true。如果設(shè)置為false,需要手工啟動(dòng)Scheduler;
              ●startupDelay:在SchedulerFactoryBean初始化完成后,延遲多少秒啟動(dòng)Scheduler,默認(rèn)為0,表示馬上啟動(dòng)。如果并非馬上擁有需要執(zhí)行的任務(wù),可通過(guò)startupDelay屬性讓Scheduler延遲一小段時(shí)間后啟動(dòng),以便讓Spring能夠更快初始化容器中剩余的Bean;

              SchedulerFactoryBean的一個(gè)重要功能是允許你將Quartz配置文件中的信息轉(zhuǎn)移到Spring配置文件中,帶來(lái)的好處是,配置信息的集中化管理,同時(shí)我們不必熟悉多種框架的配置文件結(jié)構(gòu)。回憶一個(gè)Spring集成JPA、Hibernate框架,就知道這是Spring在集成第三方框架經(jīng)常采用的招數(shù)之一。SchedulerFactoryBean通過(guò)以下屬性代替框架的自身配置文件:
              ●dataSource:當(dāng)需要使用數(shù)據(jù)庫(kù)來(lái)持久化任務(wù)調(diào)度數(shù)據(jù)時(shí),你可以在Quartz中配置數(shù)據(jù)源,也可以直接在Spring中通過(guò)dataSource指定一個(gè)Spring管理的數(shù)據(jù)源。如果指定了該屬性,即使quartz.properties中已經(jīng)定義了數(shù)據(jù)源,也會(huì)被此dataSource覆蓋;
              ●transactionManager:可以通過(guò)該屬性設(shè)置一個(gè)Spring事務(wù)管理器。在設(shè)置dataSource時(shí),Spring強(qiáng)烈推薦你使用一個(gè)事務(wù)管理器,否則數(shù)據(jù)表鎖定可能不能正常工作;
              ●nonTransactionalDataSource:在全局事務(wù)的情況下,如果你不希望Scheduler執(zhí)行化數(shù)據(jù)操作參與到全局事務(wù)中,則可以通過(guò)該屬性指定數(shù)據(jù)源。在Spring本地事務(wù)的情況下,使用dataSource屬性就足夠了;
              ●quartzProperties:類(lèi)型為Properties,允許你在Spring中定義Quartz的屬性。其值將覆蓋quartz.properties配置文件中的設(shè)置,這些屬性必須是Quartz能夠識(shí)別的合法屬性,在配置時(shí),你可以需要查看Quartz的相關(guān)文檔。下面是一個(gè)配置quartzProperties屬性的例子:

          <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
              …
              <property name="quartzProperties">
                  <props>
                      <prop key="org.quartz.threadPool.class"①Q(mào)uartz屬性項(xiàng)1
                          org.quartz.simpl.SimpleThreadPool
                      </prop>
                      <prop key="org.quartz.threadPool.threadCount">10</prop①Q(mào)uartz屬性項(xiàng)2
                  </props>
              </property>
          </bean>

             在實(shí)際應(yīng)用中,我們并不總是在程序部署的時(shí)候就可能確定需要哪些任務(wù),往往需要在運(yùn)行期根據(jù)業(yè)務(wù)數(shù)據(jù)動(dòng)態(tài)產(chǎn)生觸發(fā)器和任務(wù)。你完全可以在運(yùn)行期通過(guò)代碼調(diào)用SchedulerFactoryBean獲取Scheduler實(shí)例,進(jìn)行動(dòng)態(tài)的任務(wù)注冊(cè)和調(diào)度。

              小結(jié)
              Spring為Quartz的JobDetail和Trigger提供了更具Bean風(fēng)格的支持類(lèi),這使我們能夠更地方便地在Spring中通過(guò)配置定制這些組件實(shí)例。Spring的SchedulerFactoryBean讓我們可以脫離Quartz自身的配置體系,而以更具Spring風(fēng)格的方式定義Scheduler。此外,還可以享受Scheduler生命周期和Spring 容器生命周期綁定的好處。

           

          posted @ 2009-03-25 18:07 心路 閱讀(10690) | 評(píng)論 (0)編輯 收藏
          如果您用eclipse開(kāi)發(fā)代碼,但是eclipse響應(yīng)很慢,甚至有些時(shí)候你切換一個(gè)java代碼文件或者動(dòng)了一下eclipse,就要等待一段時(shí)間(有點(diǎn)嚴(yán)重到20多秒以上),類(lèi)似卡住了的感覺(jué)(我的內(nèi)存是1G的,磁盤(pán)空閑空間多,而且只開(kāi)了一個(gè)eclipse應(yīng)用,速度也不會(huì)有改善。),那么我這個(gè)方法可以幫助你解決這個(gè)問(wèn)題:

          使用下面的命令行啟動(dòng)eclipse: 

          eclipse.exe -vmargs -Xverify:none -XX:+UseParallelGC -XX:PermSize=20M -Xms64M -Xmx512M

          如果通過(guò)快捷方式啟動(dòng)eclipse,這樣操作:“右鍵->屬性->目標(biāo)(輸入框)”,參照上面的命令行在輸入框中修改其中的命令行。

          myEclipse也可以參照這樣使用。

          通常有用的開(kāi)關(guān)


          以下設(shè)置在大多數(shù)系統(tǒng)應(yīng)該產(chǎn)生比出廠設(shè)置更好的性能。

          • -Xverify:none - 該開(kāi)關(guān)禁用 Java 字節(jié)代碼驗(yàn)證,從而使加載更快,并且在啟動(dòng)過(guò)程中不需要加載類(lèi),僅用于驗(yàn)證。該開(kāi)關(guān)縮短了啟動(dòng)時(shí)間,因此,沒(méi)有理由不使用它。
          • -vmargs - 表示將后面的所有參數(shù)直接傳遞到所指示的 Java VM。 
          • -Xms32m - 該設(shè)置告訴 Java 虛擬機(jī)將它的初始堆大小設(shè)置為 32 兆字節(jié)。通過(guò)告訴 JVM 最初應(yīng)該為堆分配多少內(nèi)存。
          • -Xmx256m - 該設(shè)置告訴 Java 虛擬機(jī)它應(yīng)該為該堆使用的最大內(nèi)存數(shù)量。對(duì)該數(shù)量進(jìn)行強(qiáng)硬的上限限制意味著 Java 進(jìn)程占用的內(nèi)存比可用的物理 RAM 少。對(duì)于具有較多內(nèi)存的系統(tǒng)可以提高該顯示。當(dāng)前默認(rèn)值為 128MB。注意: 不要將該值設(shè)置為接近或大于您系統(tǒng)中物理 RAM 的量,否則它將造成運(yùn)行時(shí)期間嚴(yán)格的交換。
          •  -XX:PermSize=20m - 此 JVM 開(kāi)關(guān)不僅功能更為強(qiáng)大,而且能夠縮短啟動(dòng)時(shí)間。該設(shè)置用于調(diào)整內(nèi)存"永久區(qū)域"(類(lèi)保存在該區(qū)域中)的大小。因此我們向 JVM 提示它將需要的內(nèi)存量。該設(shè)置消除了許多系統(tǒng)啟動(dòng)過(guò)程中的主要垃圾收集事件。 

          更多吸引人的開(kāi)關(guān)

          • -XX:+UseConcMarkSweepGC-XX:+UseParNewGC - 如果您遇到入侵垃圾收集暫停的問(wèn)題,則嘗試這些開(kāi)關(guān)。該開(kāi)關(guān)使 JVM 對(duì)主要的垃圾收集事件(也對(duì)于次要的收集,如果運(yùn)行在多處理器的工作站上)使用不同的算法,一些算法并不停止整個(gè)垃圾收集進(jìn)程。
          • -XX:+UseAdaptiveSizePolicy - 該開(kāi)關(guān)可能有助于提高垃圾收集器吞吐量并減少內(nèi)存占用。在 JDK5.0 中實(shí)現(xiàn)的 garbage collector ergonomics 的一部分。
          • -XX:+UseParallelGC - 一些測(cè)試表明,至少在裝備相當(dāng)好的內(nèi)存的系統(tǒng)上,當(dāng)在單處理器系統(tǒng)上使用該收集算法時(shí),次要垃圾收集的持續(xù)時(shí)間將減半。注意這是自相矛盾的,該收集器設(shè)計(jì)用于在具有十億字節(jié)堆的多處理器系統(tǒng)上工作最佳。沒(méi)有數(shù)據(jù)表示它在主要垃圾收集上的效果。注意: 該收集器和 -XX:+UseConcMarkSweepGC 是相互排斥的。
          • -J-XX:CompileThreshold=100 - 該開(kāi)關(guān)將使啟動(dòng)時(shí)間更慢,通過(guò) HotSpot 來(lái)編譯下載至本機(jī)的代碼的很多方法比其他情況更快。報(bào)告的結(jié)果是 IDE 運(yùn)行之后性能較高,因?yàn)閷⒕幾g比解釋的代碼更多的 UI 代碼。該值表示編譯之前必須調(diào)用方法的次數(shù)。

          影響圖形行為的選項(xiàng) 

          • -Dsun.java2d.opengl=true - 啟用新的基于 OpenGL 的管道,以便 Java 2D 用來(lái)支持使用 OpenGL 的快速硬件渲染。
          • -Dsun.java2d.d3d=false - 該開(kāi)關(guān)禁用 DirectDraw 并且可能解決一些 HW 配置的性能問(wèn)題。
          • -Dawt.nativeDoubleBuffering=true - 該開(kāi)關(guān)使 Swing 假設(shè)操作系統(tǒng)正在處理雙倍緩存并且它不應(yīng)該執(zhí)行任何操作。在遠(yuǎn)程 X 連接上該開(kāi)關(guān)可能不工作,但是對(duì)于本地使用,它非常有用,因?yàn)槟嬲吹搅嗣總€(gè)重畫(huà)的完成,這使它很容易注意到某些操作是否正在造成不必要的重畫(huà)。
          • Font anti-aliasing 用于 Swing widget,可以與 -Dswing.aatext=true 屬性一起啟用。與環(huán)境變量 J2D_PIXMAPS=shared 的設(shè)置和導(dǎo)出一起使用時(shí)非常有用,至少在 Linux 平臺(tái)上可以獲得合理的性能。
          posted @ 2009-03-11 15:14 心路 閱讀(3959) | 評(píng)論 (0)編輯 收藏

          log4j簡(jiǎn)介

          簡(jiǎn)單的說(shuō)log4j就是用于幫助開(kāi)發(fā)人員進(jìn)行日志輸出管理的API類(lèi)庫(kù)。它最重要的特點(diǎn)是可以配置文件靈活的設(shè)置日志信息的優(yōu)先級(jí)、日志信息的輸出目的地以及日志信息的輸出格式。Log4j除了可以記錄程序運(yùn)行日志信息外還有一重要的功能就是用來(lái)顯示調(diào)試信息。

          Log4j的類(lèi)圖

          • Logger - 日志寫(xiě)出器,供程序員輸出日志信息
          • Appender - 日志目的地,把格式化好的日志信息輸出到指定的地方去
          • Layout - 日志格式化器,用來(lái)把程序員的logging request格式化成字符串

          log4j使用方法

          1、定義配置文件

            首先使用配置文件將使我們的應(yīng)用程序更加靈活配置。log日志輸出方式包括輸出優(yōu)先級(jí)、輸出目的地、輸出格式。Log4j支持兩種配置文件格式,一種是XML格式的文件,一種是Java特性文件log4j.properties(鍵=值)。下面將介紹使用log4j.properties文件作為配置文件的方法:

            ①配置根Logger,其語(yǔ)法為:0

            log4j.rootLogger = [ level ] , appenderName, appenderName, …

            其中,level 是日志記錄的優(yōu)先級(jí),分為OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定義的級(jí)別。Log4j建議只使用四個(gè)級(jí)別,優(yōu)先級(jí)從高到低分別是ERROR、WARN、INFO、DEBUG。通過(guò)在這里定義的級(jí)別,您可以控制到應(yīng)用程序中相應(yīng)級(jí)別的日志信息的開(kāi)關(guān)。比如在這里定義了INFO級(jí)別,則應(yīng)用程序中所有DEBUG級(jí)別的日志信息將不被打印出來(lái)。 appenderName就是指定日志信息輸出到哪個(gè)地方。可同時(shí)指定多個(gè)輸出目的地。

            ②配置日志信息輸出目的地Appender,其語(yǔ)法為:

            log4j.appender.appenderName = fully.qualified.name.of.appender.class
            log4j.appender.appenderName.option1 = value1
            …
            log4j.appender.appenderName.option = valueN

            其中,Log4j提供的appender有以下幾種:
            org.apache.log4j.ConsoleAppender(控制臺(tái)),
            org.apache.log4j.FileAppender(文件),
            org.apache.log4j.DailyRollingFileAppender(每天產(chǎn)生一個(gè)日志文件),
            org.apache.log4j.RollingFileAppender(文件大小到達(dá)指定尺寸的時(shí)候產(chǎn)生一個(gè)新的文件),
            org.apache.log4j.WriterAppender(將日志信息以流格式發(fā)送到任意指定的地方)

            ③配置日志信息的格式(布局),其語(yǔ)法為:

            log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
            log4j.appender.appenderName.layout.option1 = value1
            …
            log4j.appender.appenderName.layout.option = valueN

            其中,Log4j提供的layout有以下幾種:
            org.apache.log4j.HTMLLayout(以HTML表格形式布局),
            org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
            org.apache.log4j.SimpleLayout(包含日志信息的級(jí)別和信息字符串),
            org.apache.log4j.TTCCLayout(包含日志產(chǎn)生的時(shí)間、線程、類(lèi)別等等信息)

            Log4J采用類(lèi)似C語(yǔ)言中的printf函數(shù)的打印格式格式化日志信息,打印參數(shù)如下: %m 輸出代碼中指定的消息

            %p 輸出優(yōu)先級(jí),即DEBUG,INFO,WARN,ERROR,F(xiàn)ATAL
            %r 輸出自應(yīng)用啟動(dòng)到輸出該log信息耗費(fèi)的毫秒數(shù)
            %c 輸出所屬的類(lèi)目,通常就是所在類(lèi)的全名
            %t 輸出產(chǎn)生該日志事件的線程名
            %n 輸出一個(gè)回車(chē)換行符,Windows平臺(tái)為“\r\n”,Unix平臺(tái)為“\n”
            %d 輸出日志時(shí)間點(diǎn)的日期或時(shí)間,默認(rèn)格式為ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類(lèi)似:2002年10月18日 22:10:28,921
            %l 輸出日志事件的發(fā)生位置,包括類(lèi)目名、發(fā)生的線程,以及在代碼中的行數(shù)。舉例:Testlog4.main(TestLog4.java:10)

          2、在代碼中使用Log4j

            ①得到記錄器

            使用Log4j,第一步就是獲取日志記錄器,這個(gè)記錄器將負(fù)責(zé)控制日志信息。其語(yǔ)法為:

            public static Logger getLogger( String name)

            通過(guò)指定的名字獲得記錄器,如果必要的話,則為這個(gè)名字創(chuàng)建一個(gè)新的記錄器。Name一般取本類(lèi)的名字,比如:

            static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )

            ②讀取配置文件

            當(dāng)獲得了日志記錄器之后,第二步將配置Log4j環(huán)境,其語(yǔ)法為:

                  BasicConfigurator.configure (): 自動(dòng)快速地使用缺省Log4j環(huán)境。
            PropertyConfigurator.configure ( String configFilename) :讀取使用Java的特性文件編寫(xiě)的配置文件。

          例:PropertyConfigurator.configure(".\\src\\log4j.properties")
            DOMConfigurator.configure ( String filename ) :讀取XML形式的配置文件。

            ③插入記錄信息(格式化日志信息)

            當(dāng)上兩個(gè)必要步驟執(zhí)行完畢,就可輕松地使用不同優(yōu)先級(jí)別的日志記錄語(yǔ)句插入到您想記錄日志的任何地方,其語(yǔ)法如下:

            Logger.debug ( Object message ) ;
            Logger.info ( Object message ) ;
            Logger.warn ( Object message ) ;
            Logger.error ( Object message ) ;

          下面是配置文件log4j.properties的內(nèi)容: 

          log4j.rootCategory=DEBUG, stdout,R

          log4j.appender.stdout
          =org.apache.log4j.ConsoleAppender

          log4j.appender.stdout.layout
          =org.apache.log4j.PatternLayout

          log4j.appender.stdout.layout.ConversionPattern
          =%5p (%F:%L) - %m%n

          log4j.appender.R
          =org.apache.log4j.RollingFileAppender

          log4j.appender.R.File
          =log.txt

          log4j.appender.R.MaxFileSize
          =100KB

          log4j.appender.R.MaxBackupIndex
          =1

          log4j.appender.R.layout
          =org.apache.log4j.PatternLayout

          log4j.appender.R.layout.ConversionPattern
          =%d{yyyy MMM dd HH:mm:ss} %-5p %- %m%n

          程序說(shuō)明:

          ① log4j.rootCategory=DEBUG, stdout,R

          要顯示所有優(yōu)先權(quán)等于和高于Debug的信息。
          "stdout",”R”表示定義了兩個(gè)輸出端。

          ②下面的三行說(shuō)stdout輸出端其實(shí)是標(biāo)準(zhǔn)輸出Console,也就是屏幕。輸出的格式是PatternLayout。轉(zhuǎn)換方式是%5p (%F:%L) - %m%n,即前五格用來(lái)顯示優(yōu)先權(quán),再顯示當(dāng)前的文件名,加當(dāng)前的行數(shù)。最后是logger.debug()或logger.info()或logger.warn()或logger.error()里的信息。%n表示回車(chē)空行。

          ③再加上下面六行則說(shuō)明log信息不光顯示在屏幕上,而且被保存在一個(gè)叫"log.txt"的文件里,文件最大為100KB。如果文件大小超過(guò)100KB,文件會(huì)被備份成"log.txt.1",新的"log.txt"繼續(xù)記錄log信息。

          我們可以改變log4j.properties,而不需重新編譯就可以控制log信息是否顯示、log信息的輸出端類(lèi)型、輸出方式、輸出格式,等等。舉例如下:

          ①在log4j.properties文件里把"log4j.rootCategory=DEBUG,stdout,R"改寫(xiě)成"log4j.rootCategory=OFF, stdout,R",這樣所有的log信息都不會(huì)顯示了;解決了本文開(kāi)始提出的問(wèn)題。
          ②在log4j.properties文件里把"log4j.rootCategory=DEBUG,stdout,R"改寫(xiě)成"log4j.rootCategory=INFO, stdout,R",這樣只顯示INFO, WARN, ERROR的log信息,而DEBUG信息不會(huì)被顯示;

          在web程序中使用log4j注意問(wèn)題

          1、    由于jsp或servlet在執(zhí)行狀態(tài)時(shí)沒(méi)有當(dāng)前路徑概念,所有使用PropertyConfigurator.configure(String)語(yǔ)句找log4j.properties文件時(shí)要給出相對(duì)于當(dāng)前jsp或servlet的路徑轉(zhuǎn)化成為一個(gè)絕對(duì)的文件系統(tǒng)路徑。方法是使用servletcontext.getrealpath(string)語(yǔ)句。例:

          //得到當(dāng)前jsp路徑

          String prefix 
          = getServletContext().getRealPath("/");

          //讀取log4j.properties

          PropertyConfigurator.configure(prefix
          +"\\WEB-INF\\log4j.properties");

           2、相應(yīng)的log4j.properties設(shè)置某個(gè)屬性時(shí)也要在程序中設(shè)置絕對(duì)路徑。例:

          log4j.appender.R.File屬性設(shè)置日志文件存放位置。可以用讀寫(xiě).properties配置文件的方法進(jìn)行靈活設(shè)置。

          附:[配置文件]

          ### set log levels ###
          log4j.rootLogger
          = debug ,  stdout ,  D ,
           E

          ### 輸出到控制臺(tái) ###
          log4j.appender.stdout
          =
          org.apache.log4j.ConsoleAppender
          log4j.appender.stdout.Target
          =
          System.out
          log4j.appender.stdout.layout
          =
          org.apache.log4j.PatternLayout
          log4j.appender.stdout.layout.ConversionPattern
          =  %d{ABSOLUTE} %5p %c{ 1
          }:%L - %m%n

          ### 輸出到日志文件 ###
          log4j.appender.D
          =
          org.apache.log4j.DailyRollingFileAppender
          log4j.appender.D.File
          =
          logs/log.log
          log4j.appender.D.Append
          =
          true
          log4j.appender.D.Threshold
          =
          DEBUG ## 輸出DEBUG級(jí)別以上的日志
          log4j.appender.D.layout
          =
          org.apache.log4j.PatternLayout
          log4j.appender.D.layout.ConversionPattern
          = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]
           %m%n

          ### 保存異常信息到單獨(dú)文件 ###
          log4j.appender.E
          =
          org.apache.log4j.DailyRollingFileAppender
          log4j.appender.E.File
          =
          logs/error.log ## 異常日志文件名
          log4j.appender.E.Append
          =
          true
          log4j.appender.E.Threshold
          =
          ERROR ## 只輸出ERROR級(jí)別以上的日志!!!
          log4j.appender.E.layout
          =
          org.apache.log4j.PatternLayout
          log4j.appender.E.layout.ConversionPattern
          = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
          posted @ 2009-03-10 13:25 心路 閱讀(1788) | 評(píng)論 (0)編輯 收藏
          Struts1.1機(jī)制[摘錄](méi)

          Struts 的底層機(jī)制是MVC,下面是Struts 1.1中的MVC實(shí)現(xiàn)示意圖:



          首先,控制器(ActionServlet)進(jìn)行初始化工作,讀取配置文件(struts-config.xml),為不同的Struts模塊初始化相應(yīng)的ModuleConfig對(duì)象。比如配置文件中的Action映射定義都保存在ActionConfig集合中。相應(yīng)地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合等。

          控制器接收HTTP請(qǐng)求,并從ActionConfig中找出對(duì)應(yīng)于該請(qǐng)求的Action子類(lèi),如果沒(méi)有對(duì)應(yīng)的Action,控制器直接將請(qǐng)求轉(zhuǎn)發(fā)給JSP或者靜態(tài)頁(yè)面。否則控制器將請(qǐng)求分發(fā)至具體Action類(lèi)進(jìn)行處理。

          在控制器調(diào)用具體Action的execute方法之前,ActionForm對(duì)象將利用HTTP請(qǐng)求中的參數(shù)來(lái)填充自己(可選步驟,需要在配置文件中指定)。具體的ActionForm對(duì)象應(yīng)該是ActionForm的子類(lèi)對(duì)象,它其實(shí)就是一個(gè)JavaBean。此外,還可以在ActionForm類(lèi)中調(diào)用validate方法來(lái)檢查請(qǐng)求參數(shù)的合法性,并且可以返回一個(gè)包含所有錯(cuò)誤信息的ActionErrors對(duì)象。如果執(zhí)行成功,ActionForm自動(dòng)將這些參數(shù)信息以JavaBean(一般稱(chēng)之為form bean)的方式保存在Servlet Context中,這樣它們就可以被其它Action對(duì)象或者JSP調(diào)用。

          Struts將這些ActionForm的配置信息都放在FormBeanConfig集合中,通過(guò)它們Struts能夠知道針對(duì)某個(gè)客戶(hù)請(qǐng)求是否需要?jiǎng)?chuàng)建相應(yīng)的ActionForm實(shí)例。

          Action很簡(jiǎn)單,一般只包含一個(gè)execute方法,它負(fù)責(zé)執(zhí)行相應(yīng)的業(yè)務(wù)邏輯,如果需要,它也進(jìn)行相應(yīng)的數(shù)據(jù)檢查。執(zhí)行完成之后,返回一個(gè)ActionForward對(duì)象,控制器通過(guò)該ActionForward對(duì)象來(lái)進(jìn)行轉(zhuǎn)發(fā)工作。我們主張將獲取數(shù)據(jù)和執(zhí)行業(yè)務(wù)邏輯的功能放到具體的JavaBean當(dāng)中,而Action只負(fù)責(zé)完成與控制有關(guān)的功能。遵循該原則,所以在上圖中我將Action對(duì)象歸為控制器部分。

          提示:其實(shí)在Struts 1.1中,ActionMapping的作用完全可以由ActionConfig來(lái)替代,只不過(guò)由于它是公共API的一部分以及兼容性的問(wèn)題得以保留。ActionMapping通過(guò)繼承ActionConfig來(lái)獲得與其一致的功能,你可以等同地看待它們。同理,其它例如ActionForward與ForwardConfig的關(guān)系也是如此。

          下圖給出了客戶(hù)端從發(fā)出請(qǐng)求到獲得響應(yīng)整個(gè)過(guò)程的圖解說(shuō)明。



          ActionServlet

          首先來(lái)了解MVC中的控制器。在Struts 1.1中缺省采用ActionServlet類(lèi)來(lái)充當(dāng)控制器,當(dāng)然如果ActionServlet不能滿(mǎn)足需求,也可以通過(guò)繼承它來(lái)實(shí)現(xiàn)自己的類(lèi)。可以在/WEB-INF/web.xml中來(lái)具體指定。

          要掌握ActionServlet,就必須了解它所扮演的角色。首先,ActionServlet表示MVC結(jié)構(gòu)中的控制器部分,它需要完成控制器所需的前端控制及轉(zhuǎn)發(fā)請(qǐng)求等職責(zé)。其次,ActionServlet被實(shí)現(xiàn)為一個(gè)專(zhuān)門(mén)處理HTTP請(qǐng)求的Servlet,它同時(shí)具有servlet的特點(diǎn)。在Struts 1.1中它主要完成以下功能:
          接收客戶(hù)端請(qǐng)求;
          根據(jù)客戶(hù)端的URI將請(qǐng)求映射到一個(gè)相應(yīng)的Action類(lèi);
          從請(qǐng)求中獲取數(shù)據(jù)填充Form Bean(如果需要);
          調(diào)用Action類(lèi)的execute()方法獲取數(shù)據(jù)或者執(zhí)行業(yè)務(wù)邏輯;
          選擇正確的視圖響應(yīng)客戶(hù)。
          此外,ActionServlet還負(fù)責(zé)初始化和清除應(yīng)用配置信息的任務(wù)。ActionServlet的初始化工作在init方法中完成,它可以分為兩個(gè)部分:初始化ActionServlet自身的一些信息以及每個(gè)模塊的配置信息。前者主要通過(guò)initInternal、initOther和initServlet三個(gè)方法來(lái)完成。

          我們可以在/WEB-INF/web.xml中指定具體的控制器以及初始參數(shù)。

          ActionForm

          對(duì)于ActionForm你可以從以下幾個(gè)方面來(lái)理解:
          1、ActionForm表示HTTP窗體中的數(shù)據(jù),可以將其看作是模型和視圖的中介,它負(fù)責(zé)保存視圖中的數(shù)據(jù)供模型或者視圖使用。Struts 1.1文檔中把它比作HTTP和Action之間的防火墻,這體現(xiàn)了ActionForm具有的過(guò)濾保護(hù)的作用,只有通過(guò)ActionForm驗(yàn)證的數(shù)據(jù)才能夠發(fā)送到Action處理。
           
          2、ActionForm是與一個(gè)或多個(gè)ActionConfig關(guān)聯(lián)的JavaBean,在相應(yīng)的action的execute方法被調(diào)用之前,ActionForm會(huì)自動(dòng)利用請(qǐng)求參數(shù)來(lái)填充自己(初始化屬性)。
           
          3、ActionForm是一個(gè)抽象類(lèi),必須通過(guò)繼承來(lái)實(shí)現(xiàn)自己的類(lèi)。

          4、ActionForm首先利用屬性的getter和setter方法來(lái)實(shí)現(xiàn)初始化,初始化完畢后,ActionForm的validate方法被調(diào)用,可以檢查請(qǐng)求參數(shù)的正確性和有效性,并且可以將錯(cuò)誤信息以ActionErrors的形式返回到輸入窗體。否則,ActionForm將被作為參數(shù)傳給action的execute方法以供使用。

          5、ActionForm bean的生命周期可以設(shè)置為session(缺省)和request,當(dāng)設(shè)置為session時(shí),記得在reset方法中將所有的屬性重新設(shè)置為初始值。

          6、由于ActionForm對(duì)應(yīng)于HTTP窗體,所以隨著頁(yè)面的增多,ActionForm將會(huì)急速增加。而且可能同一類(lèi)型頁(yè)面字段將會(huì)在不同的ActionForm中出現(xiàn),并且在每個(gè)ActionForm中都存在相同的驗(yàn)證代碼。為了解決這個(gè)問(wèn)題,可以為整個(gè)應(yīng)用實(shí)現(xiàn)一個(gè)ActionForm或者至少一個(gè)模塊對(duì)應(yīng)于一個(gè)ActionForm。

          但是,聚合的代價(jià)就是復(fù)用性很差,而且難維護(hù)。針對(duì)這個(gè)問(wèn)題,在Struts 1.1中提出了DynaActionForm的概念。

          DynaActionForm類(lèi)

          DynaActionForm的目的就是減少ActionForm的數(shù)目,利用DynaActionForm不必創(chuàng)建一個(gè)個(gè)具體的ActionForm類(lèi),而是在配置文件中配置出所需的虛擬ActionForm。例如,在下表中通過(guò)指定<form-bean>的type為"org.apache.struts.action.DynaActionForm"來(lái)創(chuàng)建一個(gè)動(dòng)態(tài)的ActionForm--loginForm。
          <form-beans>
              <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">  
                  <form-property name="actionClass" type="java.lang.String"/>
                  <form-property name="username" type="java.lang.String"/>
                  <form-property name="password" type="java.lang.String"/> 
              </form-bean> 
          </form-beans>
          動(dòng)態(tài)的ActionForm的使用方法跟普通的ActionForm相同,但是要注意一點(diǎn):普通的ActionForm對(duì)象需要為每個(gè)屬性提供getter和setter方法,如果使用DynaActionForm,它將屬性保存在一個(gè)HashMap類(lèi)對(duì)象中,同時(shí)提供相應(yīng)的get(name) 和 set(name)方法,其中參數(shù)name是要訪問(wèn)的屬性名。例如要訪問(wèn)DynaActionForm中username的值,可以采用類(lèi)似的代碼:
          String username = (String)form.get("username");

          由于值存放于一個(gè)HashMap對(duì)象,所以要記得對(duì)get()方法返回的Object對(duì)象做強(qiáng)制性類(lèi)型轉(zhuǎn)換。正是由于這點(diǎn)區(qū)別,如果在Action中非常頻繁地使用ActionForm對(duì)象,建議還是使用普通的ActionForm對(duì)象。

          Action

          我們通過(guò)繼承Action類(lèi)來(lái)實(shí)現(xiàn)具體的執(zhí)行類(lèi)。具體Action類(lèi)的功能一般都在execute(以前是perform方法)方法中完成,其中主要涉及到以下幾個(gè)方面:
          a、輔助ActionForm進(jìn)行一些表單數(shù)據(jù)的檢查; 
          b、執(zhí)行必要的業(yè)務(wù)邏輯,比如存取數(shù)據(jù)庫(kù),調(diào)用實(shí)體bean等; 
          c、更新服務(wù)器端的bean數(shù)據(jù),后續(xù)對(duì)象中可能會(huì)用到這些數(shù)據(jù),比如在JSP中利用bean:write來(lái)獲得這些數(shù)據(jù); 
          d、根據(jù)處理結(jié)果決定程序的去處,并以ActionForward對(duì)象的形式返回給ActionServlet。 

          提示:由于在Action和ActionForm中都可以實(shí)現(xiàn)驗(yàn)證方法,那么如何來(lái)安排它們之間的分工呢?一般來(lái)說(shuō),我們秉著MVC分離的原則,也就是視圖級(jí)的驗(yàn)證工作放在ActionForm來(lái)完成,比如輸入不能為空,email格式是否正確,利用ValidatorForm可以很輕松地完成這些工作。而與具體業(yè)務(wù)相關(guān)的驗(yàn)證則放入Action中,這樣就可以獲得最大ActionForm重用性的可能。

          前面提到過(guò),我們主張將業(yè)務(wù)邏輯執(zhí)行分離到單獨(dú)的JavaBean中,而Action只負(fù)責(zé)錯(cuò)誤處理和流程控制。而且考慮到重用性的原因,在執(zhí)行業(yè)務(wù)邏輯的JavaBean中不要引用任何與Web應(yīng)用相關(guān)的對(duì)象,比如HttpServletRequest,HttpServletResponse等對(duì)象,而應(yīng)該將其轉(zhuǎn)化為普通的Java對(duì)象。
          posted @ 2009-03-06 15:14 心路 閱讀(618) | 評(píng)論 (0)編輯 收藏
          今天終于開(kāi)博了 主要來(lái)記錄遇到的難題及解決方案 以及作為網(wǎng)路上精華文章的備忘錄。
          posted @ 2009-03-06 09:54 心路 閱讀(227) | 評(píng)論 (0)編輯 收藏
          僅列出標(biāo)題  
          主站蜘蛛池模板: 博野县| 德阳市| 宁乡县| 大荔县| 肥乡县| 绥芬河市| 忻州市| 安远县| 宜宾市| 徐闻县| 简阳市| 松潘县| 神农架林区| 平度市| 浮梁县| 启东市| 扎鲁特旗| 故城县| 体育| 通海县| 泸定县| 铜陵市| 班玛县| 镇原县| 荔浦县| 尤溪县| 个旧市| 五大连池市| 石景山区| 鄂州市| 高邑县| 电白县| 阿坝| 大理市| 二连浩特市| 轮台县| 绍兴县| 南漳县| 英德市| 浦县| 锦屏县|