posts - 7,comments - 5,trackbacks - 0

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

          Image 標簽 <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 標簽 Struts-Form 下的 Image Button 按鈕。其中可以使用 servlet 隨機生成的圖片,或者 jsp 文件。 JSP 下的彩色驗證碼的解決:

          隨機驗證圖片的生成文件

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

          <%!

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

                  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);

                  }

          %>

          <%

          // 設置頁面不緩存

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

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

          response.setDateHeader("Expires", 0);

          // 在內存中創建圖象

          int width=60, height=20;

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

          // 獲取圖形上下文

          Graphics g = image.getGraphics();

          // 生成隨機類

          Random random = new Random();

          // 設定背景色

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

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

          // 設定字體

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

          // 畫邊框

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

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

          // 隨機產生 155 條干擾線,使圖象中的認證碼不易被其它程序探測到

          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);

          }

          // 取隨機產生的認證碼 (4 位數字 )

          String sRand="";

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

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

              sRand+=rand;

              // 將認證碼顯示到圖象中

              g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));// 調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成

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

          }

          // 將認證碼存入 SESSION

          session.setAttribute("rand",sRand);

          // 圖象生效

          g.dispose();

          // 輸出圖象到頁面

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

          %>

          使用頁面:

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

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

          <html>

          <head>

          <title> 認證碼輸入頁面 </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> 系統產生的認證碼: </td>

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

          </tr>

          <tr>

          <td align=left> 輸入上面的認證碼: </td>

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

          </tr>

          <tr>

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

          </tr>
          </table>

          </form>

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

                  一直以來都是用jdk1.5,這次重返電信由于其系統是在jdk1.4上編譯的,編譯的時候出現了unsupported major.minor version49.0的錯誤,上網查看了一下還是一個很普遍的錯誤,搗鼓了兩天終于搗鼓出一些東西,現分享給大家。

               何謂 major.minor,且又居身于何處呢?先感性認識并找到 major.minor 來。順便寫一段 代碼,然后用 JDK 1.5 的編譯器編譯成class,用UltraEdit或者其他能打開非十進制文件的軟件打開此class,見下圖:        

           

                 從上圖中我們看出來了什么是 major.minor version 了,它相當于一個軟件的主次版本號,只是在這里是標識的一個 Java Class 的主版本號和次版本號,同時我們看到 minor_version 為 0x0000,major_version 為 0x0031,轉換為十制數分別為0 和 49,即 major.minor 就是 49.0 了。

                現在不妨從 JDK 1.1 到 JDK 1.7 編譯器編譯出的 class 的默認 minor.major version 吧。(又走到 Sun 的網站上翻騰出我從來都沒用過的古董來)
               

          JDK 編譯器版本 target 參數 十六進制 minor.major 十進制 minor.major
          jdk1.1.8 不能帶 target 參數 00 03 00 2D 45.3
          jdk1.2.2 不帶(默認為 -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 不帶(默認為 -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 不帶(默認為 -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 不帶(默認為 -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 不帶(默認為 -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 不帶(默認為 -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 不帶(默認為 -target 1.2) 00 00   00 2E 46.0
          Apache Harmony 5.0M3 -target 1.4 00 00   00 30 48.0

           

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

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

                相應的如果使用 ant ,它的 javac 任務也可對應的選擇 target 和 source

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

          如果是在開發中,可以肯定的是現在真正算得上是 JAVA IDE 對于工程也都有編譯選項設置目標代碼的。例如 Eclipse 的項目屬性中的 Java Compiler 設置,如圖:

                  

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

          如果我們發布前了解到目標 JVM 版本,知道怎么從 java class 文件中看出 major.minor 版本來,就不用等到服務器報出異常才著手去解決,也就能預知到可能發生的問題。

          其他時候遇到這個問題應具體解決,總之問題的根由是低版本的 JVM 無法加載高版本的 class 文件造成的,找到高版本的 class 文件處理一下就行了。

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

              概述
              各種企業應用幾乎都會碰到任務調度的需求,就拿論壇來說:每隔半個小時生成精華文章的RSS文件,每天凌晨統計論壇用戶的積分排名,每隔30分鐘執行鎖定用戶解鎖任務。對于一個典型的MIS系統來說,在每月1號凌晨統計上個月各部門的業務數據生成月報表,每半個小時查詢用戶是否已經有快到期的待處理業務…… 

              Quartz 是開源任務調度框架中的翹首,它提供了強大任務調度機制,同時保持了使用的簡單性。Quartz 允許開發人員靈活地定義觸發器的調度時間表,并可以對觸發器和任務進行關聯映射。此外,Quartz提供了調度運行環境的持久化機制,可以保存并恢復調度現場,即使系統因故障關閉,任務調度現場數據并不會丟失。此外,Quartz還提供了組件式的偵聽器、各種插件、線程池等功能。

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

          1)為Quartz的重要組件類提供更具Bean風格的擴展類; 
          2)提供創建Scheduler的BeanFactory類,方便在Spring環境下創建對應的組件對象,并結合Spring容器生命周期進行啟動和停止的動作。

           
              創建JobDetail 
              可以直接使用Quartz的JobDetail在Spring中配置一個JobDetail Bean,但是JobDetail使用帶參的構造函數,對于習慣通過屬性配置的Spring用戶來說存在使用上的不便。為此Spring通過擴展JobDetail提供了一個更具Bean風格的JobDetailBean。此外,Spring提供了一個MethodInvokingJobDetailFactoryBean,通過這個FactoryBean可以將Spring容器中Bean的方法包裝成Quartz任務,這樣開發者就不必為Job創建對應的類。
              JobDetailBean
              JobDetailBean擴展于Quartz的JobDetail。使用該Bean聲明JobDetail時,Bean的名字即是任務的名字,如果沒有指定所屬組,即使用默認組。除了JobDetail中的屬性外,還定義了以下屬性:
              ● jobClass:類型為Class,實現Job接口的任務類;
              ● beanName:默認為Bean的id名,通過該屬性顯式指定Bean名稱,對應任務的名稱;
              ● jobDataAsMap:類型為Map,為任務所對應的JobDataMap提供值。之所以需要提供這個屬性,是因為除非你手工注冊一 個編輯器,你不能直接配置JobDataMap類型的值,所以Spring通過jobDataAsMap設置JobDataMap的值;
              ●applicationContextJobDataKey:你可以將Spring ApplicationContext的引用保存到JobDataMap中,以便在Job的代碼中訪問ApplicationContext。為了達到這個目的,你需要指定一個鍵,用以在jobDataAsMap中保存ApplicationContext,如果不設置此鍵,JobDetailBean就不將ApplicationContext放入到JobDataMap中;
              ●jobListenerNames:類型為String[],指定注冊在Scheduler中的JobListeners名稱,以便讓這些監聽器對本任務的事件進行監聽。
           下面配置片斷使用JobDetailBean在Spring中配置一個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任務類,并為Job對應JobDataMap設置了一個size的數據。此外,通過指定applicationContextJobDataKey讓Job的JobDataMap持有Spring ApplicationContext的引用。這樣,MyJob在運行時就可以通過JobDataMap訪問到size和ApplicationContext了。來看一下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關聯的JobDataMap
          String size 
          =(String)dataMap.get("size");  ②
          ApplicationContext ctx 
          = (ApplicationContext)dataMap.get("applicationContext");  ③
          System.out.println(
          "size:"+size);
          dataMap.put(
          "size",size+"0");  ④對JobDataMap所做的更改是否被會持久,取決于任務的類型
          //do sth 
          }
          }

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

          MethodInvokingJobDetailFactoryBean
              通常情況下,任務都定義在一個業務類方法中。這時,為了滿足Quartz Job接口的規定,還需要定義一個引用業務類方法的實現類。為了避免創建這個只包含一行調用代碼的Job實現類,Spring為我們提供了MethodInvokingJobDetailFactoryBean,借由該FactoryBean,我們可以將一個Bean的某個方法封裝成滿足Quartz要求的Job。來看一個具體的例子:

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

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

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

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

              doJob()方法即可以是static也可以是非static的,但不能擁有方法入參。通過MethodInvokingJobDetailFactoryBean產生的JobDetail不能被序列化,所以不能被持久化到數據庫中的,如果希望使用持久化任務,則你只能創建正規的Quartz的Job實現類了。

              創建Trigger
              Quartz中另一個重要的組件就是Trigger,Spring按照相似的思路分別為SimpleTrigger和CronTrigger提供了更具Bean風格的SimpleTriggerBeanCronTriggerBean擴展類,通過這兩個擴展類更容易在Spring中以Bean的方式配置Trigger。

              SimpleTriggerBean
              默認情況下,通過SimpleTriggerBean配置的Trigger名字即為Bean的名字,并屬于默認組Trigger組。SimpleTriggerBean在SimpleTrigger的基礎上,新增了以下屬性:
              ● jobDetail:對應的JobDetail;
              ● beanName:默認為Bean的id名,通過該屬性顯式指定Bean名稱,它對應Trigger的名稱;
              ● jobDataAsMap:以Map類型為Trigger關聯的JobDataMap提供值;
              ● startDelay:延遲多少時間開始觸發,單位為毫秒,默認為0;
              ● triggerListenerNames:類型為String[],指定注冊在Scheduler中的TriggerListener名稱,以便讓這些監聽器對本觸發器的事件進行監聽。
              下面的實例使用SimpleTriggerBean定義了一個Trigger,該Trigger和jobDetail相關聯,延遲10秒后啟動,時間間隔為20秒,重復執行100次。此外,我們還為Trigger設置了JobDataMap數據:

          <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,任務執行時必須通過以下方式獲取配置的值:

          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");   ② 對JobDataMap的更改不會被持久,不影響下次的執行
                  …
              }
          }

              CronTriggerBean
              CronTriggerBean擴展于CronTrigger,觸發器的名字即為Bean的名字,保存在默認組中。在CronTrigger的基礎上,新增的屬性和SimpleTriggerBean大致相同,配置的方法也和SimpleTriggerBean相似,下面給出一個簡單的例子:

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

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

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

          <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
              …
              <property name="quartzProperties">
                  <props>
                      <prop key="org.quartz.threadPool.class"①Quartz屬性項1
                          org.quartz.simpl.SimpleThreadPool
                      </prop>
                      <prop key="org.quartz.threadPool.threadCount">10</prop①Quartz屬性項2
                  </props>
              </property>
          </bean>

             在實際應用中,我們并不總是在程序部署的時候就可能確定需要哪些任務,往往需要在運行期根據業務數據動態產生觸發器和任務。你完全可以在運行期通過代碼調用SchedulerFactoryBean獲取Scheduler實例,進行動態的任務注冊和調度。

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

           

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

          使用下面的命令行啟動eclipse: 

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

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

          myEclipse也可以參照這樣使用。

          通常有用的開關


          以下設置在大多數系統應該產生比出廠設置更好的性能。

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

          更多吸引人的開關

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

          影響圖形行為的選項 

          • -Dsun.java2d.opengl=true - 啟用新的基于 OpenGL 的管道,以便 Java 2D 用來支持使用 OpenGL 的快速硬件渲染。
          • -Dsun.java2d.d3d=false - 該開關禁用 DirectDraw 并且可能解決一些 HW 配置的性能問題。
          • -Dawt.nativeDoubleBuffering=true - 該開關使 Swing 假設操作系統正在處理雙倍緩存并且它不應該執行任何操作。在遠程 X 連接上該開關可能不工作,但是對于本地使用,它非常有用,因為您真正看到了每個重畫的完成,這使它很容易注意到某些操作是否正在造成不必要的重畫。
          • Font anti-aliasing 用于 Swing widget,可以與 -Dswing.aatext=true 屬性一起啟用。與環境變量 J2D_PIXMAPS=shared 的設置和導出一起使用時非常有用,至少在 Linux 平臺上可以獲得合理的性能。
          posted @ 2009-03-11 15:14 心路 閱讀(3953) | 評論 (0)編輯 收藏

          log4j簡介

          簡單的說log4j就是用于幫助開發人員進行日志輸出管理的API類庫。它最重要的特點是可以配置文件靈活的設置日志信息的優先級、日志信息的輸出目的地以及日志信息的輸出格式。Log4j除了可以記錄程序運行日志信息外還有一重要的功能就是用來顯示調試信息。

          Log4j的類圖

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

          log4j使用方法

          1、定義配置文件

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

            ①配置根Logger,其語法為:0

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

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

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

            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(控制臺),
            org.apache.log4j.FileAppender(文件),
            org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件),
            org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件),
            org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方)

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

            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(包含日志信息的級別和信息字符串),
            org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)

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

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

          2、在代碼中使用Log4j

            ①得到記錄器

            使用Log4j,第一步就是獲取日志記錄器,這個記錄器將負責控制日志信息。其語法為:

            public static Logger getLogger( String name)

            通過指定的名字獲得記錄器,如果必要的話,則為這個名字創建一個新的記錄器。Name一般取本類的名字,比如:

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

            ②讀取配置文件

            當獲得了日志記錄器之后,第二步將配置Log4j環境,其語法為:

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

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

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

            當上兩個必要步驟執行完畢,就可輕松地使用不同優先級別的日志記錄語句插入到您想記錄日志的任何地方,其語法如下:

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

          下面是配置文件log4j.properties的內容: 

          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

          程序說明:

          ① log4j.rootCategory=DEBUG, stdout,R

          要顯示所有優先權等于和高于Debug的信息。
          "stdout",”R”表示定義了兩個輸出端。

          ②下面的三行說stdout輸出端其實是標準輸出Console,也就是屏幕。輸出的格式是PatternLayout。轉換方式是%5p (%F:%L) - %m%n,即前五格用來顯示優先權,再顯示當前的文件名,加當前的行數。最后是logger.debug()或logger.info()或logger.warn()或logger.error()里的信息。%n表示回車空行。

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

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

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

          在web程序中使用log4j注意問題

          1、    由于jsp或servlet在執行狀態時沒有當前路徑概念,所有使用PropertyConfigurator.configure(String)語句找log4j.properties文件時要給出相對于當前jsp或servlet的路徑轉化成為一個絕對的文件系統路徑。方法是使用servletcontext.getrealpath(string)語句。例:

          //得到當前jsp路徑

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

          //讀取log4j.properties

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

           2、相應的log4j.properties設置某個屬性時也要在程序中設置絕對路徑。例:

          log4j.appender.R.File屬性設置日志文件存放位置。可以用讀寫.properties配置文件的方法進行靈活設置。

          附:[配置文件]

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

          ### 輸出到控制臺 ###
          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級別以上的日志
          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

          ### 保存異常信息到單獨文件 ###
          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級別以上的日志!!!
          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 心路 閱讀(1783) | 評論 (0)編輯 收藏
          Struts1.1機制[摘錄]

          Struts 的底層機制是MVC,下面是Struts 1.1中的MVC實現示意圖:



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

          控制器接收HTTP請求,并從ActionConfig中找出對應于該請求的Action子類,如果沒有對應的Action,控制器直接將請求轉發給JSP或者靜態頁面。否則控制器將請求分發至具體Action類進行處理。

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

          Struts將這些ActionForm的配置信息都放在FormBeanConfig集合中,通過它們Struts能夠知道針對某個客戶請求是否需要創建相應的ActionForm實例。

          Action很簡單,一般只包含一個execute方法,它負責執行相應的業務邏輯,如果需要,它也進行相應的數據檢查。執行完成之后,返回一個ActionForward對象,控制器通過該ActionForward對象來進行轉發工作。我們主張將獲取數據和執行業務邏輯的功能放到具體的JavaBean當中,而Action只負責完成與控制有關的功能。遵循該原則,所以在上圖中我將Action對象歸為控制器部分。

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

          下圖給出了客戶端從發出請求到獲得響應整個過程的圖解說明。



          ActionServlet

          首先來了解MVC中的控制器。在Struts 1.1中缺省采用ActionServlet類來充當控制器,當然如果ActionServlet不能滿足需求,也可以通過繼承它來實現自己的類。可以在/WEB-INF/web.xml中來具體指定。

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

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

          ActionForm

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

          4、ActionForm首先利用屬性的getter和setter方法來實現初始化,初始化完畢后,ActionForm的validate方法被調用,可以檢查請求參數的正確性和有效性,并且可以將錯誤信息以ActionErrors的形式返回到輸入窗體。否則,ActionForm將被作為參數傳給action的execute方法以供使用。

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

          6、由于ActionForm對應于HTTP窗體,所以隨著頁面的增多,ActionForm將會急速增加。而且可能同一類型頁面字段將會在不同的ActionForm中出現,并且在每個ActionForm中都存在相同的驗證代碼。為了解決這個問題,可以為整個應用實現一個ActionForm或者至少一個模塊對應于一個ActionForm。

          但是,聚合的代價就是復用性很差,而且難維護。針對這個問題,在Struts 1.1中提出了DynaActionForm的概念。

          DynaActionForm類

          DynaActionForm的目的就是減少ActionForm的數目,利用DynaActionForm不必創建一個個具體的ActionForm類,而是在配置文件中配置出所需的虛擬ActionForm。例如,在下表中通過指定<form-bean>的type為"org.apache.struts.action.DynaActionForm"來創建一個動態的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>
          動態的ActionForm的使用方法跟普通的ActionForm相同,但是要注意一點:普通的ActionForm對象需要為每個屬性提供getter和setter方法,如果使用DynaActionForm,它將屬性保存在一個HashMap類對象中,同時提供相應的get(name) 和 set(name)方法,其中參數name是要訪問的屬性名。例如要訪問DynaActionForm中username的值,可以采用類似的代碼:
          String username = (String)form.get("username");

          由于值存放于一個HashMap對象,所以要記得對get()方法返回的Object對象做強制性類型轉換。正是由于這點區別,如果在Action中非常頻繁地使用ActionForm對象,建議還是使用普通的ActionForm對象。

          Action

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

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

          前面提到過,我們主張將業務邏輯執行分離到單獨的JavaBean中,而Action只負責錯誤處理和流程控制。而且考慮到重用性的原因,在執行業務邏輯的JavaBean中不要引用任何與Web應用相關的對象,比如HttpServletRequest,HttpServletResponse等對象,而應該將其轉化為普通的Java對象。
          posted @ 2009-03-06 15:14 心路 閱讀(614) | 評論 (0)編輯 收藏
          今天終于開博了 主要來記錄遇到的難題及解決方案 以及作為網路上精華文章的備忘錄。
          posted @ 2009-03-06 09:54 心路 閱讀(223) | 評論 (0)編輯 收藏
          主站蜘蛛池模板: 岢岚县| 红安县| 阜阳市| 铁力市| 仙桃市| 伊吾县| 新巴尔虎左旗| 南郑县| 昌平区| 洪湖市| 阳朔县| 壤塘县| 理塘县| 龙口市| 萝北县| 微博| 吉木萨尔县| 汉沽区| 武定县| 醴陵市| 苏州市| 二手房| 吉首市| 绍兴县| 德钦县| 锦州市| 西吉县| 赣州市| 永清县| 新野县| 五峰| 金山区| 全州县| 普格县| 布拖县| 谢通门县| 伊宁市| 甘肃省| 剑川县| 徐闻县| 永嘉县|