Java 调用 python 的接口
不管什么技术,不管什么问题,只要努力就能解决。
最近在做项目的时候,需要java 调用 python 接口,在网上找了一些方法,但是总碰到一些问题,索性将网上的方法和自己的理解总结一下,希望对各位博友有所帮助,也请各位大神不吝赐教。
一:创建环境 Python 环境
import org.python.util.PythonInterpreter;
import java.util.Properties;
/**
* Jython环境,获取Python的实例
* @author webim
*
*/
public class JythonEnvironment {
//定义一个静态变量
private static JythonEnvironment INSTANCE = new JythonEnvironment();
/**
* 私有构造方法
*/
private JythonEnvironment()
{
}
/**
* 获取单例
* @return JythonEnvironment
*/
public static JythonEnvironment getInstance()
{
return INSTANCE;
}
/**
* 获取python解释器
* @return PythonInterpreter
*/
public PythonInterpreter getPythonInterpreter()
{
Properties props = new Properties();
props.put("python.home","path to the Lib folder");
props.put("python.console.encoding", "UTF-8"); // Used to prevent: console: Failed to install "": java.nio.charset.UnsupportedCharsetException: cp0.
props.put("python.security.respectJavaAccessibility", "false"); //don"t respect java accessibility, so that we can access protected members on subclasses
props.put("python.import.site","false");
Properties preprops = System.getProperties();
//对 python 进行初始化
PythonInterpreter.initialize(preprops, props, new String[0]);
PythonInterpreter inter = new PythonInterpreter();
return inter;
}
}在创建 python 解释器之前,需要初始化 python 环境,参考过一些例子,是没有进行初始化,会进行报下列错误。
org.python.core.PyException: null
at org.python.core.Py.ImportError(Py.java:330) ~[jython-2.7.1b3.jar:na]
at org.python.core.Py.importSiteIfSelected(Py.java:1577) ~[jython-2.7.1b3.jar:na]
at org.python.util.PythonInterpreter.<init>(PythonInterpreter.java:116) ~[jython-2.7.1b3.jar:na]
at org.python.util.PythonInterpreter.<init>(PythonInterpreter.java:94) ~[jython-2.7.1b3.jar:na]
at org.python.util.PythonInterpreter.<init>(PythonInterpreter.java:71) ~[jython-2.7.1b3.jar:na]
at com.sihuatech.puzzlevideo.manage.controller.AAlarmController.getAllAlarmInfo(AAlarmController.java:85) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.27.jar:8.5.27]
二:调用 python 的接口
因为 python 和 java是两种不同的语言,因此在项目的 controller 、service 和 mapper 中直接出现 Python 的接口,因此自己封装 ExecPython 类,
封装python的接口,目的让 python 接口和java程序分隔开。
import org.python.core.PyFunction;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.Map;
/*enum的这个用法,可以作为变种的安全单例,值得借鉴哦 ^_^ */
@Service
@Component
public class ExecPython {
public static final Logger logger = LoggerFactory.getLogger(Exception.class);
//定义 python 解释器
private static PythonInterpreter inter;
public ExecPython() {
this.inter = JythonEnvironment.getInstance().getPythonInterpreter();
this.inter.execfile("C:\test.py");
}
//设置 python 脚本的路径
public void setPythonPath (String pythonPath){
this.inter.execfile(pythonPath);
}
public void execute(String scriptFile, Map<String,String> properties)
{
logger.info("获取解释器");
try
{
PyFunction getNetInfo = (PyFunction) inter.get("getNetInfo", PyFunction.class);
PyObject netInfo = getNetInfo.__call__();
System.out.println("anwser = " + netInfo.toString());
}
catch (Exception e)
{
e.printStackTrace();
logger.info("Python 脚本文件执行失败");
}
}
//获取 Python 字符串
public String getString(){//获取到python 脚本中的接口
PyFunction func = (PyFunction) inter.get("adder", PyFunction.class);
PyObject pyobj = func.__call__();
System.out.println("anwser = " + pyobj.toString());
return pyobj.toString();
}
// 获取当前数组
public String getArr() {
PyFunction getArr = (PyFunction) inter.get("getArr", PyFunction.class);
PyObject pyobjTwo = getArr.__call__();
pyobjTwo.__len__();
System.out.println("anwser = " + pyobjTwo.toString()+" len:"+pyobjTwo.__len__());
//将 PyObject 对象转换成 java 对象
//Object object = pyobjTwo.__tojava__(List.class);
//List<String> list = (List<String>) object;
//将查询到数据转换成一个 JSON 字符串
String result = pyobjTwo.toString();
String JsonStr = "{" + result + "}";
logger.info(JsonStr);
logger.info("将查询的结果转换成 JSON 字符串:",JsonStr);
return pyobjTwo.toString();
}
}三: python 脚本
def adder():return "{"name":"leilei","age":"18"}"
def getArr():
return ["aaa","bbb"]
def getNetInfo():
return [{"DNS":"192.168.12.3","ip":"45.23.16.0"},{"DNS2":"192.168.12.2","ip2":"45.23.16.2"}]
- 上一篇: 在Java中动态传参调用Python脚本
- 下一篇: Java调用Python脚本并获取返回值
