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>
一直以來都是用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 的網站上翻騰出我從來都沒用過的古董來)
當然你也可以用其他方法查看版本號,比如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
![]() 其實理解 major.minor 就像是我們可以這么想像,同樣是微軟件的程序,32 位的應用程序不能拿到 16 位系統中執行那樣。 |
概述
各種企業應用幾乎都會碰到任務調度的需求,就拿論壇來說:每隔半個小時生成精華文章的RSS文件,每天凌晨統計論壇用戶的積分排名,每隔30分鐘執行鎖定用戶解鎖任務。對于一個典型的MIS系統來說,在每月1號凌晨統計上個月各部門的業務數據生成月報表,每半個小時查詢用戶是否已經有快到期的待處理業務……
Quartz 是開源任務調度框架中的翹首,它提供了強大任務調度機制,同時保持了使用的簡單性。Quartz 允許開發人員靈活地定義觸發器的調度時間表,并可以對觸發器和任務進行關聯映射。此外,Quartz提供了調度運行環境的持久化機制,可以保存并恢復調度現場,即使系統因故障關閉,任務調度現場數據并不會丟失。此外,Quartz還提供了組件式的偵聽器、各種插件、線程池等功能。
Spring為創建Quartz的Scheduler、Trigger和JobDetail提供了便利的FactoryBean類,以便能夠在Spring 容器中享受注入的好處。此外Spring還提供了一些便利工具類直接將Spring中的Bean包裝成合法的任務。Spring進一步降低了使用Quartz的難度,能以更具Spring風格的方式使用Quartz。概括來說它提供了兩方面的支持:
創建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:
在②處獲取size值,在③處還可以根據鍵“applicationContext”獲取ApplicationContext,有了ApplicationContext的引用,Job就可以毫無障礙訪問Spring容器中的任何Bean了。MyJob可以在execute()方法中對JobDataMap進行更改,如④所示。如果MyJob實現Job接口,這個更改對于下一次執行是不可見的,如果MyJob實現StatefulJob接口,這種更改對下一次執行是可見的。
MethodInvokingJobDetailFactoryBean
通常情況下,任務都定義在一個業務類方法中。這時,為了滿足Quartz Job接口的規定,還需要定義一個引用業務類方法的實現類。為了避免創建這個只包含一行調用代碼的Job實現類,Spring為我們提供了MethodInvokingJobDetailFactoryBean,借由該FactoryBean,我們可以將一個Bean的某個方法封裝成滿足Quartz要求的Job。來看一個具體的例子:
jobDetail_1將MyService#doJob()封裝成一個任務,同時通過concurrent屬性指定任務的類型,默認情況下封裝為無狀態的任務,如果希望目標封裝為有狀態的任務,僅需要將concurrent設置為false就可以了。Spring通過名為concurrent的屬性指定任務的類型,能夠更直接地描述到任務執行的方式(有狀態的任務不能并發執行,無狀態的任務可并發執行)。
MyService服務類擁有一個doJob()方法,它的代碼如下所示:
doJob()方法即可以是static也可以是非static的,但不能擁有方法入參。通過MethodInvokingJobDetailFactoryBean產生的JobDetail不能被序列化,所以不能被持久化到數據庫中的,如果希望使用持久化任務,則你只能創建正規的Quartz的Job實現類了。
創建Trigger
Quartz中另一個重要的組件就是Trigger,Spring按照相似的思路分別為SimpleTrigger和CronTrigger提供了更具Bean風格的SimpleTriggerBean和CronTriggerBean擴展類,通過這兩個擴展類更容易在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數據:
需要特別注意的是,①處配置的JobDataMap是Trigger的JobDataMap,任務執行時必須通過以下方式獲取配置的值:
CronTriggerBean
CronTriggerBean擴展于CronTrigger,觸發器的名字即為Bean的名字,保存在默認組中。在CronTrigger的基礎上,新增的屬性和SimpleTriggerBean大致相同,配置的方法也和SimpleTriggerBean相似,下面給出一個簡單的例子:
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屬性的例子:
在實際應用中,我們并不總是在程序部署的時候就可能確定需要哪些任務,往往需要在運行期根據業務數據動態產生觸發器和任務。你完全可以在運行期通過代碼調用SchedulerFactoryBean獲取Scheduler實例,進行動態的任務注冊和調度。
小結
Spring為Quartz的JobDetail和Trigger提供了更具Bean風格的支持類,這使我們能夠更地方便地在Spring中通過配置定制這些組件實例。Spring的SchedulerFactoryBean讓我們可以脫離Quartz自身的配置體系,而以更具Spring風格的方式定義Scheduler。此外,還可以享受Scheduler生命周期和Spring 容器生命周期綁定的好處。