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>
一直以來(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))
當(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
![]() 其實(shí)理解 major.minor 就像是我們可以這么想像,同樣是微軟件的程序,32 位的應(yīng)用程序不能拿到 16 位系統(tǒng)中執(zhí)行那樣。 |
概述
各種企業(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ō)它提供了兩方面的支持:
創(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:
在②處獲取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è)具體的例子:
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()方法,它的代碼如下所示:
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)格的SimpleTriggerBean和CronTriggerBean擴(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ù):
需要特別注意的是,①處配置的JobDataMap是Trigger的JobDataMap,任務(wù)執(zhí)行時(shí)必須通過(guò)以下方式獲取配置的值:
CronTriggerBean
CronTriggerBean擴(kuò)展于CronTrigger,觸發(fā)器的名字即為Bean的名字,保存在默認(rèn)組中。在CronTrigger的基礎(chǔ)上,新增的屬性和SimpleTriggerBean大致相同,配置的方法也和SimpleTriggerBean相似,下面給出一個(gè)簡(jiǎn)單的例子:
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屬性的例子:
在實(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 容器生命周期綁定的好處。
如果您用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:
如果通過(guò)快捷方式啟動(dòng)eclipse,這樣操作:“右鍵->屬性->目標(biāo)(輸入框)”,參照上面的命令行在輸入框中修改其中的命令行。
myEclipse也可以參照這樣使用。
以下設(shè)置在大多數(shù)系統(tǒng)應(yīng)該產(chǎn)生比出廠設(shè)置更好的性能。
-XX:+UseConcMarkSweepGC
是相互排斥的。