
嘻道奇闻
- 文章199742
- 阅读14625734
SpringBoot整合Python脚本的最佳实践,附完整Demo
浣犺姘斾笉姘斾汉锛熸槑鏄庣敤Python涓夎浠g爜灏辫兘鎼炲畾鐨勬暟鎹垎鏋愶紝闈炲緱鍦⊿pringBoot椤圭洰閲岄噸鍐橨ava鐗堛€傚埆褰撹繖绉嶅ぇ鍐ょ锛佷粖澶╁挶浠氨鐢ㄦ渶鎺ュ湴姘旂殑鏂瑰紡锛屾暀浣犫€?strong>鈥嬩笉閫犺疆瀛愮洿鎺ヨ皟鐢≒ython鑴氭湰鈥?/strong>鈥嬬殑缁濇椿锛岃繛鏂版墜閮借兘20鍒嗛挓涓婃墜锛屾枃鏈繕鍑嗗浜嗗紑绠卞嵆鐢ㄧ殑Demo锛?/p>
涓€銆佷负浠€涔堥潪瑕佹暣鍚圥ython锛熶妇涓牀瀛愷煂?/h3>
鍘诲勾鎴戜滑鍥㈤槦鎺ヤ簡涓渶姹傦細鐢↗ava澶勭悊鍥惧儚璇嗗埆銆傜粨鏋滅敤OpenCV鎶樿吘涓€鍛紝鍑嗙‘鐜囨墠68%銆傚悗鏉ユ崲鎴怭ython鐨凱addleOCR锛屼袱澶╁氨鎼炲埌92%鈥斺€旇繖宸窛灏卞儚鐢ㄧ畻鐩樺拰璁$畻鍣ㄦ瘮璧涳紒
鈥?strong>鈥嬩笁澶у繀椤绘暣鍚堢殑鍦烘櫙鈥?/strong>鈥嬶細
- 鏈哄櫒瀛︿範妯″瀷锛圱ensorFlow/PyTorch锛?/li>
- 绉戝璁$畻锛圢umpy/Pandas锛?/li>
- 鐗规湁鐢熸€侊紙姣斿鐖櫕妗嗘灦锛?/li>
浜屻€佷笁绉嶅Э鍔夸换鍚涢€夋嫨
濮垮娍1锛歊untime鐩存帴璋冪敤锛堥€傚悎灏忕櫧锛?/h4>
java澶嶅埗// 鏈€鍘熷浣嗘湁鏁堢殑鏂瑰紡
public String runPython(String param) throws IOException {
Process process = Runtime.getRuntime().exec(
new String[]{"python", "script.py", param}
);
// 閲嶇偣锛佸繀椤昏鍙栬緭鍑烘祦
return new BufferedReader(new InputStreamReader(process.getInputStream()))
.lines().collect(Collectors.joining("\n"));
}
// 鏈€鍘熷浣嗘湁鏁堢殑鏂瑰紡
public String runPython(String param) throws IOException {
Process process = Runtime.getRuntime().exec(
new String[]{"python", "script.py", param}
);
// 閲嶇偣锛佸繀椤昏鍙栬緭鍑烘祦
return new BufferedReader(new InputStreamReader(process.getInputStream()))
.lines().collect(Collectors.joining("\n"));
}
鈥?strong>鈥嬪潙鐐归璀︹€?/strong>鈥嬶細
- 璺緞闂锛氱粷瀵硅矾寰勬瘮鐩稿璺緞闈犺氨
- 缂栫爜闂锛歐indows榛樿GBK锛孡inux鏄疷TF-8
- 瓒呮椂鎺у埗锛氬埆璁㏄ython鑴氭湰鍗℃浣犵殑Java绾跨▼
濮垮娍2锛欽ython宓屽叆寮忔柟妗堬紙閫傚悎鑰侀」鐩級
xml澶嶅埗<dependency> <groupId>org.pythongroupId> <artifactId>jython-standaloneartifactId> <version>2.7.3version> dependency>
java澶嶅埗PythonInterpreter interpreter = new PythonInterpreter(); interpreter.exec("print('浣犲ソJython')"); // 鐩存帴鍐橮ython浠g爜
鈥?strong>鈥嬪姖閫€涓夎繛鈥?/strong>鈥嬶細
- 涓嶆敮鎸丳ython3锛堣繖骞村ご杩樻湁浜虹敤Python2锛燂級
- 绗笁鏂瑰簱鍏煎鎬у樊
- 鎬ц兘姣斿師鐢熷樊3鍊?/li>
濮垮娍3锛欻TTP鎺ュ彛閫氫俊锛堟帹鑽愭柊椤圭洰锛?/h4>
Python绔捣涓狥lask鏈嶅姟锛?/p>
python澶嶅埗from flask import Flask, request app = Flask(__name__) @app.route('/predict', methods=['POST']) def predict(): data = request.json['input_data'] return {'result': f"澶勭悊鍚庣殑鏁版嵁: {data.upper()}"}
Java绔敤RestTemplate璋冪敤锛?/p>
java澶嶅埗public String callPythonService(String input) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); Map
body = new HashMap<>(); body.put("input_data", input); return restTemplate.postForObject( "http://localhost:5000/predict", new HttpEntity<>(body, headers), String.class ); }
鈥?strong>鈥嬩紭鍔垮姣旇〃鈥?/strong>鈥嬶細
鎸囨爣 | Runtime鏂规 | HTTP鏂规 |
---|---|---|
璺ㄧ増鏈?/td> | 鉂?/td> | 鉁?/td> |
浼犺緭鏁堢巼 | 猸愨瓙猸?/td> | 猸愨瓙 |
缁存姢鎴愭湰 | 猸?/td> | 猸愨瓙猸?/td> |
閿欒鎺掓煡闅惧害 | 鍦扮嫳绾?/td> | 鏅€氭ā寮?/td> |
涓夈€佸弬鏁颁紶閫掔殑涓夊ぇ绾緥鍏」娉ㄦ剰
鈥?strong>鈥嬭杩囨渶绂昏氨鐨刡ug鈥?/strong>鈥嬶細Java浼?1,2,3"缁橮ython锛孭ython鐢╯plit(',')澶勭悊鈥斺€旂粨鏋滅敤鎴蜂紶浜嗕釜"浣犲ソ锛屼笘鐣?鐩存帴宕╀簡锛?/p>
鈥?strong>鈥嬪畨鍏ㄤ紶杈撳洓姝ヨ蛋鈥?/strong>鈥嬶細
- Java绔敤URLEncoder缂栫爜
- JSON鏍煎紡浼犲鏉傚璞?/li>
- Python绔敤try-except鍖呰9
- 閲嶈鏁版嵁璧癇ase64
java澶嶅埗// Java缂栫爜绀轰緥 String safeParam = Base64.getEncoder() .encodeToString(JSON.toJSONString(paramObj).getBytes());
python澶嶅埗# Python瑙g爜绀轰緥 import base64, json param_str = base64.b64decode(safe_param).decode('utf-8') param_obj = json.loads(param_str)
鍥涖€佷緷璧栫鐞嗙殑姝g‘鎵撳紑鏂瑰紡
瑙佽繃鏈変汉鎶奝ython鐜鎵撳寘杩汥ocker闀滃儚锛岀粨鏋滈暅鍍忎綋绉毚娑?G锛佹纭殑濮垮娍搴旇鏄細
- 鐢╮equirements.txt閿佸畾鐗堟湰
- 鍦―ockerfile閲屽垎灞傚畨瑁?/li>
- Java椤圭洰閫氳繃閰嶇疆璇诲彇Python璺緞
dockerfile澶嶅埗# 鍩虹闀滃儚灞?/span> FROM python:3.9-slim AS py-base COPY requirements.txt . RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # Java搴旂敤灞?/span> FROM openjdk:11-jdk COPY --from=py-base /usr/local/lib/python3.9/site-packages /py-libs ENV PYTHONPATH=/py-libs
浜斻€佸畬鏁碊emo鎵嬫妸鎵嬫暀瀛?/h3>
鈥?strong>鈥嬪満鏅€?/strong>鈥嬶細鐢≒ython鐨刯ieba搴撳仛涓枃鍒嗚瘝锛孲pringBoot鎻愪緵API鎺ュ彛
Python鏈嶅姟绔紙seg.py锛?
python澶嶅埗from flask import Flask, request import jieba app = Flask(__name__) @app.route('/segment', methods=['POST']) def segment(): text = request.json.get('text', '') return {'words': list(jieba.cut(text))}
Java璋冪敤绔細
java澶嶅埗@RestController public class SegmentController { @Autowired private RestTemplate restTemplate; @PostMapping("/segment") public List
segment(@RequestBody Map param) { String url = "http://localhost:5000/segment"; return restTemplate.postForObject(url, param, Map.class) .get("words"); } }
鈥?strong>鈥嬪惎鍔ㄩ『搴忊€?/strong>鈥嬶細
- 鍏堣捣Python鏈嶅姟锛歠lask run --port=5000
- 鍐嶅惎鍔⊿pringBoot搴旂敤
- 娴嬭瘯鎺ュ彛锛歝url -X POST http://localhost:8080/segment -H "Content-Type: application/json" -d '{"text":"浠婂ぉ鐨勫ぉ姘旂湡涓嶉敊"}'
鍏€佹€ц兘浼樺寲鍐风煡璇?/h3>
瀹炴祴鍙戠幇锛氬綋QPS瓒呰繃50鏃讹紝Runtime鏂规鐩存帴宕╋紝鑰孒TTP鏂规杩樿兘鎾戝埌120銆備笉杩囪繖鏃跺€欏氨璇ヤ笂鈥?strong>鈥媑RPC鈥?/strong>鈥嬩簡鈥斺€旂敤Protobuf搴忓垪鍖栬兘姣擩SON蹇?鍊嶏紝浣嗕粖澶╁挶浠厛涓嶅睍寮€璇淬€?/p>
鏈€鍚庤涓湡鐩革細寰堝鍥㈤槦涓轰簡"鎶€鏈粺涓€"寮虹敤Java閲嶅啓Python浠g爜锛岀粨鏋滈」鐩欢鏈熶笁涓湀銆傝鎴戣锛屸€?strong>鈥嬬敤鍚堥€傜殑宸ュ叿鍋氬悎閫傜殑浜嬧€?/strong>鈥嬫墠鏄湡鏈簨锛屼綘浠瀵瑰惂锛?/p>