java程序中调用python程序全教程

一、项目介绍:


        本人在做一个java的spring-boot后端,这个后端需要接收一个文件,然后对这个文件进行一定的处理,随后返回给前端结果,这里的处理就是调用的写好的python程序。

        针对我的情况,目前谷歌和百度没有一个涉及完整开发流程的教程,里面有很多的坑,我一点一点通过谷歌百度chatgpt填起来的。

        数据的流动是:前端→springboot→python程序→springboot→前端

        本文会介绍针对本地调试和服务器调试的案例。

二、环境配置:

2.1 java环境配置

        我用的java 8,应该别的版本也可以,不需要额外的库

2.2 python环境配置

        对于python的环境分两种情况:本地windows和服务器(一般为Linux或者centos)

        对于python的输出,你需要打印到控制台上,也就是print出来,这样java才能捕捉到。

2.2.1 python+windows环境配置情况

        就是正常的在windows上的python项目,能跑通就可以,没什么特殊的,建议使用虚拟环境而非全局环境。

2.2.2 python+linux环境配置情况

        项目结构和windows的python项目一样,但是有一个地方不一样!那就是venv环境文件夹,这里的venv需要是linux的python环境。windows和linux的python环境结构是不同的。你需要根据python的版本,和你自己用到的库,自行安装环境。

        后续的命令构建也会体现区别。

三、项目构建

        3.1 核心语句:

        //命令构建
        List<String> command = getBuilderCommand(filteredData, filterMethod, peekMethod);

        // 创建进程构建器
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        if (!System.getProperty("os.name").toLowerCase().contains("win")) {
            processBuilder.directory(new File("/www/wwwroot/SignalPlat/SignalPlatPY/SignalPlatPY_venv"));
        }

        // 错误输出流合并到标准输出流
        processBuilder.redirectErrorStream(true);


        Process process = processBuilder.start();


        InputStream inputStream = process.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        StringBuilder output = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            output.append(line);
        }

        int exitCode = process.waitFor();


        if (exitCode == 0) {
            return output.toString();
        } else {

            return "运行python脚本时出现问题,python错误输出为:" + output;
        }

对于构建命令的方法,分两种操作系统:

public List<String> getBuilderCommand(String filteredData, String filterMethod, String peekMethod) throws IOException {

        // 获取当前操作系统的名称
        String osName = System.getProperty("os.name").toLowerCase();

        // 设置配置信息
        String pyVenv;
        String pyScript;
        // 构建命令参数列表
        List<String> command = new ArrayList<>();


        if (osName.contains("win")) {
            command.add("cmd.exe");
            command.add("/c");

            pyVenv = "E:/project/PYsiglPlat/venv";
            pyScript = "E:/project/PYsiglPlat/hrv.py";

            command.add(pyVenv + "/Scripts/python.exe");


        } else {
            pyVenv = "/www/wwwroot/SignalPlat/SignalPlatPY/SignalPlatPY_venv/bin/python";
            pyScript = "/www/wwwroot/SignalPlat/SignalPlatPY/hrv.py";

            command.add(pyVenv);

        }

        // Python程序的路径
        command.add(pyScript);
        // python程序需要的参数们
        command.add(filteredData);
        command.add(filterMethod);
        command.add(peekMethod);

        return command;

    }

内容有点多,下面一点点讲(如果你有chatgpt,你也可以用它读代码)

3.2 代码详解

1,首先,我们构建一条命令,这个命令是用来执行python程序的。不同操作系统下命令会有所不同。

我写了一个自定义函数getBuilderCommand(),该函数在上面有详细代码和详细注释。

//命令构建
List<String> command = getBuilderCommand(filteredData, filterMethod, peekMethod);

2,随后,我们执行这条命令

ProcessBuilder processBuilder = new ProcessBuilder(command);

3,值得一提的是,如果在linux环境下,我们需要加上一句

processBuilder.directory(new File("/www/wwwroot/SignalPlat/SignalPlatPY/SignalPlatPY_venv"));

需要指定他的python环境的工作目录。

4,如果输出流合并到标准输出流

// 错误输出流合并到标准输出流
processBuilder.redirectErrorStream(true);

就是python打印了啥java就捕捉啥。如果不加这句话,后续是会有两个输出流,一个是正确的,一个出错的,我没细研究,于是我让他俩合并了。个人感觉不加这句话更专业一些,可以分别处理是否python程序报错了的两种情况,你可以再研究研究。

5,随后就是开始执行,然后吧输出都捕捉到String output变量里,随后根据

int exitCode = process.waitFor();

exitCode来判断程序是否发生了错误,来采取不同的手段。

四,总结

个人感觉有几个关键点容易踩坑:

一是phthon项目在windows和linux上的结构是相似但是不同的。

二是两个操作系统上需要执行的命令是不同的。

三是你需要把python的结果打印到控制台,好让java捕捉到。

好了,你已经学会怎么使用java程序调用python程序了,有问题可以给我留言评论~peace

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值