一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Java調(diào)用掃描儀2

 ctbtcol 2015-01-07

最近碰到的問(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就存在里面.

如下圖:



 這樣一個(gè)keystore就建立好了,在當(dāng)前目錄下就多出了一個(gè)zengge.keystore的文件


 

有了keystore之后jarsigner就可以利用存放在keystore中的key來(lái)為jar簽名



 這里有兩個(gè)類(lèi),先打包

 


包里面的META-INFO里面只有一個(gè)文件,且內(nèi)容為上圖

 

接下來(lái)為jar包簽名:

jarsigner -keystore zengge.keystore HelloWorld.jar zengge
zengge.keystore是keystore的路徑/名字,這里是相對(duì)路徑
HelloWorld.jar是要簽名的jar包
zengge是存放在keystore中的密鑰的別名


密碼為建立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)簽,如下

Html代碼  收藏代碼
  1. <object  
  2.     classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"  
  3.     codebase = "http://java./update/1.6.0/jinstall-6u14-windows-i586.cab#Version=6,0,0,8"  
  4.     WIDTH = "320" HEIGHT = "240" NAME = "HelloWorld" >  
  5.     <PARAM NAME = CODE VALUE = "HelloWorld" >  
  6.     <PARAM NAME = CODEBASE VALUE = "." >  
  7.     <PARAM NAME = ARCHIVE VALUE = "applet_test.jar" >  
  8.     <PARAM NAMENAME = NAME VALUE = "HelloWorld" >  
  9.     <param name = "type" value = "application/x-java-applet;version=1.6">  
  10.     <param name = "scriptable" value = "false">  
  11.       
  12.     //上面是針對(duì)IE  
  13.     //下面的embed是針對(duì)firefox  
  14.       
  15.     <comment>  
  16.     <embed  
  17.             type = "application/x-java-applet;version=1.6" \  
  18.             CODE = "HelloWorld" \  
  19.             JAVA_CODEBASE = "." \  
  20.             ARCHIVE = "applet_test.jar" \  
  21.             NAME = "HelloWorld" \  
  22.             WIDTH = "320" \  
  23.             HEIGHT = "240"  
  24.         scriptable = false  
  25.         pluginspage = "http://java./products/plugin/index.html#download">  
  26.         <noembed>   
  27.             </noembed>  
  28.     </embed>  
  29.     </comment>  
  30. </object>  
  31. <!--  
  32. <APPLET CODE = "HelloWorld" JAVA_CODEBASE = "." WIDTH = "320" HEIGHT = "240" NAME = "HelloWorld">  
  33. </APPLET>  
  34. -->  
  35. <!--"END_CONVERTED_APPLET"-->  
 

其中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ù)。

Java代碼  收藏代碼
  1. public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata){  
  2.   
  3.     if(type.equals(ScannerIOMetadata.ACQUIRED)){  
  4.       BufferedImage image=metadata.getImage();  
  5.       System.out.println("Have an image now!");  
  6.       HttpClient httpClient = new HttpClient();  
  7.       MultipartPostMethod mpm = new MultipartPostMethod("http://localhost:8086/ReiyenDMS/TestUploadServlet");  
  8. //      MultipartPostMethod mpm = new MultipartPostMethod("http://localhost:8086/applet_study/servlet/AppletServlet");  
  9.       File file = new File("c:/upload/abc"+index+".jpg");  
  10.       try{  
  11.         ImageIO.write(image, "jpg", file);  
  12.         index++;  
  13.        mpm.addParameter("aFile""haha.pdf", file);  
  14.         httpClient.executeMethod(mpm);  
  15.   
  16.       }catch(Exception e){  
  17.         e.printStackTrace();  
  18.       }  
  19.     }else if(type.equals(ScannerIOMetadata.NEGOTIATE)){  
  20.       ScannerDevice device=metadata.getDevice();  
  21. /* 
  22.       try{ 
  23.         device.setResolution(100); 
  24. //        device.setRegionOfInterest(0.0,0.0,40.0,50.0);       // top-left corner 40x50 mm 
  25.         device.setRegionOfInterest(0,0,400,500);               // top-left corner 400x500 pixels 
  26.         device.setShowUserInterface(false); 
  27.         device.setShowProgressBar(false); 
  28.       }catch(Exception e){ 
  29.         e.printStackTrace(); 
  30.       } 
  31. */  
  32.     }else if(type.equals(ScannerIOMetadata.STATECHANGE)){  
  33.       System.err.println(metadata.getStateStr());  
  34.     }else if(type.equals(ScannerIOMetadata.EXCEPTION)){  
  35.       metadata.getException().printStackTrace();  
  36.     }  
  37.   }  
 

 

完工

中間碰到最多的問(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就能掃描了):

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    欧美一级片日韩一级片| 亚洲伦理中文字幕在线观看| 日韩视频在线观看成人| 中文字幕高清不卡一区| 亚洲av专区在线观看| 久久一区内射污污内射亚洲| 噜噜中文字幕一区二区| 久久亚洲成熟女人毛片| 在线精品首页中文字幕亚洲| 情一色一区二区三区四| 亚洲综合色婷婷七月丁香| 国产乱久久亚洲国产精品| 中文字幕熟女人妻视频| 91爽人人爽人人插人人爽| 亚洲一区二区欧美在线| 国产高清精品福利私拍| 国产精品制服丝袜美腿丝袜| 黄色片一区二区在线观看| 国产欧美日韩精品一区二区| 亚洲日本久久国产精品久久| 日韩中文字幕有码午夜美女| 一区二区日韩欧美精品| 无套内射美女视频免费在线观看| 日韩成人h视频在线观看| 国产精品十八禁亚洲黄污免费观看| 亚洲精品日韩欧美精品| 91欧美一区二区三区成人| 国产日产欧美精品大秀| 亚洲永久一区二区三区在线| 性欧美唯美尤物另类视频| 国产免费黄片一区二区| 亚洲男人的天堂久久a| 日韩免费成人福利在线| 黄片三级免费在线观看| 精品亚洲一区二区三区w竹菊| 日韩欧美三级视频在线| 亚洲av成人一区二区三区在线| 国产精品久久精品毛片| 亚洲专区中文字幕在线| 欧美日韩精品综合在线| 欧美日韩国产免费看黄片|