原由:本人不會Java代碼,可是想在jmeter(純Java語言)中去調用python腳本,來達到個人目的。因而開啓了一個漫長的新知識探索。過程崎嶇,在小巷子裏繞了很久。均告失敗!!!!html
1、開始各類百度找思路,最終大概流程就是這個樣子的(如下全部操做均在window下進行)。java
一、下載所需文件(包含JDK、Java編輯器、Python編輯器、Python3.六、jython-standalone-2.7.1.jar);python
二、安裝並配置JDK環境變量(本人所用爲版本爲:JDK 64位 1.8.0_211);編程
三、安裝並配置Python環境(本人所用爲:Python3.六、2.7版);eclipse
四、安裝Java編輯器(本人所用爲:Eclipse);編輯器
五、安裝Python編輯器(本人所用爲:PyCharm);函數式編程
六、配置jython環境變量;函數
七、編寫Python測試腳本;測試
八、新建Java項目;編碼
九、Java項目加載jython-standalone-2.7.1.jar包;
十、編寫Java測試腳本;
十一、調試;
2、接下來就讓咱們一塊兒來踩坑、填坑吧,吼吼吼~
一、下載所需文件,其中JDK、jython-standalone-2.7.1.jar、Eclipse、PyCharm 已提供下載地址:
連接:https://pan.baidu.com/s/1TQvm0uxxYFXa_ICck86-hg
提取碼:812d
二、配置JDK環境變量(自行百度解決)
三、安裝並配置Python環境
1)、下載Python;去官網—> https://www.python.org/downloads/release/python-374/
2)、安裝並配置環境;去這裏—> https://jingyan.baidu.com/article/c45ad29c05c208051653e270.html
四、安裝Java編輯器Eclipse
1)、將下載好的壓縮包進行解壓 (免安裝),點擊 eclipse.exe文件啓動編輯器便可;
五、安裝Python編輯器;(自行百度解決)
六、配置jython環境變量;
1)、做用:Jython的主要通途就是在Java中調用Python程序;並且,還能夠直接在Jython程序中引用Java。就是一座橋,鏈接他和它。
2)、配置:實際上是有兩個不一樣的文件
jython_installer-2.5.2.jar:須要安裝和配置環境變量的,多用於使用Java的Runtime()函數調用時。
jython-standalone-2.7.1.jar:免安裝,須要配置環境變量,經過Jython的API進行調用。可以指定到具體的函數和方法。
本人採用的是第二種。配置環境變量,即將 jython-standalone-2.7.1.jar 所在的目錄(D:\java_test\lib\jython-standalone-2.7.1.jar)添加到系統環境變量的CLASSPATH中。
(沒有這一步會報錯:java.io.IOException: Cannot run program "python": CreateProcess error=2, 系統找不到指定的文件。)
七、編寫Python測試腳本,以下:
a = [1,2,3,4,5,6,7] b = a[:] print(b)
八、新建Java項目
1)、新建一個項目文件夾 java_test,在文件件中新建一個lib文件夾,將jython-standalone-2.7.1.jar複製到lib文件中;
2)、打開Eclipse,依次新建Java項目、填寫項目名稱。(Contents中選擇Create project from existing source ,位置選擇java_test文件夾),保存;
3)、選擇項目下的src文件後右鍵新建包,填寫包名稱,保存;
4)、選擇新建的包右鍵新建類,填寫類名稱,保存;
九、Java項目加載jython-standalone-2.7.1.jar包
1)、選擇新建的Java項目,右鍵後依次選擇 「構建路徑---->配置構建路徑---->L庫---->添加JAR--->找到lib文件夾中的jython-standalone-2.7.1.jar文件;
2)、在java_test文件夾中新建一個放Python腳本的文件Script文件夾;
此時能夠看到的文件目錄結構以下:
其中bin、src文件夾、.classpath、.project是在建立Java項目時自動建立,bin是用來存放Java項目目錄、src存放類目錄,lib文件夾是手動添加的存放須要導入的jar文件目錄,Script文件夾是手動添加的存放須要用的Python文件目錄;
十、編寫Java測試腳本
1)、在Java中簡單調用Python程序,不須要傳遞參數,也不須要獲取返回值,簡單版的先測試一下有沒有問題;
Java測試代碼以下:
package java_Test; import java.io.IOException; import org.python.util.PythonInterpreter;
public class TestIng { /** * @param args * @throws IOException * @throws InterruptedException */
public static void main(String[] args) throws IOException { // 寫入jython文件的路徑
System.setProperty("python.home","D:\\java_test\\lib\\jython-standalone-2.7.1.jar"); // 寫入Python文件的路徑
String python = "D:\\java_test\\Script\\test.py"; PythonInterpreter interp = new PythonInterpreter(); interp.execfile(python); interp.cleanup(); interp.close(); } }
簡單測試了一下結果以下:
結果能夠正常打印出來 ,可是報了錯,console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0. 其實這是編碼的問題 。
解決辦法:解決辦法爲在要執行的代碼上右鍵,Run As>Run Configurations,選擇第二個頁籤Arguments,在VM arguments中添加
-Dpython.console.encoding=UTF-8
在運行就不會有那個紅的報錯了 ,歐耶~~~
2)、以上完成算是將Java與Python文件打通了 ,可是這並不能知足個人使用要求,由於我是須要有參數傳入和輸出的。因而乎,在Java中單向調用Python程序中的方法,須要傳遞參數,並接收返回值。Python既支持面向函數式編程,也支持面向對象編程。所以,調用Python程序中的方法也分別以面向函數式編程和麪向對象式編程進行說明。
開始第二步的征程;
修改Python文件內容(調用方法),以下:
#coding=utf-8
import math
def power(x,y): return math.pow(x,y)
對應的Java代碼以下:
package java_Test; import java.io.IOException; import org.python.core.Py; import org.python.core.PyFunction; import org.python.core.PyObject; import org.python.util.PythonInterpreter; public class TestIng { /** * @param args * @throws IOException * @throws InterruptedException */
public static void main(String[] args) throws IOException { System.setProperty("python.home", "D:\\java_test\\lib\\jython-standalone-2.7.1.jar"); // 1. Python面向函數式編程: 在Java中調用Python函數
String pythonFunc = "D:\\java_test\\Script\\test.py"; PythonInterpreter pi1 = new PythonInterpreter(); // 加載python程序
pi1.execfile(pythonFunc); // 調用Python程序中的函數
PyFunction pyf = (PyFunction) pi1.get("power", PyFunction.class); PyObject dddRes = pyf.__call__(Py.newInteger(2), Py.newInteger(3)); System.out.println(dddRes); pi1.cleanup(); pi1.close(); } }
第一個錯誤出現了,
緣由:說文件的編碼不合規,有問題 ,由於這個是直接修改後綴名來改變文件格式的因此至關因而假修改 。
解決辦法:將文件另存爲,在另存爲的時候選擇文件的編碼爲UTF-8。就能夠解決了
此時此刻,第二個錯出來了 。
若是你遇到這個問題,那麼恭喜你。和我同喜了,哈哈 ~~
而後若是你去百度,貌似是解決不了的(是真的沒有相關詳細的解決辦法說明),那我就來悄悄地告訴你是爲啥子吧!!!
緣由:是jython的版本問題 ,版本過高了 ,他不支持這樣讓你玩,換個低版本的,我選jython-standalone-2.5.3.jar,因而我也把它上傳雲盤了
詳細解決辦法:
1)、解除以前導入的jython-standalone-2.7.1.jar版本的包,解除辦法就是將導入的辦法倒序操做就行;
2)、刪除java_test文件夾中全部的文件,按照以前建立的文件目錄接口從新文件夾結構;
3)、將jython-standalone-2.5.3.jar文件配置系統環境變量;
4)、從新新建Java項目;
期間還有其餘的小問題,如:
緣由:代碼的編寫問題,Python代碼中一個逗號是中文版的
解決辦法:改爲英文版的就OK了
上邊貼的代碼此時也是會報錯的,如jar路徑名稱、代碼語法等。對應的修改一下就OK了 。
3、以上是完成了第一階段的調試,接下來爲我本身所需來就行調試。
Python代碼以下(Python文件名爲:Original.py):
# -*- coding: utf-8 -*-
import base64 import ast import urllib.parse def addse(Original): # 解碼
url_org = urllib.parse.unquote(Original) # 提取 args參數
parameter1 = urllib.parse.urlparse(url_org) parameter2 = urllib.parse.urlparse(parameter1.fragment) # base64位解碼args參數並切片截取值
parameter3 = base64.b64decode(parameter2.query[5:]) # 將截取的byte類型的值轉化爲字符串str類型的值
# print(parameter3) 會輸出被b包圍的字典, b 表示 byte的意思,咱們只要再將byte轉換回去
# 將str類型的值轉化爲字典類型
parameter5 = ast.literal_eval(str(parameter3,'utf-8')) # 經過for循環將字典中的值取出
for i in parameter5: return("%s = %s" %(i,parameter5[i])) if __name__ == "__main__": addse(Original)
Java代碼以下:
package test_java; import java.io.IOException; import org.python.core.Py; import org.python.core.PyFunction; import org.python.core.PyObject; import org.python.util.PythonInterpreter; public class TestIng { /** * @param args * @throws IOException * @throws InterruptedException */
public static void main(String[] args) throws IOException { System.setProperty("python.home", "D:\\java_test\\lib\\jython-standalone-2.5.3.jar"); // 1. Python面向函數式編程: 在Java中調用Python函數
String pythonFunc = "D:\\java_test\\Script\\Original.py"; PythonInterpreter pi1 = new PythonInterpreter(); // 加載python程序
pi1.execfile(pythonFunc); // 調用Python程序中的函數
PyFunction pyf = (PyFunction) pi1.get("addse", PyFunction.class); PyObject dddRes = pyf.__call__(Py.newDecimal("https://***********.com/new/#/register/h5?args=eyJ0ZW5hbnROYW1lIjoiQUEyQkwiLCJzaGFyZVBhcmFtIjoibjM0Z0MvNHVGek5pVFdGRk1UTml1SFREUWhSUzZxNVV3NmVUSlp6cThabGF6ZVdjK0p4cWNnPT0ifQ%3d%3d" )); System.out.println(dddRes); pi1.cleanup(); pi1.cleanup(); } }
修改完參數,直接運行,狂吃,喜提報錯 :
緣由:根據報錯內容,能夠知道是Python文件中引入的第三方包沒有找到或者Python版本問題。
解決辦法:直接把Python代碼用Python2.7的語法重寫。便可解決
Python2.7語法的代碼以下:
import urlparse import base64 import ast def addse(Originals): # 解碼
url_org = urlparse.unquote(Originals) # 提取 args參數
parameter1 = urlparse.urlparse(url_org) parameter2 = urlparse.urlparse(parameter1.fragment) # # base64位解碼args參數並切片截取值
parameter3 = base64.b64decode(parameter2.query[5:]) parameter5 = ast.literal_eval(str(parameter3)) # # 經過for循環將字典中的值取出
for i in parameter5: print "%s = %s" %(i,parameter5[i]) if __name__ == "__main__": Original = "https://xxxxxxxxxxx.com/new/#/register/h5?args=eyJ0ZW5hbnROYW1lIjoiQUEyQkwiLCJzaGFyZVBhcmFtIjoibjM0Z0MvNHVGek5pVFk1UTml1S11231SUzZxNVV3NmVUSlp6cThabGF6ZVdjK0p4cWNnPT0ifQ%3d%3d" addse(Original )
再次試運行,,,,幺吼,又翻車了,換了個錯繼續報:
緣由:提示說,Original沒有被定義。
解決辦法:修改Python代碼,不要初始化相關的信息:if __name__ == "__main__":
此時在運行,,OMG又他麼報錯了
事實證實此時個人程序是通了的,可是我太菜了由於各類語法規則問題致使一直報錯問題就出在 :url_org = urlparse.unquote(Originals) 這一句上;
緣由:在調用Python程序時,其中的unquote這個在urlparse這個中沒有(在pycharm中一樣的這一句倒是能夠正常成功的,好奇爲啥經過Java去調就失敗)。看了一下在Python2.7中關於解碼的方法調用。將解碼這一句改爲:url_org = urllib.unquote_plus(Originals) 在一執行,奇蹟出現了 ,沃德瑪雅,終於在控制檯看到了我想要的結果。
其實仍是有點小激動的。大家是不知道像我這樣太菜的人去搞這些是有多痛苦。不過解決了全部問題,看到了成功的時候仍是很激動的。
這個就先這樣吧 ,吧這些代碼打成jar包,放在jmeter裏,當作正常的jar包去調用就行了 ,具體的後續在更新》》》》》》》
參考文章: