工作原因,需要通过Python脚本进行接口访问获取接口数据。
网上java执行Python脚本无外乎三种方法:
1、直接执行Python脚本代码
引用 org.python包
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("days=('mod','Tue','Wed','Thu','Fri','Sat','Sun'); ");
///执行python脚本
2、执行python .py文件
PythonInterpreter interpreter = new PythonInterpreter();
InputStream filepy = new FileInputStream("D:\\demo.py");
interpreter.execfile(filepy); ///执行python py文件
filepy.close();
3、使用Runtime.getRuntime()执行脚本文件
这种方式和.net下面调用cmd执行命令的方式类似。如果执行的python脚本有引用第三方包的,建议使用此种方式。使用上面两种方式会报错Java ImportError: No module named arcpy。
Process proc = Runtime.getRuntime().exec("python D:\\demo.py");
proc.waitFor();
引用:http://blog.csdn.net/l1028386804/article/details/50914261
本次项目使用了Runtime.getRuntime().exec()方法,解决Python的执行问题,原因如下:
1、此方法使用的系统命令执行,window下使用cmd命令,linux环境下使用Python命令。没有使用第三方依赖包,功能齐全、方便管理。
2、系统环境下对Python环境的支持最大,如引入的第三方包python、jpython等,可能对类库的支持不是很好,在引入基础类库的时候就得不到很好的支持,引起异常报错。
代码如下:
public List<String> python(String pythonPath) {
List<String> res = new ArrayList<>();
String url=PythonRunner.class.getClassLoader().getResource("").getPath()+"cfg/spring/cs.py";
logger.info("脚本地址:"+url);
File file = new File(url);
if (!file.exists()){
res.add("python脚本不存在!");
return res;
}
String [] cmd={"python",url};
try {
logger.info("开始执行脚本...\n");
Process process = Runtime.getRuntime().exec(cmd);
if (process == null) {
return null;
}
Scanner scanner = new Scanner(process.getInputStream());
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
res.add(line);
}
try {
process.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("脚本执行结束...\n 本次查询数据"+res.size()+"条");
} catch (IOException e) {
e.printStackTrace();
}
return res;
}
上面的程序经过了调试,可以正常获取到Python脚本执行输出的信息并在java程序里面进行处理。
命令执行采用的是
public Process exec(String [] cmdArray)
其中 amdArray 是命令数组,如
String [] cmd={"python",url};
其实就是linux环境下的Python执行命令:
python ../vip/cs.py
至于cs.py 可以简单写个Python脚本测试下,如下实例:
#!/usr/bin/env python
# By: Kelcey Damage, 2012 & Kraig Amador, 2012
str ='1123'
print str
1123
不过在Python脚本执行输出后,如果对输出的内容进行转化在输出,例如转成json格式后print,java程序里面的Process好像不能正常获取到转换之后的信息流。如:
from api import json
json=json.dumps(all_vms, ensure_ascii=False, indent=2)
print json
该Process获取的结果为空。
问题原因可能是因为Process获取内存流,而通过json工具类转化后已经在脚本里面把原始流处理接收了,因此导致Process接收的为空。本分析只是猜测,具体还未验证。不过暂时不影响项目开发,先记录下来吧。
为记录日志,还用到了文件写入:
#p = open("/home/print.txt", 'w+')
#print >>p,json.dumps(all_vms).decode('utf8').encode('gbk')
这个方法还解决了中文乱码的问题,也记录一下。