Java调用Javascript、Python算法总结
最近项目中经常需要将Javascript或者Python中的算法发布为服务,而发布Tomcat服务则需要在Java中调用这些算法,因此就不免要进行跨语言调用,即在Java程序中调用这些算法。
不管是调用Javascript文件还是python脚本,都需要将原来的算法文件进行适当的更改,以便可以在Java中传入参数,并且得到算法运算结果。
一、Java调用Javascript
需要注意的是Javascript是弱类型语言,定义变量只需要一个var就可以搞定,但是在Java中却要注意变量类型,不同的输入参数会有不同的类型。
调用js文件时,需要对其进行调整,设置好需要调用的function和相关参数,使用的js文件代码如下(其中有些核心算法不能展示):
function get3DCode(Latitude,Longitude,Height,level){
var latcode=[];var lngcode=[];
latcode=GeoSOTCode1D(Latitude,level);
lngcode=GeoSOTCode1D(Longitude,level);
var heicode=[];var geosot3Dcode=[];
heicode=Altcode(Height,level);
geosot3Dcode=GeoSOT3D(latcode,lngcode, heicode,level);//三维网格编码
var d3code=[];
d3code=getQuantcodeString(geosot3Dcode);
return d3code;
}
在Java中使用对应的接口就可以调用,需要设置js文件路径和输入参数,调用的代码如下;
package whu.get.three.beidou; import java.io.FileReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager; /** * Java调用并执行js文件,传递参数,并获得返回值 */
public class ThreeD_GetBeidouCode {
//获取经纬度及高度,返回三维码
public static String main(String Latitude,String Longitude,String Height,int CodeSize) throws Exception {
//获取经纬度及高度,保存为double类型
Double latitude = Double.parseDouble(Latitude);
Double longitude = Double.parseDouble(Longitude);
Double height = Double.parseDouble(Height);
int level = CodeSize; //调用js文件
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
String jsFileName = System.getProperty("catalina.home") + "/webapps/3DBeiDouCode/WEB-INF/classes/3Dcode.js"; // 读取js文件
FileReader reader = new FileReader(jsFileName); // 执行指定脚本
engine.eval(reader);
String c = "";
if(engine instanceof Invocable) {
Invocable invoke = (Invocable)engine; // 调用merge方法,并传入两个参数
c = String.valueOf(invoke.invokeFunction("get3DCode", latitude, longitude, height, level));
}
reader.close();
return c; //返回三维码
}
}
这里的ThreeD_GetBeidouCode类只是一个普通的类,需要在其他可运行的主函数中调用这个类的main方法,传入运行参数就可以得到结果。
二、Java调用Python
Java调用python脚本有好几种方法,最简单的是通过Jython来直接运行python代码,但是这种方法不支持python中引用的第三方库,因此我使用了Runtime来调用的方法,这也相当于是在控制台执行脚本。
需要注意的是,Java调用python时,不能通过return语句来获取返回值,而只能通过print将结果写入到标准输出流中,然后在Java中通过标准输入流来读取到返回结果。
如果对python环境有要求,比如在特定的环境中安装了需要引用的第三方库,则还要在Java工程中添加运行环境,在eclipse中点击Run->Run Configurations->environment,添加Path,值设置为python安装的路径。
在python程序中做适当修改:添加引用 import sys,将调用的函数参数设定为sys.argv[1],sys.argv[2]...注意必须是从1开始计数,将需要返回的结果用print函数打印。
本例中python代码如下:
# -*- coding:utf-8 -*-
import BaseFunction
import numpy as np
import itertools
import math
import sys #计算中心要素
def cal_central_feature(path,x,y):
sf = BaseFunction.open_shpfile(path)
x_records = BaseFunction.get_attr_records(sf,x)
y_records = BaseFunction.get_attr_records(sf,y) dis = []
for x0,y0 in zip(x_records,y_records):
distance = 0 for x1,y1 in zip(x_records,y_records):
distance = distance + get_distance(x0,y0,x1,y1) dis.append(distance) i = dis.index(np.min(dis)) result = [x_records[i],y_records[i]] return result #计算两点之间的距离
def get_distance(x0,y0,x1,y1):
xd = x1 - x0
yd = y1 - y0
distance = math.sqrt(xd**2+yd**2)
return distance if __name__ == '__main__':
result = cal_central_feature(sys.argv[1],sys.argv[2],sys.argv[3])
print(result[0])
print(result[1])
Java中调用的代码如下:
package whu.get.three.beidou; import java.io.BufferedReader;
import java.io.InputStreamReader; /** * Java调用并执行js文件,传递参数,并活动返回值 */
public class CalCentralFeatureClass {
//输入shp路径,获取坐标
public static String main(String filepath) {
String pyPath = System.getProperty("catalina.home") + "/webapps/CalCentralFeature/WEB-INF/classes/CalCentralFeature.py"; //python文件路径
String[] args = new String[] { "python", pyPath, filepath, "x","y"};
String c = ""; //记录返回值
try {
Process proc = Runtime.getRuntime().exec(args); //执行py文件
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
c = c+line+' ';
}
in.close();
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
return c; //返回结果
}
}
得到的运算结果中,每一个python中print的结果,对应一个in.readLine(),可以按照需要获取自己想要的结果。
如果需要将调用python的程序用tomcat发布为服务,也需要配置tomcat的运行环境,同样是添加一个Path,赋值为python安装路径。
Java调用Javascript、Python算法总结的更多相关文章
- [转]Java调用Javascript、Python算法总结
最近项目中经常需要将Javascript或者Python中的算法发布为服务,而发布Tomcat服务则需要在Java中调用这些算法,因此就不免要进行跨语言调用,即在Java程序中调用这些算法. 不管是调 ...
- Java 调用 Javascript 函数的范例
在Java 7 以后,可以在Java代码中调用javascript中的函数,请看下面的例子: package com.lee; import java.io.FileNotFoundException ...
- Java调用外部程序常用算法和封装类
一个项目不可能只使用一种编程语言来开发,也不可能由一个人开发,所以,Java程序员要学会和使用其他编程语言的程序员合作.那么,让我来发布一个工具类--Java外接程序扩展包,并将相应算法发布.Java ...
- Selenium+java - 调用JavaScript操作
前言 在做web自动化时,有些情况selenium的api无法完成,需要通过第三方手段比如js来完成实现,比如去改变某些元素对象的属性或者进行一些特殊的操作,本文将来讲解怎样来调用JavaScript ...
- Java调用JavaScript
1.main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...
- java 调用javascript
首先我们在D盘的根目录下有一个js文件 名叫 common.js 假设里面有一个这样的方法 /** * @param int * _number 你想要的最大值 * @param ...
- 从Java 调用JavaScript
篇幅过长 下载资源链接https://www.slidestalk.com/s/java_javascript_5hl09w
- Java调用Python脚本
今天遇到Java调用一个Python脚本的问题,纠结了大半天,遇到各种问题.网上搜索的大部分都是用jython,但是我想要调用的python脚本里有import urllib,这个urllib也不是什 ...
- WebView上实现Java与JavaScript交互
在安卓开发上,考虑到开发效率和界面更新,有时使用WebView结合web页面技术,可以快速迭代地开发移动应用.WebView加载资源的速度并不慢,但是如果资源多了,就很慢.图片.css.js.html ...
随机推荐
- Java/JSP/JS Debug笔记
2006年的blog,当时好生涩啊: ------------------------ 谨以此文献给我没有头绪或心劲去debug的日子和很多辛苦debug的同志们. 应部门一个科的需求,给他们写一个夜 ...
- 拖拽模块move1
刚开的博客,想着写点什么,以前写过拖拽函数,后来又学习了模块化,于是一直想把之前写的拖拽函数封成一个独立的模块,方便以后调用,说干就干,下面码代码... <script> var move ...
- Spring HTTP状态码枚举值对照表
使用Spring时总去查HTTP状态码对应的Spring枚举值的那篇代码,有点不方便,把代码拷贝出来统一替换格式做成了表格,放在这里,方便大家使用.(枚举类为HttpStatus) 枚举值 HTTP状 ...
- SpringCloud实战-Hystrix请求熔断与服务降级
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- 洛谷 P2725 解题报告
P2725 邮票 Stamps 题目背景 给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K -- 表示信封上能够贴 K 张邮票.计算从 1 到 M 的最大连续可贴出的邮资. 题目描 ...
- C语言pow()函数的计算精度问题
编程计算 a+aa+aaa+-+aa-a(n个a)的值,n和a的值由键盘输入.例如,当n=4,a=2,表示计算2+22+222+2222的值. 程序运行结果示例: Input a,n: 2,4↙ su ...
- 在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示
在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示 当我们在VS的C++中使用vector.list.map等这些STL容器,在开启调试的时 ...
- SSM-MyBatis-02:Mybatis最基础的增删改查(查全部和查单独一个)
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 继续上次的开始,这次记录的是增删改查,上次重复过的代码不做过多解释 首先先创建mysql的表和实体类Book ...
- Ambiguous mapping found
If you have a single default method (without explicit path mapping), then all requests without a mor ...
- 用php过滤文字中的表情字符
很多时候,如果文字中夹带表情,那么这些文字的处理就会出现问题,例如,如果一个用户的昵称带有表情,那么我怎么把这个昵称转换为拼音呢?在实际的开发中,我遇到了这个个问题,先是找到了 https://git ...