编写获取本地和远程图片流的Jmeter自定义函数
代码如下:
package org.apache.functions;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.commons.codec.binary.Base64;
public class ImageLocalBase64 extends AbstractFunction {
// 显示的参数名字
private static final List<String> desc = new LinkedList();
// 显示的函数名字
private static final String KEY = "__ImageLocalBase64";
// 参数值
private Object[] values;
static {
desc.add("local path for image");
desc.add("Name of variable in which to store the result (optional)");
}
public String execute(SampleResult paramSampleResult, Sampler paramSampler) throws InvalidVariableException {
String s = null;
try {
String url = ((CompoundVariable) this.values[0]).execute();
url = new String(url.getBytes("UTF-8"), "UTF-8");
InputStream inStream = new FileInputStream(url);
byte[] b = ImageUtil.readInputStream(inStream);
byte[] bs = Base64.encodeBase64(b);
s = new String(bs);
return s;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return s;
}
// 获取参数值
public synchronized void setParameters(Collection<CompoundVariable> paramCollection)
throws InvalidVariableException {
// 检查参数,我也搞不懂是毛线意思,NND
checkMinParameterCount(paramCollection, 1);
this.values = paramCollection.toArray();
}
// 返回函数名字
public String getReferenceKey() {
return KEY;
}
// 返回参数名字
public List<String> getArgumentDesc() {
return desc;
}
}
package org.apache.functions;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.commons.codec.binary.Base64;
public class ImageRemoteBase64 extends AbstractFunction {
//显示的参数名字
private static final List<String> desc = new LinkedList();
//显示的函数名字
private static final String KEY = "__ImageRemoteBase64";
//参数值
private Object[] values;
static {
desc.add("URL for remote Image");
desc.add("Name of variable in which to store the result (optional)");
}
public String execute(SampleResult paramSampleResult, Sampler paramSampler)
throws InvalidVariableException {
String s = null;
try {
String url = ((CompoundVariable)this.values[0]).execute();
s = ImageUtil.getImageFromNetByURL1(url);
return s;
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return s;
}
//获取参数值
public synchronized void setParameters(Collection<CompoundVariable> paramCollection)
throws InvalidVariableException {
//检查参数,我也搞不懂是毛线意思,NND
checkMinParameterCount(paramCollection, 1);
this.values = paramCollection.toArray();
}
//返回函数名字
public String getReferenceKey() {
return KEY;
}
//返回参数名字
public List<String> getArgumentDesc() {
return desc;
}
/**
* 从输入流中获取数据
*
* @param inStream
* 输入流
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[inStream.available()];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
}
package org.apache.functions;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class ImageUtil {
/**
* 根据地址获得数据的字节流
*
* @param strUrl
* 网络连接地址
* @return
*/
public static String getImageFromNetByURL1(String strUrl) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(strUrl);
HttpResponse response;
String s = null;
try {
response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
byte[] b = readInputStream(instream);
byte[] bs = Base64.encodeBase64(b);
s = new String(bs);
return s;
}
} catch (ClientProtocolException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return s;
}
/**
* 根据地址获得数据的字节流
*
* @param strUrl
* 本地连接地址
* @return
*/
public static byte[] getImageFromLocalByUrl(String strUrl) {
try {
File imageFile = new File(strUrl);
InputStream inStream = new FileInputStream(imageFile);
byte[] btImg = readInputStream(inStream);// 得到图片的二进制数据
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 从输入流中获取数据
*
* @param inStream
* 输入流
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[inStream.available()];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
/**
* 将图片写入到磁盘
*
* @param img
* 图片数据流
* @param fileName
* 文件保存时的名称
*/
public static void writeImageToDisk(byte[] img, String zipImageUrl) {
try {
File file = new File(zipImageUrl);
FileOutputStream fops = new FileOutputStream(file);
fops.write(img);
fops.flush();
fops.close();
System.out.println("图片已经写入" + zipImageUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
将生成的jar包放置到Jmeter的lib\ext目录下。重启Jmeter后再运行--函数助手模块能够看到自定义的两个函数。
使用时可以用如下方式引用:
${__ImageRemoteBase64(${photoPath},)
其中${photoPath}通过CSV Data Set Config参数化得到的远端图片路径。
心得:
1、httpclient 可以自动对URL字符串中的中文编码进行转码,减少了URL包含中文导致的图片获取不到问题。
2、Jmeter自定义函数的包名必须要包含“functions”,否则Jmeter发现不了该自定义函数。建议包名:package org.apache.functions