告诉你如何用springboot调用python脚本

目录

springboot调用python脚本

准备工作

方法一:使用 ProcessBuilder

1. 编写测试方法

2. 解释代码

方法二:使用 Apache Commons Exec

1. 编写测试方法

2. 解释代码

Python 脚本的数据通过接口让 Spring Boot 接收。

Python 脚本作为服务

1. 使用 Flask 创建 Python HTTP 服务

2. 在 Spring Boot 中调用 Python HTTP 服务

使用 RestTemplate

使用 WebClient

结论


在现代软件开发中,有时我们需要在 Java 应用中调用外部脚本,比如 Python 脚本。Spring Boot 提供了灵活的方式来集成这些外部脚本。本文将详细介绍如何在 Spring Boot 应用中调用 Python 脚本,包括两种不同的方法:使用 Java 的 ProcessBuilder 类和使用 Apache Commons Exec 库。

springboot调用python脚本

准备工作

在开始之前,我们需要准备一个 Python 脚本。请按照以下步骤操作:

  1. 在 D 盘创建一个名为 python 的文件夹。
  2. 在该文件夹内创建一个名为 hello.py 的 Python 脚本,内容如下:
 

python

print("Hello World!!")
  1. 在 Spring Boot 项目中定义 Python 脚本的路径:
 

java

private static final String PATH = "D:\\python\\hello.py";

方法一:使用 ProcessBuilder

ProcessBuilder 是 Java 提供的一个类,允许我们启动和管理操作系统进程。以下是使用 ProcessBuilder 调用 Python 脚本的步骤:

1. 编写测试方法

在 Spring Boot 应用中,我们可以编写一个测试方法来调用 Python 脚本:

 

java

@Test
public void testMethod1() throws IOException, InterruptedException {
    final ProcessBuilder processBuilder = new ProcessBuilder("python", PATH);
    processBuilder.redirectErrorStream(true);

    final Process process = processBuilder.start();

    final BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));

    String s = null;
    while ((s = in.readLine()) != null) {
        System.out.println(s);
    }

    final int exitCode = process.waitFor();
    System.out.println(exitCode == 0);
}

2. 解释代码

  • ProcessBuilder 构造函数接受要执行的命令和参数。这里,我们传递了 "python" 和脚本路径 PATH
  • redirectErrorStream(true) 将错误流和标准流合并,这样我们可以从同一个流中读取输出。
  • processBuilder.start() 启动进程。
  • 使用 BufferedReader 读取进程的输出。
  • process.waitFor() 等待进程结束,并返回退出代码。

方法二:使用 Apache Commons Exec

Apache Commons Exec 提供了一个更高级的 API 来执行外部进程。首先,我们需要在项目的 pom.xml 文件中添加依赖:

 

xml

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-exec</artifactId>
    <version>1.3</version>
</dependency>

1. 编写测试方法

使用 Apache Commons Exec 调用 Python 脚本的代码如下:

 

java

@Test
public void testMethod2() {
    final String line = "python " + PATH;
    final CommandLine cmdLine = CommandLine.parse(line);

    try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        final PumpStreamHandler streamHandler = new PumpStreamHandler(baos);

        final DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(streamHandler);

        final int exitCode = executor.execute(cmdLine);

        log.info("调用Python脚本的执行结果: {}.", exitCode == 0 ? "成功" : "失败");
        log.info(baos.toString().trim());
    } catch (final IOException e) {
        log.error("调用Python脚本出错", e);
    }
}

2. 解释代码

  • CommandLine.parse(line) 解析要执行的命令。
  • PumpStreamHandler 将输出流重定向到 ByteArrayOutputStream
  • DefaultExecutor 用于执行命令。
  • executor.execute(cmdLine) 执行命令并返回退出代码。
  • log.info 和 log.error 用于记录执行结果和错误。

Python 脚本的数据通过接口让 Spring Boot 接收。

Python 脚本作为服务

为了让 Spring Boot 能够接收 Python 脚本的数据,我们可以将 Python 脚本包装成一个 HTTP 服务。这样,Spring Boot 可以通过 HTTP 请求来调用 Python 脚本,并接收其返回的数据。以下是实现这一目标的步骤:

1. 使用 Flask 创建 Python HTTP 服务

首先,我们需要在 Python 脚本中添加 Flask 库来创建一个简单的 HTTP 服务。以下是修改后的 hello.py

 

python

from flask import Flask, jsonify
app = Flask(__name__)

@app.route('/hello', methods=['GET'])
def hello_world():
    return jsonify(message="Hello World!!")

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

这段代码创建了一个 Flask 应用,它在 5000 端口上运行,并定义了一个 /hello 路由,返回一个 JSON 响应。

2. 在 Spring Boot 中调用 Python HTTP 服务

现在,我们需要在 Spring Boot 应用中调用这个 Python HTTP 服务。我们可以使用 RestTemplateWebClient 来发送 HTTP 请求。

使用 RestTemplate

在 Spring Boot 中,你可以添加 RestTemplate 的依赖:

 

xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

然后,创建一个服务来调用 Python 服务:

 

java

import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class PythonService {
    private static final String PYTHON_SERVICE_URL = "http://localhost:5000/hello";

    public String callPythonService() {
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(PYTHON_SERVICE_URL, String.class);
        return result;
    }
}
使用 WebClient

如果你使用的是 Spring WebFlux,可以使用 WebClient

 

java

import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class PythonService {
    private static final String PYTHON_SERVICE_URL = "http://localhost:5000/hello";
    private final WebClient webClient;

    public PythonService(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl(PYTHON_SERVICE_URL).build();
    }

    public String callPythonService() {
        return webClient.get()
                .retrieve()
                .bodyToMono(String.class)
                .block();
    }
}

结论

通过将 Python 脚本包装成 HTTP 服务,我们可以更容易地在 Spring Boot 应用中调用 Python 脚本,并接收其返回的数据。这种方法不仅适用于 Python 脚本,还可以用于任何可以提供 HTTP 接口的外部服务。这样,Spring Boot 应用就可以通过标准的 HTTP 请求与这些服务进行交互,实现数据的集成和处理。

### 在 Spring Boot 中集成和调用 Python 脚本或服务 #### 使用 `ProcessBuilder` 方式 为了在 Spring Boot 应用程序中执行位于特定路径下的 Python 文件,可以采用 Java 的 `ProcessBuilder` 类来启动外部进程并传递参数给该 Python 程序。下面是一个简单的例子: ```java import java.io.BufferedReader; import java.io.InputStreamReader; public class PythonScriptExecutor { public void executePythonScript() throws Exception { ProcessBuilder pb = new ProcessBuilder("python", "D:\\python\\hello.py"); Process p = pb.start(); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); String s; while ((s = stdInput.readLine()) != null) { System.out.println(s); } } } ``` 此代码片段展示了如何通过指定完整的命令行指令(即 `"python"` 和脚本位置)创建一个新的 `ProcessBuilder` 实例,并启动它以运行 Python 脚本[^1]。 #### 利用 `Runtime.exec()` 方法 另一种方式是利用 `Runtime.getRuntime().exec()` 来实现相同的功能。这种方式更为简洁,但灵活性稍差一些。以下是具体的实现方法: ```java String command = "python D:\\demo1.py"; Process process = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } int exitCode = process.waitFor(); System.out.println("\nExited with error code : " + exitCode); ``` 这段代码同样实现了读取 Python 脚本的标准输出流并将结果显示出来[^2]。 #### 借助 Apache Commons Exec 工具库 对于更复杂的场景或者需要更好的错误处理机制的情况,则推荐使用第三方工具包如 Apache Commons Exec 。这可以通过 Maven POM 文件引入相应的依赖项完成配置: ```xml <dependencies> <!-- Other dependencies --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-exec</artifactId> <version>1.3</version> </dependency> </dependencies> ``` 之后就可以编写如下所示的服务类来进行 Python 脚本调用了: ```java import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.PumpStreamHandler; // ... CommandLine cmdLine = CommandLine.parse("python D:/path/to/your_script.py arg1 arg2..."); DefaultExecutor executor = new DefaultExecutor(); executor.setExitValue(0); // 设置期望退出状态码为 0 表示成功 PumpStreamHandler streamHandler = new PumpStreamHandler(System.out, System.err); executor.setStreamHandler(streamHandler ); try { int exitValue = executor.execute(cmdLine ); } catch (Exception e) { logger.error(e.getMessage(), e); } ``` 这种方法提供了更加丰富的 API 支持以及良好的异常捕获能力,适用于生产环境中的应用开发[^3]. #### 远程调用 Python 脚本 如果目标 Python 脚本部署于不同的机器上,那么就需要考虑 SSH 或者其他网络协议来进行远程过程调用(RPC)[^4]. 不过这种情况下通常会涉及到额外的安全性和性能优化方面的工作,在实际项目里应谨慎评估其必要性.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值