最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java調(diào)用Python服務(wù)的三種實(shí)現(xiàn)過(guò)程

 更新時(shí)間:2025年10月13日 09:27:17   作者:A塵埃  
這篇文章主要介紹了Java調(diào)用Python服務(wù)的三種實(shí)現(xiàn)過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Java調(diào)用Python服務(wù)過(guò)程

在Java中調(diào)用Python服務(wù)是一種非常常見(jiàn)的需求,尤其是在利用Python強(qiáng)大的機(jī)器學(xué)習(xí)/數(shù)據(jù)科學(xué)庫(kù),或者復(fù)用現(xiàn)有Python代碼時(shí)。

根據(jù)不同的應(yīng)用場(chǎng)景,有幾種主流的方法。

方法適用場(chǎng)景優(yōu)點(diǎn)缺點(diǎn)
REST API絕大多數(shù)生產(chǎn)環(huán)境,尤其是微服務(wù)架構(gòu)解耦、伸縮性好、語(yǔ)言無(wú)關(guān)、生態(tài)豐富有網(wǎng)絡(luò)延遲、需編寫接口代碼
ProcessBuilder簡(jiǎn)單的、調(diào)用不頻繁的腳本任務(wù),快速原型實(shí)現(xiàn)簡(jiǎn)單、無(wú)需額外服務(wù)性能開(kāi)銷大、進(jìn)程管理復(fù)雜、交互麻煩
Jython遺留系統(tǒng)(Python 2.7),且無(wú)需第三方C庫(kù)無(wú)進(jìn)程開(kāi)銷、直接交互僅支持Python 2.7、無(wú)法使用主流科算庫(kù)

方法一:通過(guò) REST API 調(diào)用(最常用、最推薦)

將Python代碼包裝成一個(gè)HTTP服務(wù)器(例如使用Flask或FastAPI),然后Java程序通過(guò)HTTP客戶端(例如Spring的RestTemplate或OkHttp)像調(diào)用其他任何RESTful服務(wù)一樣來(lái)調(diào)用它。

①、創(chuàng)建 Python 服務(wù)端 (Flask)

首先,確保安裝了Flask:pip install flask

創(chuàng)建一個(gè)名為 python_server.py 的文件:

from flask import Flask,request,jsonify
import math

app = Flask(__name__)

#定義一個(gè)簡(jiǎn)單的API端點(diǎn),計(jì)算平方根
@app.route('/calculate',methods=['POST'])
def calculate():
	data = request.get_json()
	number = data['number']
	result = math.sqrt(number)
	return jsonify({'result': result, 'python_version': '計(jì)算完成'})

#文本處理
@app.route('/process_text', methods=['POST'])
def process_text():
    data = request.get_json()
    text = data['text']
    processed_text = text.upper() + " - Processed by Python"
    return jsonify({'processed_text': processed_text})

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

運(yùn)行這個(gè)Python腳本:python python_server.py。現(xiàn)在Python服務(wù)就在本地的5000端口運(yùn)行了。

②、創(chuàng)建java客戶端

使用Spring Boot的RestTemplate(傳統(tǒng)方式)和新的WebClient(響應(yīng)式)作為示例。

使用 RestTemplate (Spring Boot 2.x)

首先,pom.xml中確保有Spring Web依賴。

public class PythonServiceClient {

    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        String pythonServiceUrl = "http://localhost:5000/calculate";

        // 準(zhǔn)備請(qǐng)求數(shù)據(jù)
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("number", 9.0);

        // 發(fā)送POST請(qǐng)求并獲取響應(yīng)
        ResponseEntity<Map> response = restTemplate.postForEntity(
                pythonServiceUrl,
                requestMap,
                Map.class
        );

        // 處理響應(yīng)
        if (response.getStatusCode().is2xxSuccessful()) {
            Map<String, Object> responseBody = response.getBody();
            System.out.println("計(jì)算結(jié)果: " + responseBody.get("result"));
            System.out.println("信息: " + responseBody.get("python_version"));
        } else {
            System.out.println("請(qǐng)求失敗: " + response.getStatusCode());
        }
    }
}

使用 WebClient (Spring 5+ 響應(yīng)式)

首先,在pom.xml中添加Spring WebFlux依賴。

public class PythonServiceWebClient {

    public static void main(String[] args) throws InterruptedException {
        WebClient webClient = WebClient.create("http://localhost:5000");

        Mono<Map> responseMono = webClient.post()
                .uri("/process_text")
                .bodyValue(Collections.singletonMap("text", "hello from java"))
                .retrieve()
                .bodyToMono(Map.class);

        // 異步非阻塞地獲取結(jié)果
        responseMono.subscribe(response -> {
            System.out.println("處理后的文本: " + response.get("processed_text"));
        });

        // 等待異步操作完成(實(shí)際生產(chǎn)環(huán)境中不需要這樣)
        Thread.sleep(1000);
    }
}

方法二:使用 ProcessBuilder 直接調(diào)用Python腳本

這種方法直接在Java中啟動(dòng)一個(gè)操作系統(tǒng)進(jìn)程來(lái)運(yùn)行Python解釋器并執(zhí)行指定的腳本。Java通過(guò)進(jìn)程的輸入輸出流與Python腳本交換數(shù)據(jù)。

①、創(chuàng)建 Python 腳本 (math_utils.py)

# 這是一個(gè)簡(jiǎn)單的Python腳本,從標(biāo)準(zhǔn)輸入讀取JSON,計(jì)算后輸出JSON
import sys
import json
import math

def main():
    # 從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)
    data = sys.stdin.read()
    try:
        request_data = json.loads(data)
        number = request_data['number']
        # 執(zhí)行計(jì)算
        result = math.sqrt(number)
        # 輸出結(jié)果到標(biāo)準(zhǔn)輸出
        print(json.dumps({
            "result": result,
            "status": "success"
        }))
    except Exception as e:
        print(json.dumps({
            "status": "error",
            "message": str(e)
        }))

if __name__ == "__main__":
    main()

②、Java 代碼調(diào)用該腳本

public class ProcessBuilderExample {

    public static void main(String[] args) throws IOException, InterruptedException {
        // 1. 定義Python解釋器和腳本路徑
        String pythonInterpreter = "python3"; // 或 "python",取決于系統(tǒng)
        String pythonScriptPath = "/path/to/your/math_utils.py"; // 替換為你的腳本絕對(duì)路徑

        // 2. 構(gòu)建命令
        ProcessBuilder processBuilder = new ProcessBuilder(
                pythonInterpreter,
                "-u", // 強(qiáng)制標(biāo)準(zhǔn)輸出和錯(cuò)誤無(wú)緩沖,很重要!
                pythonScriptPath
        );
        processBuilder.redirectErrorStream(true); // 將錯(cuò)誤流合并到輸入流

        // 3. 啟動(dòng)進(jìn)程
        Process process = processBuilder.start();

        // 4. 準(zhǔn)備輸入數(shù)據(jù)并通過(guò)輸出流發(fā)送給Python腳本
        Map<String, Object> inputData = new HashMap<>();
        inputData.put("number", 16.0);
        String jsonInput = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(inputData); // 可以使用任何JSON庫(kù)

        try (BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8))) {
            writer.write(jsonInput);
            writer.flush();
        }

        // 5. 讀取Python腳本的輸出
        StringBuilder output = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line);
            }
        }

        // 6. 等待進(jìn)程結(jié)束并獲取返回值
        int exitCode = process.waitFor();
        if (exitCode == 0) {
            // 解析Python腳本的輸出
            Map<String, Object> result = new com.fasterxml.jackson.databind.ObjectMapper().readValue(
                    output.toString(), Map.class);
            System.out.println("成功: " + result.get("result"));
        } else {
            System.err.println("Python腳本執(zhí)行錯(cuò)誤: ");
            System.err.println(output);
        }
    }
}

方法三:使用 Jython(不推薦用于新項(xiàng)目)

Jython是一個(gè)JVM實(shí)現(xiàn),可以直接在JVM上運(yùn)行Python代碼,并允許Java和Python對(duì)象直接交互。

只支持Python 2.7,無(wú)法使用基于C的Python庫(kù)(如NumPy, Pandas, TensorFlow, PyTorch等),項(xiàng)目活躍度低。

①、將Jython的jar包(如jython-standalone-2.7.3.jar)添加到項(xiàng)目的classpath中。

②、Java代碼

public class JythonExample {
    public static void main(String[] args) {
        try (PythonInterpreter pyInterp = new PythonInterpreter()) {
            // 執(zhí)行簡(jiǎn)單的Python語(yǔ)句
            pyInterp.exec("print('Hello from Jython!)");
            pyInterp.exec("import math");

            // 在Python中設(shè)置變量,在Java中獲取
            pyInterp.set("a", 10);
            pyInterp.exec("b = math.sqrt(a)");
            Number b = (Number) pyInterp.get("b");
            System.out.println("Square root of 10 from Jython: " + b);
        }
    }
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 談?wù)?Java 中 this 的使用方法

    談?wù)?Java 中 this 的使用方法

    這篇文章主要介紹了Java 中 this 的使用方法,需要的朋友可以參考下
    2014-01-01
  • Java的無(wú)參構(gòu)造函數(shù)用法實(shí)例分析

    Java的無(wú)參構(gòu)造函數(shù)用法實(shí)例分析

    這篇文章主要介紹了Java的無(wú)參構(gòu)造函數(shù)用法,結(jié)合實(shí)例形式分析了java無(wú)參構(gòu)造函數(shù)基本原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Spring Cache實(shí)現(xiàn)緩存技術(shù)

    Spring Cache實(shí)現(xiàn)緩存技術(shù)

    在面對(duì)公司緩存技術(shù)混亂時(shí),張三基于Spring框架自研緩存解決方案,展現(xiàn)了他的專業(yè)技術(shù)能力和積極工作態(tài)度,他通過(guò)問(wèn)題診斷、技術(shù)選型、編碼測(cè)試、文檔編寫和部署監(jiān)控等一系列步驟,確保了新緩存系統(tǒng)的功能正確性和性能穩(wěn)定性
    2024-10-10
  • Java調(diào)用Shell命令和腳本的實(shí)現(xiàn)

    Java調(diào)用Shell命令和腳本的實(shí)現(xiàn)

    這篇文章主要介紹了Java調(diào)用Shell命令和腳本的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • java設(shè)計(jì)模式之工廠模式詳解

    java設(shè)計(jì)模式之工廠模式詳解

    本文介紹了三種常見(jiàn)的設(shè)計(jì)模式:簡(jiǎn)單廠模式、工廠方法模式和抽象工廠模式,簡(jiǎn)單廠模式通過(guò)一個(gè)工廠類來(lái)生產(chǎn)不同的產(chǎn)品實(shí)例,例如同時(shí)生產(chǎn)華為和小米手機(jī),工廠方法模式則通過(guò)定義一個(gè)創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類
    2024-11-11
  • Java 如何使用@Autowired注解自動(dòng)注入bean

    Java 如何使用@Autowired注解自動(dòng)注入bean

    這篇文章主要介紹了Java 使用@Autowired注解自動(dòng)注入bean的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java 八種基本類型和基本類型封裝類

    Java 八種基本類型和基本類型封裝類

    八種基本數(shù)據(jù)類型分別是:int、short、float、double、long、boolean、byte、char;下面跟隨腳本之家小編一起學(xué)習(xí)java八種基本類型和基本類型封裝類
    2017-09-09
  • 淺談SpringBoot是如何實(shí)現(xiàn)日志的

    淺談SpringBoot是如何實(shí)現(xiàn)日志的

    這篇文章主要介紹了淺談SpringBoot是如何實(shí)現(xiàn)日志的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • PipedWriter和PipedReader源碼分析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    PipedWriter和PipedReader源碼分析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了PipedWriter和PipedReader源碼分析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下
    2017-05-05
  • Netty分布式高性能工具類同線程下回收對(duì)象解析

    Netty分布式高性能工具類同線程下回收對(duì)象解析

    這篇文章主要為大家介紹了Netty分布式高性能工具類同線程下回收對(duì)象解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03

最新評(píng)論

浦北县| 巍山| 广德县| 潞城市| 安平县| 迭部县| 财经| 牙克石市| 大关县| 舒城县| 浏阳市| 雷山县| 辛集市| 忻城县| 乌鲁木齐县| 塔河县| 龙岩市| 岐山县| 永济市| 永丰县| 伊金霍洛旗| 漯河市| 湖北省| 丘北县| 昌吉市| 辽宁省| 基隆市| 沙田区| 资兴市| 崇州市| 鹤岗市| 长葛市| 蓬莱市| 秀山| 阳信县| 花垣县| 绥化市| 靖远县| 晋宁县| 卢氏县| 通江县|