最近项目中经常需要将Javascript或者Python中的算法发布为服务,而发布Tomcat服务则需要在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])
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视频教程
原文地址:https://www.jb51.cc/java/1192317.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。