使用java applet通过签名访问客户端串口
前端时间公司有需求要访问客户端串口读取电子称的数据,通过网上资料,决定使用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通过签名访问客户端串口的更多相关文章
- Java Applet读写client串口——终极篇
測试环境: SDK:Oracle JRockit for Java version 6, Java Communication for Windows 2.0 OS:WINDOWS7 外设:串口条形码 ...
- 使用Java Applet在客户端解压缩,以及使用证书的意义
以前解压缩是用Java Applet在客户端解压缩,而且用户不知道这回事.但是现在Chrome不支持NP API了,所以不得不把Java去掉,然后在服务器里解压缩.风险在于,解压缩以后,传输到客户端的 ...
- Java—Applet
1 Applet的定义 Applet是Java语言编写的,无法独立运行,但可以嵌入到网页中执行.它扩展了传统的编程结构和方法,可以通过互联网发布到任何具有Java编译环境浏览器的个体计算机上. 如下 ...
- Java Applet小应用
开发和部署方式 嵌入到HTML网页中,用<Applet></Applet>标签识别.java环境用浏览器的,在第一次打开时下载,可开发成以后打开,默认不必再次下载.也可 ...
- 解决HMC在IE浏览器无法登录的问题(Java Applet的使用问题)
管理IBM的小型机必须要用到HMC(Hardware Management Console),有时候在使用测试环境使用的时候我们会把HMC装到自己电脑上的虚拟机里面,然后管理小型机,但是在虚拟机里面使 ...
- Java实现UDP之Echo客户端和服务端
Java实现UDP之Echo客户端和服务端 代码内容 采用UDP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...
- Java实现TCP之Echo客户端和服务端
Java实现TCP之Echo客户端和服务端 代码内容 采用TCP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...
- Java Applet与Java Application的特点
java application是应用程序,用于桌面开发,java applet是小应用程序,一般嵌入到网页里运行.applet一般用于B/S页面上作为插件式的开发,而application主要是桌面 ...
- API访问客户端
API访问客户端(WebApiClient适用于MVC/WebForms/WinForm) 这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前 ...
随机推荐
- HDU6330-2018ACM暑假多校联合训练Problem L. Visual Cube
就是画个图啦 分三个平面去画orz #include <iostream> #include <cmath> #include <cstring> #include ...
- linux操作之文本编辑器
1.文本编辑器的作用 编辑和修改系统中的那些以文本形式存在的文件(特别是各种配置文件),也可以用于 编写程序代码 2.linux下的常见编辑器 nano.Emacs.gedit.vim等 3.vim三 ...
- resultType和resultMap的区别
1.resultType和resultMap的区别 1>resultType 返回的结果类型 2>resultMap 描述如何将结果集映射到Java对象 2.resultMap节点 1&g ...
- mac下对NTFS格式的磁盘进行读写操作
mac对NTFS格式的分区读写有很大的限制,网上看到很多相关的文章,都表明了一个信息:需要购买类似NTFS for mac这样的软件才能实现对NTFS格式的分区读写的权限,其实不然,mac自带的hdi ...
- SDUT OJ 顺序表应用5:有序顺序表归并
顺序表应用5:有序顺序表归并 Time Limit: 100 ms Memory Limit: 880 KiB Submit Statistic Discuss Problem Description ...
- TX2 自制底板不识别USB
目的:解决自制的底板无法识别USB,使能3个UART接口,使能3个SPI接口. Jetpack版本:Jetpack-3.1 虚拟机:ubuntu14.04 使用dtb文件夹下的文件替换刷机包../64 ...
- angular-ui-select (系列二)远程搜索,页面方框显示的值跟传给后台的值不一样解决方案
三:下拉单选远程搜索: 一个重点是: 这个方法,就是让我们去远程搜索的 refresh="ctrl.refreshAddresses($select.search)" refres ...
- Android 日历视图(Calendarview)
1.介绍 2.常用属性 3.xml文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayou ...
- JavaScript笔记Array.filter(Boolean)
ECMAScirpt5 中 Array 类中的 filter 方法使用目的是移除所有的 ”false“ 类型元素 (false, null, undefined, 0, NaN or an empt ...
- [转] Chrome - 浏览器跨域访问设置(附:新老版本两种设置方法)
[From] http://www.hangge.com/blog/cache/detail_1703.html 在进行前后分离的 webapp 开发,或者 H5 移动 App 开发时,我们会使用 P ...