2019独角兽企业重金招聘Python工程师标准>>>
浏览器(Chrome,IE等等)启用java程序-webstart方式
贴下自己的码云地址
https://gitee.com/imbobo_bo/angel-bo 本文章讲解的都可以在码云上找到
前端代码:https://gitee.com/imbobo_bo/angel-bo/tree/develop/angel-ui/src/views/demo/webstart 服务端代码:https://gitee.com/imbobo_bo/angel-bo/blob/develop/angel-business/src/main/java/com/angel/bo/business/service/impl/WebStartServiceImpl.java
需求
Chrome从版本45开始,不再支持NPAPI插件,而Java Applet依赖于NPAPI插件,所以Chrome 版本45以后都不再支持Java Applet,而以往大家接触最多的就是用applet的方式调用java程序,那有没有更好的或者其他方式优雅的用浏览器执行服务器上的java程序呢?
解决
选择正确的调用方式
首先想去java官网上检索相关信息,功夫不负有心人https://docs.oracle.com/javase/tutorial/deployment/deploymentInDepth/createWebStartLaunchButtonFunction.html 二话不说,照着官网示例一步一步解决吧 上面说有个js工具deployJava.js
然后使用 launchWebStartApplication(这个在上面的网址上有,调用这个方法就可以直接加载了,而createWebStartLaunchButton这个方法是加载一个按钮,点击按钮来触发java程序)
遇到的问题
上面截图中说明了,参数是个url,这个url返回是一个JNLP文件,浏览器加载这个文件才可以调用java程序 那现在随着互联网前后端分离,后端服务都提供restful方式返回json,在不改变这个大前提下如何做呢,带着这个疑问浏览deployJava.js
改造deployJava.js代码
解读源码,这个方法是加载jnlp文件的
function launchWithJnlpProtocol(jnlp) {
document.location="jnlp:"+ getAbsoluteUrl(jnlp);
}
所以修改这个方法
//jnlpURL是接口地址,option是请求参数主要是为了可以给需要执行的java动态添加执行参数
function launchWithJnlpProtocol(jnlpURL,option) {
document.location="jnlp:"+ getRootPath()+jnlpURL+"?"+option;
}
function getRootPath() {
var pathName = window.location.pathname.substring(1);
var webName = pathName == '' ? '' : pathName.substring(0, pathName.indexOf('/'));
//return window.location.protocol + '//' + window.location.host + '/'+ webName + '/';
var local = window.location.host.replace("localhost","127.0.0.1");
if(webName){
return window.location.protocol + '//' + local + '/' + webName;
}else{
return window.location.protocol + '//' + local;
}
}
编写服务端JNLP
这里没什么特别的,由controller调用service生成jnlp文件
JNLP = new StringBuffer();
JNLP.append("\n" +
"\n" +
" \n" +
" Case Cloud \n" +
" ANGEL \n" +
" \n" +
" \n" +
" \n" +
" \n" +
" \n" +
"\n" +
" \n" +
" \n" +
" \n" +
" \n" +
" \n" +
" TEST#DEMO#000000 "+
" " + webStart.getOption() +" "+
" \n" +
" \n" +
" \n>");
WebReturn webReturn = new WebReturn();
webReturn.setData(JNLP.toString());
JNLP文件规则可以参考官网上的,这里不多描述
浏览器调用java的原理
浏览器按钮触发加载JNLP文件,JNLP文件中描述了可执行jar包的下载地址,执行方法,参数。然后去下载jar包执行
可执行jar包添加签名
毕竟这种方式存在安全隐患,所以可执行jar包必须具有签名才可以
摘自其他博主的一段话,对jar包加密
到Dos状态下,,进入你们需发布应用程序的jar包所在的目录,运行下面这句话: keytool -genkey -keystore myKeystore -alias jwstest (它们将会提示你们输入用户名、密码等,,不用理它们,,按照提示随便输入即可,,但一定要记住密码..运行结束它们将会在当前路径下创建名为myKeystore(的)文件..) 说明:keytool是JDK自带的一个用于数字签名的工具。该语句的意思是生成一个证书,并且其文件名是:myKeystore。 2、用证用为应用程序签名 jarsigner -keystore myKeystore HelloWorld.jar jwstest (其中HelloWorld.jar是你们(的)jar包名(这里就是HelloWorld.jar),你们需要修改它们,,别(的)就不必修改了..运行时会提示你们输入密码,,就是你们刚才在生成myKeystore文件时设定(的)密码..)
完成下载jar包的接口
@GetMapping("/downloadWebExecuteOJar/{jarName:.+}")
@IgnoreUserToken
public void downloadWebExecuteOJar(@PathVariable("jarName") String jarName, HttpServletRequest request, HttpServletResponse response) throws IOException {
webStartService.downloadWebExecuteOJar(jarName,request,response);
}