jmeter教程(六):java请求

我们发送http请求或是其它请求,就是在执行一段代码,只不过,执行的代码,布署在服务器上。而java请求,也是在执行一段代码,只不过代码布署在本地,需要我们自己实现代码的逻辑。利用java请求,可以很方便地实现你想要的需求,当然,前提是你要会java。先看看java请求的具体实现吧,打开eclipse,新建一个java Project

这里,我项目名就叫Test了,然后在项目名上右击,选最下面的properties

Java Build Path——Libraries——Add External JARS...

找到jmeter安装目录下lib/ext目录下的ApacheJMeter_core.jar和ApacheJMeter_java.jar两个jar文件,按住Ctrl可以多选,然后点  打开

然后点 OK,这样,jar文件就引用好了,然后就是写java代码,新建包和类。类的代码

package aaa;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

public class Demo extends AbstractJavaSamplerClient {

	@Override
	public Arguments getDefaultParameters(){
		Arguments args = new Arguments();
		args.addArgument("param", "");
		return args;
	}
	
	@Override
	public SampleResult runTest(JavaSamplerContext arg0) {
		SampleResult sr = new SampleResult();
		String param = arg0.getParameter("param");
		
		sr.setResponseData(param.getBytes());
		sr.setSuccessful(true);
		
		return sr;
	}

}

这段代码的作用非常简单,接收一个参数,然后把这个参数响应回去,类似于代码里的打印语句,可以用来查看jmeter脚本中的变量的值。然后在项目上右击,new——File

File name就是manifest.mf,这个名称不要改,是java打包的默认配置文件

第一行默认写法,固定的。第二行,指定程序的入口。注意,中间的冒号后有一个空格,最后要以一个空行结束。保存,然后就可以打包了,右击项目,选Export...

包类型,选java下的JAR file,点Next

点 Browse... 选择存放jar的路径,可以直接选到jmeter安装目录下/lib/ext/目录下,然后给包取个名称,我这里就叫Test.jar。如果jar已存在,改了之后,再重新打包,要覆盖原先的jar包,最下面的复选框,勾上。看英语就知道意思了

Next

选择下面的,从工作空间选择已存在的配置文件,再点 Browse... 选择之前添加的打包配置文件

选好后,点 OK,然后再点Finish,这样,jar包就打好了

目录下也有了相应的jar包了。接下来,就要在jmeter,添加java请求了,打开jmeter,添加线程组,添加 Java请求

可以看到类名称,已经是我们刚刚写的类了,如果不是,可以点右边向下的三角形,在下拉框中选择我们需要的类。接下来,添加一个察看结果树,然后,在java请求里面,param给一个值:123456,保存脚本,运行,然后看结果

可以看到,把我们输入的123456响应回来了,当然接收的参数也可以是一个变量,我们在测试计划上设置一个全局变量aaa,值是1234

然后,在java请求里

保存,运行,看结果

把变量的值响应回来了。

在做接口集成自动化的时候,可以把脚本中需要用到的数据,全部写到一个配置文件中,脚本开头,先用一个java请求,把脚本中的参数全部更新一下,然后再用java请求,把这些参数读出来给脚本使用。这样就可以实现,脚本每次运行时,用到的参数都不一样。读文件的代码

package king.bbb;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

public class ReadFile extends AbstractJavaSamplerClient{
	public Arguments getDefaultParameters(){
		Arguments args = new Arguments();
		//添加一个参数,名称叫:文件路径
		args.addArgument("文件路径","");
		//添加一个参数,名称叫:读取的行
		args.addArgument("读取的行","4");
		args.addArgument("字符编码","GBK");
		return args;
	}

	public SampleResult runTest(JavaSamplerContext arg0) {
		SampleResult sr = new SampleResult();
		
		String fileName = arg0.getParameter("文件路径").trim();
		String lineStr = arg0.getParameter("读取的行").trim();
		String encoding = arg0.getParameter("字符编码").trim();
		sr.setDataEncoding(encoding);
		
		File file = new File(fileName);
		if(!file.isFile() || !file.exists()){
			sr.setResponseData("路径是目录或是文件不存在!!!".getBytes());
			sr.setSuccessful(false);
		}else if(lineStr==null || "".equals(lineStr)){
			sr.setResponseData("没有输入要读取的行数,不能读取文件!!!".getBytes());
			sr.setSuccessful(false);
		}else if(!lineStr.matches("\\d+")){
			sr.setResponseData("“读取的行”参数不合法,请输入数字!!!".getBytes());
			sr.setSuccessful(false);
		}else{
			BufferedReader reader = null;
			try{
				int line = Integer.parseInt(lineStr);
				reader = new BufferedReader(new FileReader(file));
				int nowLine = 0;
				String content = null;
				while((content = reader.readLine())!=null){
					++nowLine;
					if(nowLine==line){
						break;
					}
				}
				if(line>nowLine){
					sr.setResponseData("输入的数字大于文件的行数,请核对后再输入!!!".getBytes());
					sr.setSuccessful(false);
					return sr;
				}
				if("".equals(content)){
					sr.setResponseData("读取的行是空行!!!".getBytes());
					sr.setSuccessful(true);
					return sr;
				}
				String[] res = content.split(",");
				StringBuffer sb = new StringBuffer();
				for(int i=0; i<res.length; ++i){
					sb.append("parameter"+(i+1)+":"+res[i]+",");
				}
				sb.delete(sb.length()-1, sb.length());
				sr.setResponseData(sb.toString().getBytes());
				sr.setSuccessful(true);
				
			}catch(IOException e){
				e.printStackTrace();
				sr.setResponseData("打开文件出问题了!!!".getBytes());
				sr.setSuccessful(false);
			}finally{
				if(reader != null){
					try{
						reader.close();
					}catch(IOException e){
						e.printStackTrace();
						sr.setResponseData("关闭文件出问题了!!!".getBytes());
						sr.setSuccessful(false);
					}
				}
			}
		}
		
		return sr;
	}

}

一次读一行,读取的数据,以英文的逗号分割,响应为parameter1:1234,parameter2:aaa这样的格式

更新文件的代码

package king.aaa;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.Arrays;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

public class ModifyFile extends AbstractJavaSamplerClient{
	public Arguments getDefaultParameters(){
		Arguments args = new Arguments();
		//添加一个参数,名称叫:文件路径
		args.addArgument("文件路径","");
		//添加一个参数,名称叫:修改的行,可以修改多行,以英文的逗号隔开
		args.addArgument("修改的行","4,7,10");
		//添加一个参数,名称叫:字符编号,主要是解决响应信息中文乱码的问题,默认GBK,一般不用改
		args.addArgument("字符编码","GBK");
		return args;
	}
	
	public SampleResult runTest(JavaSamplerContext arg0){
		SampleResult sr = new SampleResult();
		
		//获取三个参数的值
		String fileName = arg0.getParameter("文件路径").trim();
		String lineStr = arg0.getParameter("修改的行").trim();
		String encoding = arg0.getParameter("字符编码").trim();
		
		File file = new File(fileName);
		//判断第一个参数的合法性,如果是目录,或是文件不存在,就响应错误
		if(!file.isFile() || !file.exists()){
			sr.setResponseData("路径是目录或是文件不存在!!!".getBytes());
			sr.setSuccessful(false);
		//判断第二个参数为空,就返回信息“文件未修改!!!”
		}else if(lineStr==null || "".equals(lineStr.trim())){
			sr.setResponseData("未添加要修改的行,文件未修改!!!".getBytes());
			sr.setSuccessful(true);
		//判断第二个参数的合法性,如果含有数字、空格、英文逗号之外的字符,就响应错误
		}else if(!lineStr.matches("[\\d\\s,]+")){
			sr.setResponseData("“修改的行”参数不合法!请不要输入数字、空格、英文逗号之外的字符!!!".getBytes());
			sr.setSuccessful(false);
		}else{
			//用英文逗号分割“修改的行”,字符串数组
			String[] lineStrs = lineStr.split(",");
			//定义一个整数类型数组,用来接收上面分割的字符串数组(转化成整数类型数组)
			int[] lines = new int[lineStrs.length];
			try{
				//遍历lineStrs字符串数组,元素都转成整数,放到整数类型数组中
				for(int i=0; i<lineStrs.length; ++i){
					lines[i] = Integer.parseInt(lineStrs[i].trim());
				}
				//数组排序
				Arrays.sort(lines);
				//数组去重
				lines = delArray(lines);
				//返回值为更改的行数,空行不会更新,大于文件总行数的参数会丢弃
				int count = modifyFile(fileName, lines);
				
				sr.setResponseData(("修改成功!!!共修改了 "+count+" 行。").getBytes());
				sr.setSuccessful(true);
			}catch(Exception e){
				e.printStackTrace();
				sr.setResponseData("出了点小状况,请联系网管!!!".getBytes());
				sr.setSuccessful(false);
			}
		}
		sr.setDataEncoding(encoding);
		return sr;
	}
	
	//数组去重方法
	static int[] delArray(int[] arr){
		int count=0;
		//找出数组中重复元素的个数
		for(int i=0; i<arr.length-1; ++i){
			for(int j=i+1; j<arr.length; ++j){
				if(arr[i]==arr[j]){
					++count;
					break;
				}
			}
		}
		//定义新数组,长度为原数组的长度减去重复元素的个数
		int[] resArr = new int[arr.length-count];
		count = 0;
		//遍历原数组,如果元素不在新数组中,就放进新数组中
		out:for(int i=0; i<arr.length; ++i){
			for(int j=0; j<count; ++j){
				if(arr[i]==resArr[j]){
					continue out;
				}
			}
			resArr[count++] = arr[i];
		}
		
		return resArr;
	}
	
	//获取字符串中后面的数字出现位置的方法
	static int positionNum(String str){
		int index;
		//从字符串的最后一个元素向前找,第一个非数字元素的下标,即是所要找的
		for(index=str.length()-1; index>=0; --index){
			char c = str.charAt(index);
			if((int)c<48||(int)c>57){
				break;
			}
		}
		return index;
	}
	
	//将文件中的行更新的方法
	static String modifyLine(String str){
		//用英文逗号分隔行的内容,结果保存到strs字符串数组中
		String[] strs = str.split(",");
		//定义字符缓冲类,用来保存更新后的内容
		StringBuffer sb = new StringBuffer();
		//遍历strs字符串数组
		for(String temp:strs){
			//获取数字出现的位置
			int index = positionNum(temp)+1;
			//截取最后一个非数字及其之前的字符串
			String word = temp.trim().substring(0, index);
			//截取后面的数字部分
			String num = temp.trim().substring(index, temp.length());
			//记录数字部分的长度
			int length = 0;
			//如果数字部分为空,则让数字部分为“1”
			if("".equals(num)){
				num = "1";
			}else{
				//先把数字部分的长度记录
				length = num.length();
				//数字部分转成长整型,加上1后,再转成字符串
				num = String.valueOf(Long.parseLong(num)+1);
			}
			//如果数字部分,比原先的短,就在前面补“0”
			while(num.length()<length){
				num = "0"+num;
			}
			//把处理过后的非数字和数字部分拼接起来,并在后面加英文逗号分隔,添加进字符缓冲对象
			sb.append(word+num+",");
		}
		//把字符缓冲对象中最后面的逗号删掉
		sb.delete(sb.length()-1, sb.length());
		
		return sb.toString();
	}
	
	//更新文件的方法
	static int modifyFile(String str, int[] line){
		File tempFile = null;
		File oldFile = new File(str);
		BufferedReader reader = null;
		BufferedWriter writer = null;
		//有效行的数目,传进来的数组中的元素,如果大于文件的总行数,会丢弃
		int lines = 0;
		//有效行中空行数目
		int empty = 0;
		//原文件目录下,新建一个临时文件temp
		String fTemp = str.substring(0, str.lastIndexOf("\\")+1)+"temp";
		tempFile = new File(fTemp);
		int count = 0;
		//如果temp存在了就新建temp1,如果temp1也存在,就新建temp2。。。
		while(tempFile.exists()){
			++count;
			tempFile = new File(fTemp+count);
		}
		try{
			//读文件流
			reader = new BufferedReader(new FileReader(oldFile));
			//写文件流,写到临时文件
			writer = new BufferedWriter(new FileWriter(tempFile));
			//读到多少行
			int nowLine = 0;
			//读到的内容
			String content = null;
			while((content=reader.readLine())!=null){
				++nowLine;
				//如果数组的指针未越界,并且读取文件的行数等于数组的元素
				if(lines<line.length&&nowLine==line[lines]){
					//数组指针后移
					++lines;
					//读取文件的行,为空,空行数目加1,否则就更新行的内容
					if("".equals(content.trim())){
						++empty;
					}else{
						content = modifyLine(content);
					}
				}
				//读到的行内容写到临时文件
				writer.write(content);
				writer.newLine();
			}
			
		}catch(IOException e){
			e.printStackTrace();
			System.out.println("出了点小状况,请联系网管!!!");
		}finally{
			if(writer!=null){
				try{
					writer.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			
			if(reader!=null){
				try{
					reader.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
		}
		//把临时文件的内容复制到原文件
		copyFile(tempFile.getAbsolutePath(),str);
		//删除临时文件
		if(tempFile!=null){
			tempFile.delete();
		}
		
		return lines-empty;
	}
	
	//复制文件的方法,效率高
	static void copyFile(String oldFile, String newFile){
		FileChannel oldFi = null;
		FileChannel newFi = null;
		try{
			oldFi = new FileInputStream(new File(oldFile)).getChannel();
			newFi = new FileOutputStream(new File(newFile)).getChannel();
			newFi.transferFrom(oldFi, 0, oldFi.size());
		}catch(IOException e){
			e.printStackTrace();
		}finally{
			if(newFi!=null){
				try{
					newFi.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			
			if(oldFi!=null){
				try{
					oldFi.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
		}
	}
	
}

要更新的行,每个参数之间有英文的逗号分隔开。更新机制,就是在原先的基础上添加数字,比如原先是"张三",更新后,就变为"张三1",但"张三1",更新后是变成"张三2",不是"张三11"。当然,现在的方法还是有漏洞,比如,更新的行,输入连续的两个逗号,就会异常了。

欢迎加入测试群:91425817,一起讨论测试的那此事。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值