欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java調(diào)用Python腳本實現(xiàn)HelloWorld的示例詳解

 更新時間:2025年08月17日 08:57:47   作者:程序員丘山  
作為程序員,我們經(jīng)常會遇到需要在Java項目中調(diào)用Python腳本的場景,下面我們來看看如何從基礎到進階,一步步實現(xiàn)Java與Python的"HelloWorld"交互吧

作為程序員,我們經(jīng)常會遇到需要在Java項目中調(diào)用Python腳本的場景??赡苁菫榱藦陀矛F(xiàn)成的Python工具庫,也可能是需要利用Python在數(shù)據(jù)處理上的優(yōu)勢。本文不聊太多理論,直接上手三種實用的調(diào)用方式,從基礎到進階,一步步實現(xiàn)Java與Python的"HelloWorld"交互。

一、環(huán)境準備

在開始之前,確保你的開發(fā)環(huán)境滿足以下條件:

  • Java環(huán)境:JDK 8+(推薦11),配置好JAVA_HOME
  • Python環(huán)境:Python 3.6+,配置好PATH(命令行輸入python --version能正常顯示版本)
  • 開發(fā)工具:任意IDE,文本編輯器(用于寫Python腳本)

驗證環(huán)境的小技巧:

# 檢查Java
java -version
# 檢查Python
python --version  # 或python3 --version(根據(jù)系統(tǒng)配置)

如果Python命令無法識別,大概率是沒配置環(huán)境變量。Windows用戶可以在"設置-系統(tǒng)-關于-高級系統(tǒng)設置-環(huán)境變量"中添加Python安裝路徑;Linux/Mac用戶可以在~/.bashrc~/.zshrc中添加export PATH=$PATH:/usr/local/python3/bin(替換為實際路徑)。

二、基礎調(diào)用:使用 Runtime.exec()

這是最直接的調(diào)用方式,通過Java的Runtime類啟動Python進程執(zhí)行腳本。適合簡單場景,無需復雜交互。

2.1 實現(xiàn)步驟

步驟1:編寫Python腳本

創(chuàng)建hello.py,放在Java項目的根目錄(或指定絕對路徑):

# 接收Java傳遞的參數(shù)
import sys

if __name__ == "__main__":
    # 獲取Java傳入的參數(shù)(第0個參數(shù)是腳本名)
    name = sys.argv[1] if len(sys.argv) > 1 else "World"
    # 輸出結(jié)果(會被Java捕獲)
    print(f"Hello, {name}! From Python")

步驟2:編寫Java調(diào)用代碼

創(chuàng)建JavaCallPythonByRuntime.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class JavaCallPythonByRuntime {
    public static void main(String[] args) {
        // 1. 定義Python腳本路徑和參數(shù)
        String pythonScriptPath = "hello.py";
        String param = "Java";  // 要傳遞給Python的參數(shù)

        // 2. 構建命令數(shù)組(推薦用數(shù)組形式,避免空格問題)
        String[] cmd = new String[]{"python", pythonScriptPath, param};

        try {
            // 3. 啟動Python進程
            Process process = Runtime.getRuntime().exec(cmd);

            // 4. 讀取Python的輸出(必須讀取,否則可能導致進程阻塞)
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, "UTF-8")  // 指定編碼,避免中文亂碼
            );
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("Python輸出:" + line);
            }

            // 5. 等待進程執(zhí)行完成并獲取退出碼(0表示成功)
            int exitCode = process.waitFor();
            System.out.println("進程退出碼:" + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.2 代碼解析

  • 命令數(shù)組:用String[]而不是單字符串,避免路徑或參數(shù)包含空格時解析錯誤(比如腳本路徑是D:\my script\hello.py)。
  • 輸入流處理:Python的print輸出會寫入進程的輸入流,Java必須讀取這些內(nèi)容,否則緩沖區(qū)滿了會導致進程卡住。
  • 編碼設置InputStreamReader指定UTF-8,解決Windows系統(tǒng)下默認GBK編碼導致的中文亂碼問題。
  • 退出碼process.waitFor()返回的退出碼能幫我們判斷腳本是否正常執(zhí)行(非0通常表示出錯)。

三、進階調(diào)用:使用 ProcessBuilder

ProcessBuilder是JDK 5引入的類,比Runtime.exec()更靈活,支持設置工作目錄、環(huán)境變量等,適合復雜場景。

3.1 實現(xiàn)步驟

步驟1:復用Python腳本

繼續(xù)使用前面的hello.py,稍作修改支持從環(huán)境變量讀取配置:

import sys
import os

if __name__ == "__main__":
    name = sys.argv[1] if len(sys.argv) > 1 else "World"
    # 讀取Java設置的環(huán)境變量
    app_name = os.getenv("APP_NAME", "UnknownApp")
    print(f"[{app_name}] Hello, {name}! From Python")

步驟2:編寫Java代碼

創(chuàng)建JavaCallPythonByProcessBuilder.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

public class JavaCallPythonByProcessBuilder {
    public static void main(String[] args) {
        try {
            // 1. 創(chuàng)建ProcessBuilder,指定命令和參數(shù)
            ProcessBuilder pb = new ProcessBuilder(
                "python", "hello.py", "JavaDeveloper"
            );

            // 2. 設置工作目錄(腳本所在目錄,不設置則默認當前目錄)
            pb.directory(new java.io.File("./scripts"));  // 假設腳本放在scripts子目錄

            // 3. 設置環(huán)境變量(給Python腳本傳遞配置)
            Map<String, String> env = pb.environment();
            env.put("APP_NAME", "JavaCallPythonDemo");

            // 4. 重定向錯誤流到輸入流(方便統(tǒng)一處理輸出和錯誤)
            pb.redirectErrorStream(true);

            // 5. 啟動進程
            Process process = pb.start();

            // 6. 讀取輸出
            try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream(), "UTF-8")
            )) {
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println("Python輸出:" + line);
                }
            }

            // 7. 等待進程完成
            int exitCode = process.waitFor();
            System.out.println("進程退出碼:" + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.2 代碼解析

  • 工作目錄pb.directory()指定腳本所在目錄,避免路徑混亂。比如腳本放在./scripts,就不用寫全路徑了。
  • 環(huán)境變量:通過pb.environment()設置的變量,Python可以用os.getenv()獲取,適合傳遞配置信息(如API密鑰、環(huán)境標識)。
  • 錯誤流重定向redirectErrorStream(true)將錯誤信息合并到輸入流,不用單獨處理getErrorStream(),簡化代碼。
  • 資源自動關閉try-with-resources語法確保BufferedReader自動關閉,避免資源泄漏。

四、服務化調(diào)用:HTTP接口通信

當Java和Python需要頻繁交互,或需要跨服務器調(diào)用時,將Python腳本封裝成HTTP服務是更優(yōu)的方案。這里用Flask搭建簡單接口。

4.1 實現(xiàn)步驟

步驟1:搭建Python HTTP服務

首先安裝Flask:

pip install flask

創(chuàng)建hello_service.py

from flask import Flask, request

app = Flask(__name__)

@app.route('/hello', methods=['GET'])
def hello():
    # 從請求參數(shù)獲取name
    name = request.args.get('name', 'World')
    return f"Hello, {name}! From Python Service"

if __name__ == '__main__':
    # 啟動服務,允許外部訪問
    app.run(host='0.0.0.0', port=5000, debug=True)

步驟2:編寫Java HTTP客戶端

創(chuàng)建JavaCallPythonByHttp.java,使用JDK自帶的HttpClient(JDK 11+):

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class JavaCallPythonByHttp {
    public static void main(String[] args) {
        // 1. 創(chuàng)建HttpClient
        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(5))
                .build();

        // 2. 構建請求(Python服務地址)
        String name = "JavaHttpClient";
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:5000/hello?name=" + name))
                .timeout(Duration.ofSeconds(3))
                .GET()
                .build();

        try {
            // 3. 發(fā)送請求并獲取響應
            HttpResponse<String> response = client.send(
                request, HttpResponse.BodyHandlers.ofString()
            );

            // 4. 處理響應
            if (response.statusCode() == 200) {
                System.out.println("Python服務響應:" + response.body());
            } else {
                System.err.println("請求失敗,狀態(tài)碼:" + response.statusCode());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.2 代碼解析

  • Python服務:用Flask創(chuàng)建/hello接口,通過request.args獲取Java傳遞的參數(shù),返回字符串。debug=True方便開發(fā)時自動重啟。
  • Java客戶端:JDK 11的HttpClient比傳統(tǒng)的HttpURLConnection更簡潔,支持異步調(diào)用(sendAsync),這里用同步send更直觀。
  • 跨機器調(diào)用:只要Python服務的host設為0.0.0.0,并開放5000端口,Java可以通過服務器IP訪問(如http://192.168.1.100:5000/hello)。

五、三種方法對比與選擇建議

調(diào)用方式優(yōu)點缺點適用場景
Runtime.exec()簡單直接,無需額外依賴靈活性差,不便于設置環(huán)境和工作目錄簡單腳本,一次性調(diào)用
ProcessBuilder支持環(huán)境變量、工作目錄,錯誤流合并代碼稍復雜,仍需處理進程通信復雜腳本,需要傳遞配置信息
HTTP接口松耦合,支持跨機器,可異步需要維護HTTP服務,有網(wǎng)絡開銷頻繁交互,分布式系統(tǒng),跨語言調(diào)用

實際開發(fā)中:

  • 臨時腳本調(diào)用用ProcessBuilder;
  • 長期維護的功能推薦HTTP服務化,便于獨立部署和升級;
  • 避免在高并發(fā)場景用進程調(diào)用(頻繁創(chuàng)建銷毀進程開銷大)。

六、避坑指南

1.路徑中的空格:Windows路徑如果有空格(如Program Files),用ProcessBuilder時會自動處理,但用Runtime.exec()單字符串命令可能出錯,推薦始終用數(shù)組形式傳參。

2.Python輸出緩沖區(qū):如果Python腳本輸出大量內(nèi)容,會先存到緩沖區(qū),Java讀取不及時會導致腳本卡住。解決方法:

  • Python中手動刷新緩沖區(qū):print(..., flush=True)
  • Java中用線程異步讀取輸出

3.版本兼容:確保Java調(diào)用的Python版本和開發(fā)時一致(比如同時用Python 3.9),避免語法不兼容問題。

4.異常捕獲:生產(chǎn)環(huán)境中必須捕獲所有可能的異常(IOException、InterruptedException等),并記錄日志,方便排查問題。

總結(jié)

本文介紹了三種Java調(diào)用Python腳本實現(xiàn)HelloWorld的方法,從簡單的進程調(diào)用到服務化通信,覆蓋了不同場景的需求。核心是根據(jù)項目實際情況選擇合適的方案:簡單場景用ProcessBuilder,分布式場景用HTTP接口。

實際開發(fā)中,建議先做小范圍測試,重點關注參數(shù)傳遞、異常處理和性能表現(xiàn)。只要把這些細節(jié)處理好,Java和Python的協(xié)作會非常順暢。

到此這篇關于Java調(diào)用Python腳本實現(xiàn)HelloWorld的示例詳解的文章就介紹到這了,更多相關Java調(diào)用Python腳本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java實現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法

    Java實現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法

    這篇文章主要介紹了Java實現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法,方法通過實例代碼給大家介紹的非常詳細,選擇使用哪種格式通常取決于項目的需求和上下文,所以格式轉(zhuǎn)換就成了我們必備的技能,具體實現(xiàn)代碼跟隨小編一起看看吧
    2023-10-10
  • JavaWeb搭建網(wǎng)上圖書商城畢業(yè)設計

    JavaWeb搭建網(wǎng)上圖書商城畢業(yè)設計

    這篇文章主要介紹了JavaWeb搭建網(wǎng)上圖書商城框架,特別適合正在為網(wǎng)上商城畢業(yè)設計煩惱的同學,需要的朋友可以參考下
    2015-11-11
  • Java中的Phaser使用詳解

    Java中的Phaser使用詳解

    這篇文章主要介紹了Java中的Phaser使用詳解,與其他障礙不同,注冊在phaser上進行同步的parties數(shù)量可能會隨時間變化,任務可以隨時進行注冊,需要的朋友可以參考下
    2023-11-11
  • Eclipse將Maven項目打成jar包的方法

    Eclipse將Maven項目打成jar包的方法

    這篇文章主要介紹了Eclipse將Maven項目打成jar包的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2007-09-09
  • Java實現(xiàn)蘿卜勇者游戲的示例代碼

    Java實現(xiàn)蘿卜勇者游戲的示例代碼

    《蘿卜勇者》是由國內(nèi)玩家自制的一款獨立游戲,玩家扮演蘿卜勇士闖關,打敗各種邪惡的敵人,獲得最后的勝利。本文將利用Java實現(xiàn)這一游戲,感興趣的可以了解一下
    2022-02-02
  • Java?將PDF轉(zhuǎn)為HTML時保存到流的方法和步驟

    Java?將PDF轉(zhuǎn)為HTML時保存到流的方法和步驟

    本文介紹如何通過Java后端程序代碼將PDF文件轉(zhuǎn)為HTML,并將轉(zhuǎn)換后的HTML文件保存到流,下面是實現(xiàn)轉(zhuǎn)換的方法和步驟,感興趣的朋友一起看看吧
    2022-01-01
  • springboot項目啟動的時候參數(shù)無效的解決

    springboot項目啟動的時候參數(shù)無效的解決

    這篇文章主要介紹了springboot項目啟動的時候參數(shù)無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java.lang.IllegalStateException異常原因和解決辦法

    java.lang.IllegalStateException異常原因和解決辦法

    這篇文章主要給大家介紹了關于java.lang.IllegalStateException異常原因和解決辦法,IllegalStateException是Java標準庫中的一個異常類,通常表示在不合適或無效的情況下執(zhí)行了某個方法或操作,需要的朋友可以參考下
    2023-07-07
  • 永中文檔在線轉(zhuǎn)換服務Swagger調(diào)用說明

    永中文檔在線轉(zhuǎn)換服務Swagger調(diào)用說明

    這篇文章主要為大家介紹了永中文檔在線轉(zhuǎn)換服務Swagger調(diào)用說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 解決若依微服務框架啟動報錯的問題

    解決若依微服務框架啟動報錯的問題

    Invalid bound statement錯誤通常由MyBatis映射文件未正確加載或Nacos配置未讀取導致,需檢查XML的namespace與方法ID是否匹配,確認資源目錄配置,確保bootstrap.yml中Nacos配置路徑正確加載
    2025-08-08

最新評論