前端时间公司有需求要访问客户端串口读取电子称的数据,通过网上资料,决定使用applet通过电子签名的形式实现。

1.先写applet:这里我是使用RXRTcomm.jar

LocalFileApplet.java,JobThread.java

public class LocalFileApplet extends Applet {
private static final String LIB_PATH_SUFFIX = "system32";
private static final String DLL_FILE = "rxtxSerial.dll";
private String msg = "";
private boolean ready;
private boolean right=true;
private String commName;
CommPortIdentifier portId ;
SerialPort serialPort;
InputStream is;
public boolean isRight() {
return right;
}
public void setRight(boolean right) {
this.right = right;
}
public CommPortIdentifier getPortId() {
return portId;
}
public void setPortId(CommPortIdentifier portId) {
this.portId = portId;
}
public SerialPort getSerialPort() {
return serialPort;
}
public void setSerialPort(SerialPort serialPort) {
this.serialPort = serialPort;
}
public InputStream getIs() {
return is;
}
public void setIs(InputStream is) {
this.is = is;
}
public boolean isReady() {
return ready;
}
public void setReady(boolean ready) {
this.ready = ready;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCommName() {
return commName;
}
public void setCommName(String commName) {
this.commName = commName;
}
static{
//System.setSecurityManager(null);
System.setSecurityManager(null);
String drivername = "gnu.io.RXTXCommDriver";
try {
CommDriver driver = (CommDriver) Class.forName(drivername).newInstance();
driver.initialize();
} catch (InstantiationException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ClassNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
} public void paint(Graphics g ){
//showPorts(g);
}
public void initPort() throws NoSuchPortException {
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(commName);
if (!portId.isCurrentlyOwned()) {
SerialPort port;
try {
port = (SerialPort) portId
.open("SerialMain", );
port.setSerialPortParams(, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
is = port.getInputStream();
System.out.println("得到inputstream");
} catch (PortInUseException e) {
// TODO Auto-generated catch block
cleanPort();
e.printStackTrace();
} catch (UnsupportedCommOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} public void cleanPort(){
try {
is.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
serialPort.close();
}
public void init(){
//listPorts();
System.out.println("");
x();
this.setBounds(,,,);
this.repaint();
} public void start(){
try {
initPort();
} catch (NoSuchPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.setRight(false);
}
JobThread job = new JobThread(this);
Thread t = new Thread(job);
t.start();
}
public void stop(){
cleanPort();
}
private void showPorts(Graphics g ){
g.drawString("扫描本地计算机上的串口:!",,);
String[] ports = listPorts().split(",");
if(ports.length==){
g.drawString("本地计算机上没有发现串口:!",,);
}else{
int y = ;
g.drawString("本地计算机上发现"+ports.length+"个串口:!",,);
for (int i = ; i < ports.length; i++) {
String port = (String) ports[i];
g.drawString(port,,y);
y += ;
}
}
}
public String listPorts(){
String commName="";
Enumeration en = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId;
while (en.hasMoreElements()) {
portId = (CommPortIdentifier) en.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
if(commName==""){
commName+=portId.getName();
}else{
commName+=","+portId.getName();
}
}
}
return commName;
}
private void downDll(){ try {
// 获取加载库时搜索的路径列表
String dirs = System.getProperty("java.library.path");
String[] libs = dirs.split(";");
String libPath = "";
for (String lib : libs) {
if (lib.toLowerCase().endsWith(LIB_PATH_SUFFIX)) {
libPath = lib;
break;
}
}
File dll = new File(libPath, DLL_FILE);
if (!dll.exists()) {
URL url = new URL(super.getCodeBase() + DLL_FILE);
InputStream is = url.openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(dll);
byte[] buf = new byte[]; // 读取缓存
int len = ;
while ((len = is.read(buf)) != -) {
fos.write(buf, , len);
}
fos.flush();
fos.close();
is.close();
System.out.println("创建文件完成[" + dll + "].");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
public void x() {
try {
// 获取加载库时搜索的路径列表
String dirs = System.getProperty("java.library.path");
String[] libs = dirs.split(";");
String libPath = "";
for (String lib : libs) {
if (lib.toLowerCase().endsWith(LIB_PATH_SUFFIX)) {
libPath = lib;
break;
}
}
File dll = new File(libPath, DLL_FILE);
if (!dll.exists()) {
URL url = new URL(super.getCodeBase() + DLL_FILE);
InputStream is = url.openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(dll);
byte[] buf = new byte[]; // 读取缓存
int len = ;
while ((len = is.read(buf)) != -) {
fos.write(buf, , len);
}
fos.flush();
fos.close();
is.close();
System.out.println("创建文件完成[" + dll + "].");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally{
System.loadLibrary("rxtxSerial");
}
}
}
public class JobThread implements Runnable{
private LocalFileApplet applet;
public JobThread(LocalFileApplet applet) {
this.applet = applet;
}
public void run() {
InputStream is = applet.getIs();
try {
while(true){
String msg="";
byte[] str = new byte[];
System.out.println("准备接收数据");
is.read(str);
System.out.println("收到数据" + new String(str)); String txt[] = new String[];
String value = new String(str);
if (value != null) {
String vxxx[] = value.split(",");
if (vxxx.length > ) {
String[] a = value.split(",")[].split(" "); int i = ;
for (String v : a) {
if (v.length() > ) {
txt[i] = v;
i++;
}
}
if (txt[].length() == ) {
msg = txt[].substring(,
txt[].length() - )
+ "."
+ txt[].substring(txt[].length() - ,
txt[].length());
} else {
msg = txt[].substring(,
txt[].length() - )
+ "."
+ txt[].substring(txt[].length() - ,
txt[].length());
}
}
if(msg==""||applet.getMsg().equals(msg)){
applet.setMsg(msg);
applet.setReady(false);
System.out.println(msg);
applet.repaint();
}else{
applet.setMsg(msg);
applet.setReady(true);
System.out.println(msg);
applet.repaint();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

然后用eclipse打包,到这里都很顺利,然后签名的时候遇到了很多问题。

正确的方法是:

服务器端:

1.为刚才创建的包文件(LocalFileApplet.jar)创建keystore和keys。

keytool -genkey -keystore LocalFileApplet.keystore –alias LocalFileApplet -keyalg DSA

2.用LocalFileApplet.keystore 对签名LocalFileApplet.jar

jarsigner -keystore LocalFileApplet.keystore LocalFileApplet.jar LocalFileApplet

3.生产LocalFileApplet.cer(这个是客户端需要的秘钥)

keytool -export -keystore LocalFileApplet.keystore -alias LocalFileApplet-file LocalFileApplet.cer

客户端:

1.找到jre(1.7以上版本,1.6没有例外站点)把LocalFileApplet.cer导入到cacerts

路径:***\jre1.8.0_45\lib\security

keytool -import -alias LocalFileApplet -file LocalFileApplet.cer -keystore cacerts

2.修改策略文件java.plicy

添加keystore "file:/C:/Program Files (x86)/Java/jre1.8.0_45/lib/security/cacerts", "JKS";

在grant下面增加

permission java.lang.RuntimePermission "loadLibrary.rxtxSerial", "read";
permission java.util.PropertyPermission "java.library.path", "read";
permission java.util.PropertyPermission "java.library.path", "write";
permission java.io.FilePermission "C:/Windows/system32/rxtxSerial.dll", "read";
permission java.io.FilePermission "C:/Windows/system32/rxtxSerial.dll", "write";
permission java.io.FilePermission "C:/Program Files (x86)/Java/jre1.8.0_45/lib/ext/amd64/rxtxSerial.dll", "read";
permission java.io.FilePermission "C:/Program Files (x86)/Java/jre1.8.0_45/lib/ext/amd64/rxtxSerial.dll", "write";
permission java.util.PropertyPermission "gnu.io.rxtx.SerialPorts","read";
permission java.lang.RuntimePermission "setSecurityManager";

3.把rxtxSerial.dll放到C:\Windows\System32下

4.配置本地java,打开:控制面板\程序\java 安全 例外站点
把服务器网站输入例如:http://localhost:8080/demo/

注:以/结尾,否则无效

5.高级:JNLP 文件/MIME 关联 选为始终允许,
安全执行环境勾选 允许用户为签名的内容授予权限 允许用户解释JNLP安全请求
混合代码 (沙箱代码与可信代码) 安全验证 选 启动-隐藏警告并在保护下运行
对以下项执行已签名代码证书撤销检查 选 不检查
对以下项执行 TLS 证书撤销检查 选 不检查

然后在html中调用applet

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
</head>
<script type="text/javascript">
var t;
function startComm(){
document.applets["myapp"].start();
process();
}
function process(){
var ready = document.applets["myapp"].isready();
if(ready){
// document.applets["myapp"].setReady(false);
var msg = document.applets["myapp"].getMsg();
document.getElementById("t").value=msg;
}
t=setTimeout('process()',);
}
function showComm(){
var commName = document.applets["myapp"].listPorts();
var html=""; //<option value ="">Volvo</option>
var names=commName.split(",");
for(var i=;i<names.length;i++){
html+=" <option value ='"+names[i]+"'>"+names[i]+"</option>"
}
document.getElementById("commNum").innerHTML=html; document.applets["myapp"].setCommName(names[]);
}
function changeComm(){
var commName =document.getElementById("commNum").value();
document.applets["myapp"].setCommName(commName);
}
function closeComm(){
clearTimeout(t);
}
</script>
<body onload="showComm()">
<!--"CONVERTED_APPLET"-->
<!-- HTML CONVERTER -->
<APPLET CODEBASE="." CODE="com.LocalFileApplet.class" ARCHIVE="LocalFileApplet.jar,RXTXcomm.jar" WIDTH="" HEIGHT="" name="myapp"> </APPLET>
<!--"END_CONVERTED_APPLET"-->
<input type="button" value="确定" id="x" onclick="startComm()">
<input type="button" value="关闭" id="s" onclick="closeComm()">
<input id="t" type="text" value="" >
<select id="commNum" onkeyup="showComm()" onchange="changeComm()">
</select>
</body>
</html>

很奇怪,这样写不能读,最后我无奈了,就不打包,直接引用com.LocalFileApplet.class,可以了

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
</head>
<script type="text/javascript">
var t;
function startComm(){
document.applets["myapp"].start();
process();
}
function process(){
var ready = document.applets["myapp"].isready();
if(ready){
// document.applets["myapp"].setReady(false);
var msg = document.applets["myapp"].getMsg();
document.getElementById("t").value=msg;
}
t=setTimeout('process()',);
}
function showComm(){
var commName = document.applets["myapp"].listPorts();
var html=""; //<option value ="">Volvo</option>
var names=commName.split(",");
for(var i=;i<names.length;i++){
html+=" <option value ='"+names[i]+"'>"+names[i]+"</option>"
}
document.getElementById("commNum").innerHTML=html; document.applets["myapp"].setCommName(names[]);
}
function changeComm(){
var commName =document.getElementById("commNum").value();
document.applets["myapp"].setCommName(commName);
}
function closeComm(){
clearTimeout(t);
}
</script>
<body onload="showComm()">
<!--"CONVERTED_APPLET"-->
<!-- HTML CONVERTER -->
<APPLET CODEBASE="." CODE="com.LocalFileApplet.class" ARCHIVE="RXTXcomm.jar" WIDTH="" HEIGHT="" name="myapp">
</APPLET>
<!--"END_CONVERTED_APPLET"-->
<input type="button" value="确定" id="x" onclick="startComm()">
<input type="button" value="关闭" id="s" onclick="closeComm()">
<input id="t" type="text" value="" >
<select id="commNum" onkeyup="showComm()" onchange="changeComm()">
</select>
</body>
</html>

难道是LocalFileApplet.jar签名出问题了?

但是RXTXcomm.jar同样签名的,为什么RXTXcomm.jar签名有效,LocalFileApplet.jar签名无效

使用java applet通过签名访问客户端串口的更多相关文章

  1. Java Applet读写client串口——终极篇

    測试环境: SDK:Oracle JRockit for Java version 6, Java Communication for Windows 2.0 OS:WINDOWS7 外设:串口条形码 ...

  2. 使用Java Applet在客户端解压缩,以及使用证书的意义

    以前解压缩是用Java Applet在客户端解压缩,而且用户不知道这回事.但是现在Chrome不支持NP API了,所以不得不把Java去掉,然后在服务器里解压缩.风险在于,解压缩以后,传输到客户端的 ...

  3. Java—Applet

    1  Applet的定义 Applet是Java语言编写的,无法独立运行,但可以嵌入到网页中执行.它扩展了传统的编程结构和方法,可以通过互联网发布到任何具有Java编译环境浏览器的个体计算机上. 如下 ...

  4. Java Applet小应用

    开发和部署方式     嵌入到HTML网页中,用<Applet></Applet>标签识别.java环境用浏览器的,在第一次打开时下载,可开发成以后打开,默认不必再次下载.也可 ...

  5. 解决HMC在IE浏览器无法登录的问题(Java Applet的使用问题)

    管理IBM的小型机必须要用到HMC(Hardware Management Console),有时候在使用测试环境使用的时候我们会把HMC装到自己电脑上的虚拟机里面,然后管理小型机,但是在虚拟机里面使 ...

  6. Java实现UDP之Echo客户端和服务端

    Java实现UDP之Echo客户端和服务端 代码内容 采用UDP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...

  7. Java实现TCP之Echo客户端和服务端

    Java实现TCP之Echo客户端和服务端 代码内容 采用TCP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...

  8. Java Applet与Java Application的特点

    java application是应用程序,用于桌面开发,java applet是小应用程序,一般嵌入到网页里运行.applet一般用于B/S页面上作为插件式的开发,而application主要是桌面 ...

  9. API访问客户端

    API访问客户端(WebApiClient适用于MVC/WebForms/WinForm) 这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前 ...

随机推荐

  1. django中如何建立抽象型数据库作为父模块可继承其功能

    先建立抽象数据库 from django.db import models class BaseModel(models.Model): """为模型类补充字段" ...

  2. 【bzoj4872】[Shoi2017]分手是祝愿 期望dp

    Description Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态 ...

  3. JDK1.8源码阅读系列之二:LinkedList

    本篇随笔主要描述的是我阅读 LinkedList 源码期间的对于 LinkedList 的一些实现上的个人理解,有不对的地方,请指出- 先来看一下 LinkedList 的继承图: 由于 Abstra ...

  4. samba服务器架设

    #samba服务器架设方便线上linux服务器和windows服务器之间共享 1.关闭防火墙service iptables stop 2.关闭SELinuxsetenforce 0 3.安装samb ...

  5. linux操作之文本编辑器

    1.文本编辑器的作用 编辑和修改系统中的那些以文本形式存在的文件(特别是各种配置文件),也可以用于 编写程序代码 2.linux下的常见编辑器 nano.Emacs.gedit.vim等 3.vim三 ...

  6. 线段树(压位)luogu P1558色板游戏

    题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, ... L. 现在色板上只 ...

  7. .net core UseHttpsRedirection() 正式环境无效

    莫名其妙遇到这样的问题.这样的配置在本地可以,正式环境就不行了. ··· public void Configure(IApplicationBuilder app, Microsoft.AspNet ...

  8. 181114socke编程

    一.Socket Families 地址簇 socket.AF_UNIX socket.AF_INET socket.AF_INET6 二.Socker Types socket.SOCK_STREA ...

  9. VUE学习(一)

    1.搭建vue环境 2.了解 v-on  事件监听,常常跟事件(click,mousemove,change等鼠标或者手势事件)在一起,eg:v-on:click,语法糖——:(冒号) 需要在meth ...

  10. 【语义分割】PSPNet中PSP模块的pytorch实现

    github地址:https://github.com/Lextal/pspnet-pytorch/blob/master/pspnet.py PSP模块示意图如下 代码如下 class PSPMod ...