项目中有用到Java调用python的需求,经过各种坑之后,根据业务需求,最终实现Java调用Python的各种情况,现在将总结如下,当然调用的也是Jython,具体原因,下面会介绍,先将代码贴出来。

这种方法是调用python文件的函数 ,并且需要将函数中的参数由Java数据类型转换为python的数据类型

<dependency>

<groupId>org.python</groupId>
<artifactId>jython</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.0</version>

</dependency>

public class JythonExecPyFile {

private static Log logger = LogFactory.getLog(JythonExecPyFile.class);

public static PythonInterpreter getPythonEnterpreter(String jythonHome,String jythonJsonHome,String pythonRuleDir){

Properties props = new Properties();
    //props.put("python.home", "path to the Lib folder");
    props.put("python.home", jythonHome);
    props.put("python.console.encoding", "UTF-8");
    props.put("python.security.respectJavaAccessibility", "false");
    props.put("python.import.site", "false");

Properties preprops = System.getProperties();

PythonInterpreter.initialize(preprops, props, new String[0]);
    PythonInterpreter pythonInterpreter = new PythonInterpreter();

PySystemState sys = Py.getSystemState();
    
    sys.path.add(jythonJsonHome);
    sys.path.add(pythonRuleDir);
    //logger.info("jythonHome: " + jythonHome +"    jythonJsonHome: " + jythonJsonHome + "    pythonRuleDir: " + pythonRuleDir);
    return pythonInterpreter;
  }

public static void addPythonThirdPartLib(String thirdLibPath){
    PySystemState sys = Py.getSystemState();
    sys.path.add(thirdLibPath);
    sys.path.add(SettingConfiguration.getValue("pythonDir"));
  }

public static void cleanup(PythonInterpreter interpreter){
    if(interpreter != null){
      interpreter.close();
    }
  }
  
  public static void main(String[] args) {

PythonInterpreter pythonEnterpreter = getPythonEnterpreter(SettingConfiguration.getValue("jPythonHome"),SettingConfiguration.getValue("jythonJsonHome"),SettingConfiguration.getValue("pythonDir"));
    
    System.out.println("-----------------------------调用有参数python方法执行方法-----------------------------");
    String fileNameWithParams = "D:\\Java\\python344\\age.py";
    pythonEnterpreter.execfile(fileNameWithParams);
    PyFunction func = (PyFunction) pythonEnterpreter.get("judge_age",PyFunction.class);
    PyObject pyobj = func.__call__(new PyString("2000-11-11"),new PyInteger(1));
    
    System.out.println("pyObj: " + pyobj);
    
    System.out.println("-----------------------------调用无参数python方法执行方法-----------------------------");
    String fileNameNoParams = "D:\\svnProject\\testConnectDB.py";
    pythonEnterpreter.execfile(fileNameNoParams);
    PyFunction func2 = (PyFunction) pythonEnterpreter.get("say",PyFunction.class);
    PyObject pyobj2 = func2.__call__();
    System.out.println("pyObj: " + pyobj2);
    
    JythonExecPyFile.cleanup(pythonEnterpreter);

}

而为了更好的封装,将调用python的参数放到list中,而将返回的数据放到dict中,python将dict转换为json串,然后在java接受到返回结果之后,将json串在转换成java的map类型即可。

public class RuleAndModelExecuteFunction {
  private static Log logger = LogFactory.getLog(RuleAndModelExecuteFunction.class);
  /**
   * 规则一 根据文件名、函数名称 参数列表 执行对应的规则或者模型     0 pass       1 reject      2 nodata
   * param :fileName, functionName,params,params where from the params of python ,And
   * if contact 为null,或者长度为0,或者为空字符串  则 empty_contacts=1  (反欺诈规则结果)anti_fraud_rules_result='reject'
   * else  anti_fraud_rules_result=‘pass'  empty_contacts=0    0 pass 1
   */

public static String ruleExecuteMethod(String fileName,String functionName,Object... params){
logger.info("ruleExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName);  
    String returnResult = "";
List<Object> paramList = new ArrayList<Object>();
    for(Object obj:params){
      paramList.add(obj);
    }
    String fileNamePath = SettingConfiguration.getValue(fileName);
    Integer defaultResult = 2;
    
    PythonInterpreter pythonInterpreter = null;
    PyObject pyResult  = new PyObject();
    try {
      pythonInterpreter = JythonExecPyFile.getPythonEnterpreter(SettingConfiguration.getValue("jythonHome"),SettingConfiguration.getValue("jythonJsonHome"),SettingConfiguration.getValue("pythonDir"));
      pythonInterpreter.execfile(fileNamePath);
      PyFunction func = (PyFunction) pythonInterpreter.get(functionName,PyFunction.class);
      pyResult = func.__call__(new PyList(paramList));
    }catch (Exception e){
      defaultResult = 4;
      logger.error("ruleExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + "\n" + e.getStackTrace());
      e.printStackTrace();
      return RiskRuleResultEnum.fromValue(defaultResult).getValue();
    }finally {
      JythonExecPyFile.cleanup(pythonInterpreter);
    }
    //pyResult返回的结果由原来的String类型修改为和模型一样,返回的Map类型
   /* if(pyResult != null){
        String pyResultStr = pyResult.toString();
        defaultResult = Integer.valueOf(pyResultStr);
        logger.info("RuleAndModelExecuteFunction ruleExecuteMethod result: " + pyResult.toString());
      }else {
        logger.info("RuleAndModelExecuteFunction ruleExecuteMethod result: " + pyResult);
      }*/
    if(pyResult != null){
    Map<String,Object> returnMap = JacksonUtil.convertJson2Map(pyResult.toString());
   if(returnMap.get("result") == null){
    returnResult = RiskRuleResultEnum.fromValue(defaultResult).getValue();
       logger.info("ruleExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + " result为空,设置为默认值: " + defaultResult);
   }else {
    returnResult = RiskRuleResultEnum.fromValue((Integer) returnMap.get("result")).getValue();
    logger.info("ruleExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + " result: " + defaultResult);
   }
    }else{
    returnResult = RiskRuleResultEnum.fromValue(defaultResult).getValue();
    }
    logger.info("ruleExecuteMethod result: " + returnResult );
    return returnResult;
  }

public static Map<String,String> ModelExecuteMethod(String fileName,String functionName,Object... params){
logger.info("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName);  
Map<String,String> resultMap = new HashMap<String,String>();
Integer defaultResult = 2;
Double defaultData = new Double(0.00);
    List<Object> paramList = new ArrayList<Object>();
    for(Object obj:params){
      paramList.add(obj);
    }

String fileNamePath = SettingConfiguration.getValue(fileName);
    logger.info("fileNamePath:"+fileNamePath);
    PythonInterpreter pythonInterpreter = null;
    PyObject pyResult = null;
    try {
      pythonInterpreter = JythonExecPyFile.getPythonEnterpreter(SettingConfiguration.getValue("jythonHome"),SettingConfiguration.getValue("jythonJsonHome"),SettingConfiguration.getValue("pythonDir"));
      pythonInterpreter.execfile(fileNamePath);
      PyFunction func = (PyFunction) pythonInterpreter.get(functionName,PyFunction.class);
      PyList pyList = new PyList(paramList);
      pyResult = func.__call__(pyList);
    }catch (Exception e){
      defaultResult = 4;
      defaultData = new Double(-1);;
      logger.error("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + "\n" + e.getStackTrace());
      resultMap.put("result", RiskRuleResultEnum.fromValue(defaultResult).getValue());
      resultMap.put("data",defaultData.toString());
      e.printStackTrace();
      return resultMap;
    }finally {
      JythonExecPyFile.cleanup(pythonInterpreter);
    }
    logger.info("return result:"+pyResult.toString());
    Map<String,Object> returnMap = JacksonUtil.convertJson2Map(pyResult.toString());
    if(returnMap.get("result") == null){
    resultMap.put("result",RiskRuleResultEnum.fromValue(defaultResult).getValue());
        logger.info("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + " result为空,设置为默认值: " + defaultResult);
    }else {
    resultMap.put("result",RiskRuleResultEnum.fromValue((Integer) returnMap.get("result")).getValue());
    }
    if(returnMap.get("data") == null){
      resultMap.put("data",defaultData.toString());
      logger.info("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + " data为空,设置为默认值: " + defaultData);
    }else {
    logger.info("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + " data为空,设置为默认值: " + returnMap.get("data"));
      resultMap.put("data",returnMap.get("data").toString());
    }
    
    if (returnMap.get("antifraud_model_saved")!=null) {
    resultMap.put("antifraud_model_saved", JsonUtils.toJson(returnMap.get("antifraud_model_saved")));
}
    if (returnMap.get("android_new_saved")!=null) {
        resultMap.put("android_new_saved", JsonUtils.toJson(returnMap.get("android_new_saved")));
}
    if (returnMap.get("profile_model_saved")!=null) {
    resultMap.put("profile_model_saved", JsonUtils.toJson(returnMap.get("profile_model_saved")));
}
   
    logger.info("RuleAndModelExecuteFunction ModelExecuteMethod result: " +pyResult.toString() );
    return resultMap;
  }
  
  public static Map<String,String> collectionExecuteMethod(String fileName,String functionName,Object... params){
logger.info("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName);  
Map<String,String> resultMap = new HashMap<String,String>();
    
List<Object> paramList = new ArrayList<Object>();
    for(Object obj:params){
      paramList.add(obj);
    }

String fileNamePath = SettingConfiguration.getValue(fileName);
    logger.info("fileNamePath:"+fileNamePath);
    PythonInterpreter pythonInterpreter = null;
    PyObject pyResult = null;
    try {
      pythonInterpreter = JythonExecPyFile.getPythonEnterpreter(SettingConfiguration.getValue("jythonHome"),SettingConfiguration.getValue("jythonJsonHome"),SettingConfiguration.getValue("pythonDir"));
      pythonInterpreter.execfile(fileNamePath);
      PyFunction func = (PyFunction) pythonInterpreter.get(functionName,PyFunction.class);
      PyList pyList = new PyList(paramList);
      pyResult = func.__call__(pyList);
    }catch (Exception e){
      logger.error("ModelExecuteMethod param------ fileName: " + fileName + "  functionName: " + functionName + "\n" + e.getStackTrace());
      resultMap.put("result", "error");
      resultMap.put("data","-1");
      e.printStackTrace();
      return resultMap;
    }finally {
      JythonExecPyFile.cleanup(pythonInterpreter);
    }
    logger.info("return result:"+pyResult.toString());
    Map<String,Object> returnMap = JacksonUtil.convertJson2Map(pyResult.toString());
   
    resultMap.put("result", returnMap.get("result").toString());
    resultMap.put("data", returnMap.get("data").toString());
    
    logger.info("RuleAndModelExecuteFunction ModelExecuteMethod result: " +returnMap);
    return resultMap;

}

public static Map<String, Object> convertJson2Map(String json) {
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {
};
try {
return mapper.readValue(json, typeRef);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;

}

通过这种封装之后,完成了最终的封装,并作为工具类进行调用。

Java调用python由三种方式,分别如下:

第一种方式:

public class HelloPython {public static void main(String[] args) {PythonInterpreter interpreter = new PythonInterpreter();interpreter.exec("print('hello')");}
}

什么是 PythonInterpreter 呢?它的中文意思即“ Python 解释器”。我们知道 Python 程序都是通过解释器执行的,上面的代码就是在 JVM 中创建一个“ Python 解释器”对象,模拟 Python 解释器的行为,通过 exec(" Python 语句") 直接在 JVM 中执行 Python 代码,代码的输出结果为:hello,需要提醒各位的是,该程序运行速度相较正常的 Java or Python 程序都要慢那么一点。

第二种方式:在项目中实际用到,执行的是python文件中的函数,见上面

第三种方式:通过解释器直接执行python文件

#open files
print 'hello'
number=[3,5,2,0,6]
print number
number.sort()
print number
number.append(0)
print number
print number.count(0)
print number.index(5)
import org.python.util.PythonInterpreter;
public class FirstJavaScript {
  public static void main(String args[]) {
    PythonInterpreter interpreter = new PythonInterpreter();
    interpreter.execfile("C:\\Python27\\programs\\input.py");
  }// main
}

第四种方式:该方式是否可以调用python的第三方模块,没有运行,用需求的朋友可以执行一个程序就可以验证

由于 Jython 运行过慢并且不支持第三方的 Python 模块,通过 Java 代码执行一段终端命令来调用 Python 脚本,根据具体问题决定如何交互可能才是实际中真正会用到的方式(详见下面的举例代码)。

举例代码:下面是一个可以识别很粗的手写数字写的一个小程序,界面上引用了 core java 上的一段代码:

import java.io.*;class PyCaller {private static final String DATA_SWAP = "temp.txt";private static final String PY_URL = System.getProperty("user.dir") + "\\test.py";public static void writeImagePath(String path) {PrintWriter pw = null;try {pw = new PrintWriter(new FileWriter(new File(DATA_SWAP)));} catch (IOException e) {e.printStackTrace();}pw.print(path);pw.close();}public static String readAnswer() {BufferedReader br;String answer = null;try {br = new BufferedReader(new FileReader(new File(DATA_SWAP)));answer = br.readLine();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return answer;}public static void execPy() {Process proc = null;try {proc = Runtime.getRuntime().exec("python " + PY_URL);proc.waitFor();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}// 测试码public static void main(String[] args) throws IOException, InterruptedException {writeImagePath("D:\\labs\\mytest\\test.jpg");execPy();System.out.println(readAnswer());}
}

运行流程:Java Swing 界面接收用户输入 --> Java 将用户输入写到本地文件中 --> Java 调用本地 Python 脚本 --> Python 从本地文件拿到用户输入 --> Python 处理用户输入得到最终结果 --> Python 把最终结果写到本地文件 --> Java 对 Python 脚本的调用结束 --> Java 从本地文件中取出最终结果 --> Java 把最终结果返回给用户

完整代码链接:http://pan.baidu.com/s/1sl4l68H

Java调用python项目实战相关推荐

  1. java调用python项目实战_Java调用Python

    今天遇到Java调用一个Python脚本的问题,纠结了大半天,遇到各种问题.网上搜索的大部分都是用jython,但是我想要调用的python脚本里有import urllib,这个urllib也不是什 ...

  2. C++调用Python项目实战

    C++调用Python项目: 实战:链接:https://pan.baidu.com/s/1A_If6y37aS2LfWtHglBECQ 提取码:wsnb –来自百度网盘超级会员V2的分享

  3. Python和Java结合的项目实战_[项目实战] Python高级教程项目实战篇 Python和Java结合的项目实战 视频教程 [...

    资源介绍 课程简介:xa0xa0 Python高级教程项目实战篇 Python和Java结合的项目实战 视频教程 教学视频 ----------------------课程目录 Python项目实战篇 ...

  4. Python和Java结合的项目实战

    近期正在建一个网站,用于分享视频和资料,网站现在已经建好,只是还没有开放注册功能,还在调试中.待上线后大家就 可以找到自己合适的资源了. Python和Java结合的项目实战 本次视频的项目介绍,如下 ...

  5. java和python可以在一个项目中同时使用么-java调用python的几种用法(看这篇就够了)...

    java调用python的几种用法如下: 在java类中直接执行python语句 在java类中直接调用本地python脚本 使用Runtime.getRuntime()执行python脚本文件(推荐 ...

  6. Python项目实战:使用PySpark对大数据进行分析

    Python项目实战:使用PySpark对大数据进行分析 大数据,顾名思义就是大量的数据,一般这些数据都是PB级以上.PB是数据存储容量的单位,它等于2的50次方个字节,或者在数值上大约等于1000个 ...

  7. 视频教程-Java大型企业级项目实战:VOD展示系统-Java

    Java大型企业级项目实战:VOD展示系统 系统分析师,项目经理,特级讲师:11年项目经验,8年教学经验:在多个大型企业级项目中担任过重要角色. 肖海鹏 ¥479.00 立即订阅 扫码下载「CSDN程 ...

  8. 【Java】使用Java调用Python的四种方法

    写在前面 为啥一个好好的岗位是Java开发工程师要去做写python呢?因为产品经理安排的(突然多少有点明白为啥程序员和产品经理会一直开撕).由于在选择企业的时候没看清企业性质,看了要求以为就是互联网 ...

  9. .net core 引用jar_Python一键转Jar包,Java调用Python新姿势!

    粉丝朋友们,不知道大家看故事看腻了没(要是没腻可一定留言告诉我^_^),今天这篇文章换换口味,正经的来写写技术文.言归正传,咱们开始吧! 今天的这篇文章,聊一个轩辕君之前工作中遇到的需求:如何在Jav ...

最新文章

  1. 网站服务器的ip地址会变吗,网站的服务器变了 IP地址变吗
  2. Singleton 单例模板
  3. 改变shell read命令的隔符
  4. HA总结:AWS 网络连接
  5. 无线网络国际会议排名(zz)
  6. vc中关于 directx的配置,和dxsdk_extras(directshow)
  7. new 操作符干了什么?
  8. 02 Toolbar的使用
  9. displayTag标签
  10. App Store打了这么多年,ASO优化还剩什么?
  11. xcode 软件˙∆集~
  12. python opencv轮廓检测_python opencv 来对图片(苹果)的轮廓(最大轮廓进行识别)进行...
  13. 鸿蒙系统专利申请,华为在欧盟申请HarmonyOS专利 或为鸿蒙系统的英文名称
  14. Photoshop——多变量+文字数据组替换+批处理详细操作
  15. 建模新手使用Maya的xGen功能后,角色毛发顺滑堪比使用海飞丝!
  16. 希尔排序Linux下c 实现
  17. 关于 simulink 的 1/z 模块是什么的问题
  18. 从Redis、HTTP协议,看Nett协议设计,我发现了个惊天大秘密
  19. 收藏备用 | 了解这些砼试块常见问题,升职都快人一步
  20. 2021大数据助力精准医疗产业沙龙 | 有孚网络吕鑫:基于专有云打造生物信息云平台

热门文章

  1. Python编写masscan+nmap的主机和端口信息收集工具
  2. 【转】OMG 网络验证
  3. k8s拉取镜像失败处理 ImagePullBackOff ErrImageNeverPull
  4. JAVA中opencsv包解析CSV大文件
  5. AR.js开发问题详解(二维码识别不出来及AR二维码如何进行训练)
  6. 使用python获取股票“净利润同比增长率”等“上市公司成长能力”数据
  7. Python实现批量汉字转拼音作搜索框提示词
  8. [小黄书小程序]导航栏和标题栏界面
  9. 外部排序--归并算法实现
  10. pdf怎么转换成图片?分享三种途径