代码如下:
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