最近碰到的问题,客户端调用本地的扫描仪,将扫描的文件上传。

使用到的技术:applet,twain,HttpClient

当然也碰到很多问题,因为在这周之前我都不知道什么是applet

一.Applet操作本地资源

基于安全方面的原因,applet是不允许操作本地资源的。但是java提供了相应的为jar包签名的机制来提升applet的权限。相信很多人都碰到过这种对话框:

48835103_1.gif

让用户来决定是否给applet提升权限,如果用户信任这个资源,applet将能操作本地资源。

1.为applet依赖的jar包签名

java提供了两个工具;

keytool用于生成存放key的库

jarsigner用于为jar进行签名

首先建立一个keystore(这是在当前路径上操作):

keytool -genkey -alias zengge -keystore zengge.keystore

keytool -genkey表示建库

-alias zengge是为要建立的key取一个别名

-keystore zengge.keystore是建立一个名字叫zengge.keystore的key库,key就存在里面.

如下图:

48835103_2.gif

这样一个keystore就建立好了,在当前目录下就多出了一个zengge.keystore的文件

48835103_3.gif

有了keystore之后jarsigner就可以利用存放在keystore中的key来为jar签名

48835103_4.gif

这里有两个类,先打包

48835103_5.gif

包里面的META-INFO里面只有一个文件,且内容为上图

接下来为jar包签名:

jarsigner -keystore zengge.keystore HelloWorld.jar zengge

zengge.keystore是keystore的路径/名字,这里是相对路径

HelloWorld.jar是要签名的jar包

zengge是存放在keystore中的密钥的别名

48835103_6.gif

密码为建立keystore时的密码

再来看一下签过名的jar里面的情况有什么变化:

48835103_7.gif

可以看到META-INFO里面现在是三个文件,.DSAG与.SF我想肯定是用来加解密用的,大家注意现在的MANIFEST.MF,

可以看出为每个类添加了一个SHA签名,用它来保证,这个jar里面的内容不会被其它人修改,用户可以相信这个jar。

2.将applet嵌入html

applet是通过浏览器来运行了,可能你会问,java的东西浏览器怎么能运行呢,难道客户端也要安装java?

实际上applet是通过嵌在浏览器中的jvm在运行,但是这个jvm是从那里来的呢?

对于IE,大家可以看一下,下图中的java如果选中,就表示会调用本地的jre来运行applet。

48835103_8.gif

但是绝大部分情况下,客户端是不会安装java的啊,还有firefox下面没有类似的这种选项。那么要如何来解决这种问题呢?

早期的applet都是用applet标签来嵌入html的(当然现在也可以),例如:

这里的CODE表示类名(类名后可以加上.class),archvie表示类所在的jar包,如果你有多个jar包,可以全加在archive里面,用,号分开(archive="a,jar,b.jar,c.jar",当然这些jar要签名的还得签名)。

如果用这种标签,在IE下,如果没选中用本地jre运行applet的话,是运行不了的,没安装插件的firefox也是不能运行的。

面对这种情况,升级版的标签出现了,java提供了一个工具名字叫HTMLconverter,通过它,能将html中的applet标签转换成标准的标签,如下

Html代码  48835103_9.png

classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"

codebase = "http://java.sun.com/update/1.6.0/jinstall-6u14-windows-i586.cab#Version=6,0,0,8"

WIDTH = "320" HEIGHT = "240" NAME = "HelloWorld" >

//上面是针对IE

//下面的embed是针对firefox

type = "application/x-java-applet;version=1.6" \

CODE = "HelloWorld" \

JAVA_CODEBASE = "." \

ARCHIVE = "applet_test.jar" \

NAME = "HelloWorld" \

WIDTH = "320" \

HEIGHT = "240"

scriptable = false

pluginspage = "http://java.sun.com/products/plugin/index.html#download">

其中Object部分是针对IE的,embed是针对firefox的.classid与codebase都是表示相应的plugin的下载地址,如果codebase的版本高于classid将下载codebase版本的plugin。这样不管本地有没有安装java,applet都能正常运行了。

现在,在applet里面己经能调用本地的资源了,那么如何驱动扫描仪呢?

二.applet调用TWain驱动本地扫描仪

TWain是一个标准,用于获取扫描仪等设备的信息,它有很多实现(基本都是收费的),这里选择的是一个开源twain产品,mmsc twain(官网 http://www.mms-computing.co.uk/例子很丰富)。

只要本地安装有扫描仪驱动,twain就能找到并运行且获取到扫描的数据。

它里面有个Scanner类,Scanner scanner = Scanner.getDevice()能获取到相应的设备。然后为scanner添加一个监听器,ScannerListener,它里面有个方法public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata){},第二个参数即为扫描得到的数据,而且这个方法是在扫描述的状态发生变变就会解发。具体可以看一些mmsc里面的例子。

三.applet与服务器通信

得到了扫描的数据,得把它上传到服务器。我这里用的是HttpClient(需要的jar包commons-codec-1.4.jar,commons-httpclient-3.0.jar,commons-io-1.4.jar,commons-logging-1.0.2.jar)。在使用时最好对这几个jar包都签名(我没有测试这种方式,我是将这几个jar全给解压了,最后连同我的类一起打成了一个jar,最后签名),上传代码位于update方法内即可。

因为扫描仪有多种状态,所以要进行判断,那次才是拿到了扫描数据。

Java代码  48835103_9.png

public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata){

if(type.equals(ScannerIOMetadata.ACQUIRED)){

BufferedImage image=metadata.getImage();

System.out.println("Have an image now!");

HttpClient httpClient = new HttpClient();

MultipartPostMethod mpm = new MultipartPostMethod("http://localhost:8086/ReiyenDMS/TestUploadServlet");

//      MultipartPostMethod mpm = new MultipartPostMethod("http://localhost:8086/applet_study/servlet/AppletServlet");

File file = new File("c:/upload/abc"+index+".jpg");

try{

ImageIO.write(image, "jpg", file);

index++;

mpm.addParameter("aFile", "haha.pdf", file);

httpClient.executeMethod(mpm);

}catch(Exception e){

e.printStackTrace();

}

}else if(type.equals(ScannerIOMetadata.NEGOTIATE)){

ScannerDevice device=metadata.getDevice();

/*

try{

device.setResolution(100);

//        device.setRegionOfInterest(0.0,0.0,40.0,50.0);       // top-left corner 40x50 mm

device.setRegionOfInterest(0,0,400,500);               // top-left corner 400x500 pixels

device.setShowUserInterface(false);

device.setShowProgressBar(false);

}catch(Exception e){

e.printStackTrace();

}

*/

}else if(type.equals(ScannerIOMetadata.STATECHANGE)){

System.err.println(metadata.getStateStr());

}else if(type.equals(ScannerIOMetadata.EXCEPTION)){

metadata.getException().printStackTrace();

}

}

完工

中间碰到最多的问题就是,applet签名及applet布署,开始老以为applet根平时的类布署是一样的,后来发现就应该把它当成一个独立的应用来对等。

中间可能有错,有问题请在家指出,谢谢

效果图(点击中间的acquire就能扫描了):

48835103_10.gif

java 扫描仪_Java调用扫描仪2相关推荐

  1. java 存储过程_Java 调用存储过程

    本文阐述了怎么使用DBMS存储过程.我阐述了使用存储过程的基本的和高级特性,比如返回ResultSet.本文假设你对DBMS和JDBC已经非常熟悉,也假设你能够毫无障碍地阅读其它语言写成的代码(即不是 ...

  2. java文件快速扫描仪_Java使用扫描仪进入按键

    这可以使用java.util.Scanner进行,并且会执行多次"输入"击键: Scanner scanner = new Scanner(System.in); String r ...

  3. js 引用 java常量_java调用JS 与JS 调java

    这个 刚开始 我也不会,把我整的是个蛋疼的啊, 最后发现其实挺简单的,我现在给大家说的是我自己掌握的一种, 1. 先是要给项目配置一些权限 (1).访问网络权限 (2).访问SD卡权限 2.给webv ...

  4. linux shell java 参数_java调用linux中的shell脚本传递参数并返回执行结果

    [刚接触 linux下的开发,最近遇到java调用shell脚本的问题,找到一个比较适合菜鸟级的方法,转述如下: 在需要运行的SHELL脚本第一行添加 #!/bin/sh然后在终端运行  chmod ...

  5. JAVA飞信_java调用飞信接口发短信 - 贪吃蛇学院-专业IT技术平台

    java调用飞信接口发短信,看到挺好的,有利于大家做毕业设计加亮点,就发给大家了(新人发帖,不会发多个文件名,测试类就放这了) 需要这3个jar包: commons-codec-1.4.jar com ...

  6. java 父类_java 调用父类的父类

    展开全部 在father中在定义一个62616964757a686964616fe59b9ee7ad9431333335313738调用父类的方法,在子类逐级调用...class GrandPa { ...

  7. java 打印机_java调用打印机方式二

    一.主类: package org.jeecg.print; import java.awt.BasicStroke; import java.awt.Color; import java.awt.F ...

  8. 飞信java接口_java调用飞信接口免费短信发送到对方手机

    飞信发送信息限(移动用户) 1.用飞信加为好友才可以跟对方发飞信(达到此条件发飞信不收取费用) 2.FetionConfig配置文件里的 WeekendGreetings=是发送另一个配置文件名 如 ...

  9. java 打印机_java调用打印机接口

    全部代码: import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt ...

  10. java项目中外接扫描仪无法使用_java – 扫描仪行不可用错误

    我用两种不同的方法从两个不同的扫描仪对象调用Scanner.nextLine()方法.有时当我从第二种方法调用Scanner.nextLine()时,它会给我一个"行不可用"错误. ...

最新文章

  1. TestNG学习随笔
  2. LeetCode Excel Sheet Column Title(表格列数数字到英文转换)
  3. 黑龙江2020计算机一级考试时间,黑龙江2020年计算机等级考试报名时间汇总
  4. 有关架构图你需要了解的基础知识
  5. 如何用python写脚本_【按键教程】用python写脚本 另附垫材24与变奏22的实现
  6. canvas在舞台上点击后图片旋转_View绘制系列(10)Canvas基础变换
  7. uvalive5990(坑点蛮多的一道题。。)
  8. MySQL 数据库热备的操作
  9. jquery-幻灯片的移动分析
  10. android studio安装部署及sdk下载_「从零开始Python爬虫」1.7.3 APPium的安装
  11. Scrapy 爬取京东商城华为全系列手机评论
  12. bzoj 3208 花神的秒题计划I
  13. ie浏览器框架不显示_Python 爬虫(四):Selenium 框架介绍与使用
  14. ArcGIS实验教程:ArcGIS 10.2手把手图文安装教程(经典版)
  15. 对于三极管饱和状态的理解
  16. matlab代码运行教程(如何运行下载的代码)
  17. 纯CSS3模拟iPhone X背景切换动画
  18. 程序员应该学习如何学习
  19. 大数据学习笔记1.3 Linux目录操作
  20. 项目奖金一般是多少_MPAcc职业发展|看看国内券商、投行、四大一年能挣多少?...

热门文章

  1. BZOJ-2037 Sue的小球 DP+费用提前
  2. java+selnium爬取凡人修仙传
  3. ObjectARX标注公差简单实例
  4. bingo update1
  5. beyond compare密钥
  6. 计算机英语(第四版)刘艺英语单词
  7. 计算机十六进制是什么意思,2进制和16进制是什么意思?它们之间如何换算?
  8. JavaScript数组方法(最全)
  9. 如何设置无需fn直接按F1~F10(HP Pavilion Notebook )
  10. Docker进阶 dockerfile指令构建docker镜像