最近碰到的問(wèn)題,客戶(hù)端調(diào)用本地的掃描儀,將掃描的文件上傳。 使用到的技術(shù):applet,twain,HttpClient 當(dāng)然也碰到很多問(wèn)題,因?yàn)樵谶@周之前我都不知道什么是applet 一.Applet操作本地資源 基于安全方面的原因,applet是不允許操作本地資源的。但是java提供了相應(yīng)的為jar包簽名的機(jī)制來(lái)提升applet的權(quán)限。相信很多人都碰到過(guò)這種對(duì)話(huà)框: 讓用戶(hù)來(lái)決定是否給applet提升權(quán)限,如果用戶(hù)信任這個(gè)資源,applet將能操作本地資源。
1.為applet依賴(lài)的jar包簽名 java提供了兩個(gè)工具; keytool用于生成存放key的庫(kù) jarsigner用于為jar進(jìn)行簽名
首先建立一個(gè)keystore(這是在當(dāng)前路徑上操作): keytool -genkey -alias zengge -keystore zengge.keystore keytool -genkey表示建庫(kù) -alias zengge是為要建立的key取一個(gè)別名 -keystore zengge.keystore是建立一個(gè)名字叫zengge.keystore的key庫(kù),key就存在里面. 如下圖:
有了keystore之后jarsigner就可以利用存放在keystore中的key來(lái)為jar簽名
包里面的META-INFO里面只有一個(gè)文件,且內(nèi)容為上圖
接下來(lái)為jar包簽名: jarsigner -keystore zengge.keystore HelloWorld.jar zengge
密碼為建立keystore時(shí)的密碼
再來(lái)看一下簽過(guò)名的jar里面的情況有什么變化:
可以看到META-INFO里面現(xiàn)在是三個(gè)文件,.DSAG與.SF我想肯定是用來(lái)加解密用的,大家注意現(xiàn)在的MANIFEST.MF, 可以看出為每個(gè)類(lèi)添加了一個(gè)SHA簽名,用它來(lái)保證,這個(gè)jar里面的內(nèi)容不會(huì)被其它人修改,用戶(hù)可以相信這個(gè)jar。
2.將applet嵌入html applet是通過(guò)瀏覽器來(lái)運(yùn)行了,可能你會(huì)問(wèn),java的東西瀏覽器怎么能運(yùn)行呢,難道客戶(hù)端也要安裝java? 實(shí)際上applet是通過(guò)嵌在瀏覽器中的jvm在運(yùn)行,但是這個(gè)jvm是從那里來(lái)的呢? 對(duì)于IE,大家可以看一下,下圖中的java如果選中,就表示會(huì)調(diào)用本地的jre來(lái)運(yùn)行applet。
但是絕大部分情況下,客戶(hù)端是不會(huì)安裝java的啊,還有firefox下面沒(méi)有類(lèi)似的這種選項(xiàng)。那么要如何來(lái)解決這種問(wèn)題呢? 早期的applet都是用applet標(biāo)簽來(lái)嵌入html的(當(dāng)然現(xiàn)在也可以),例如: <APPLET CODE = "HelloWorld" archive ="HelloWorld.jar" JAVA_CODEBASE = "." WIDTH = "320" HEIGHT = "240" NAME = "HelloWorld"></APPLET> 這里的CODE表示類(lèi)名(類(lèi)名后可以加上.class),archvie表示類(lèi)所在的jar包,如果你有多個(gè)jar包,可以全加在archive里面,用,號(hào)分開(kāi)(archive="a,jar,b.jar,c.jar",當(dāng)然這些jar要簽名的還得簽名)。 如果用這種標(biāo)簽,在IE下,如果沒(méi)選中用本地jre運(yùn)行applet的話(huà),是運(yùn)行不了的,沒(méi)安裝插件的firefox也是不能運(yùn)行的。
面對(duì)這種情況,升級(jí)版的標(biāo)簽出現(xiàn)了,java提供了一個(gè)工具名字叫HTMLconverter,通過(guò)它,能將html中的applet標(biāo)簽轉(zhuǎn)換成標(biāo)準(zhǔn)的標(biāo)簽,如下
其中Object部分是針對(duì)IE的,embed是針對(duì)firefox的.classid與codebase都是表示相應(yīng)的plugin的下載地址,如果codebase的版本高于classid將下載codebase版本的plugin。這樣不管本地有沒(méi)有安裝java,applet都能正常運(yùn)行了。
現(xiàn)在,在applet里面己經(jīng)能調(diào)用本地的資源了,那么如何驅(qū)動(dòng)掃描儀呢?
二.applet調(diào)用TWain驅(qū)動(dòng)本地掃描儀 TWain是一個(gè)標(biāo)準(zhǔn),用于獲取掃描儀等設(shè)備的信息,它有很多實(shí)現(xiàn)(基本都是收費(fèi)的),這里選擇的是一個(gè)開(kāi)源twain產(chǎn)品,mmsc twain(官網(wǎng) http://www./例子很豐富)。 只要本地安裝有掃描儀驅(qū)動(dòng),twain就能找到并運(yùn)行且獲取到掃描的數(shù)據(jù)。 它里面有個(gè)Scanner類(lèi),Scanner scanner = Scanner.getDevice()能獲取到相應(yīng)的設(shè)備。然后為scanner添加一個(gè)監(jiān)聽(tīng)器,ScannerListener,它里面有個(gè)方法public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata){},第二個(gè)參數(shù)即為掃描得到的數(shù)據(jù),而且這個(gè)方法是在掃描述的狀態(tài)發(fā)生變變就會(huì)解發(fā)。具體可以看一些mmsc里面的例子。
三.applet與服務(wù)器通信 得到了掃描的數(shù)據(jù),得把它上傳到服務(wù)器。我這里用的是HttpClient(需要的jar包c(diǎn)ommons-codec-1.4.jar,commons-httpclient-3.0.jar,commons-io-1.4.jar,commons-logging-1.0.2.jar)。在使用時(shí)最好對(duì)這幾個(gè)jar包都簽名(我沒(méi)有測(cè)試這種方式,我是將這幾個(gè)jar全給解壓了,最后連同我的類(lèi)一起打成了一個(gè)jar,最后簽名),上傳代碼位于update方法內(nèi)即可。 因?yàn)閽呙鑳x有多種狀態(tài),所以要進(jìn)行判斷,那次才是拿到了掃描數(shù)據(jù)。
完工 中間碰到最多的問(wèn)題就是,applet簽名及applet布署,開(kāi)始老以為applet根平時(shí)的類(lèi)布署是一樣的,后來(lái)發(fā)現(xiàn)就應(yīng)該把它當(dāng)成一個(gè)獨(dú)立的應(yīng)用來(lái)對(duì)等。
中間可能有錯(cuò),有問(wèn)題請(qǐng)?jiān)诩抑赋?,謝謝
效果圖(點(diǎn)擊中間的acquire就能掃描了):
|
|
來(lái)自: ctbtcol > 《待分類(lèi)1》