以百度天气预报查询API 服务为例,创建Jmeter JavaSampler请求范例

简介: 最近在整理性能测试的一些入门文章,给同事们分享,介绍API 接口自动化和性能测试入门。下面将以百度天气预报查询API 服务为例,创建Java API 请求范例。1. API 服务信息参考文档:https://blog.

最近在整理性能测试的一些入门文章,给同事们分享,介绍API 接口自动化和性能测试入门。

下面将以百度天气预报查询API 服务为例,创建Java API 请求范例。

1. API 服务信息

参考文档:https://blog.csdn.net/younghaiqing/article/details/54799303

接口示例:http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=amMXVSEUGt6yU95x4DQOC2Um

百度ak申请地址:http://lbsyun.baidu.com/apiconsole/key

接口参数说明:

 

返回结果:

 

 

2. 创建Java工程

2.1 分析API 服务接口

接口示例如下:

http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=yourkey

输出的数据格式,默认为xml格式;当output设置为'json'时,输出的为json格式的数据。

通过观察接口示例,可以判断HTTP请求方式为GET——GET方法向URL添加数据。

 

2.2 写出API 服务请求

package com.ane56.tester;

import java.io.BufferedReader;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.net.HttpURLConnection;  
import java.net.URL; 

public class BaiduWeather_originalV1 {
    /* 
     * 根据城市名称查询天气 
     * @param city 
     *  
     * auther Jason Ma
     */
    
    //接口示例
    //http://api.map.baidu.com/telematics/v3/weather?location=北京&output=json&ak=yourkey
    //百度ak申请地址:http://lbsyun.baidu.com/apiconsole/key
    //输出的数据格式,默认为xml格式;当output设置为'json'时,输出的为json格式的数据
    
    private static String MYKEY = "amMXVSEUGt6yU95x4DQOC2Um";
    private static String ADDRESS = "http://api.map.baidu.com/telematics/v3/weather";
    
    public static void main(String[] args) {
        String city = "青浦";
        String httpArg = "location=" + city + "&output=" + "xml" + "&ak=" + MYKEY;
        
        String httpUrl = ADDRESS + "?" + httpArg;
        System.out.println("请求的地址是:" + httpUrl);
        
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        System.out.println(result);
    }
}

 

3. 转化为Jmeter JavaSampler

下面将利用Eclipse创建Maven工程的方式,完成JavaSampler的编码工作。

3.1 创建Maven工程

在Eclipse左侧的Package Explore点击右键,依次选择New -> Other -> Maven -> Maven Project:

这里要注意,之前创建的API 请求类,不是一定要基于Maven工程,普通的Java Project就可以;

创建Maven Project是为了开发和调试Jmeter JavaSampler。

 

3.2 添加依赖

打开Maven工程的POM.xml文件,添加依赖包。我们需要的依赖包如下:

 - Junit:工程创建时已存在;

 - Jmeter:核心,作为JavaSampler请求;有三个组件需要添加:ApacheJMeter_core、ApacheJMeter_java、ApacheJMeter_components;

 - log4j-over-slf4j:为了解决调试阶段log4j红字报错,非必选,也可以用其他依赖包替代。

 完成后的POM.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ane56.tester</groupId>
    <artifactId>Jmeter_JavaSampler</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <name>Jmeter_JavaSampler</name>
    <url>http://maven.apache.org</url>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.slf4j/log4j-over-slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
         
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_core</artifactId>
            <version>3.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>3.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_components</artifactId>
            <version>3.3</version>
        </dependency>
        
  </dependencies>
</project>

 

3.3 理解Java Sampler的套路

首先:要实现AbstractJavaSamplerClient类,才能被Jmeter加载;创建名为“BaiduWeather_JavaSamplerV1”的Java类,

添加对AbstractJavaSamplerClient类的实现;完成后如下:

public class BaiduWeather_JavaSamplerV1 extends AbstractJavaSamplerClient {
……
}

其次:(对比LoadRunner脚本的结构:)

-        设置参数:getDefaultParameters,用于设置传入的参数;

-        初始化(init):setupTest,用于初始化性能测试时的每个线程;

-        执行迭代(action):runTest,为性能测试时的线程运行体;

-        完成退出(end):teardownTest,为测试结束方法,用于结束性能测试中的每个线程。

补充:调试脚本的main()方法。

 

3.4 详解getDefaultParameters()

在getDefaultParameters()代码段中,添加请求的参数;

作用:当Jmeter读取此JavaSampler后,能够读出请求的参数到列表:

 

注意:

在getDefaultParameters()代码段中,只需要添加参数项的名字,而不必要赋值。

通常我们会在Jmeter脚本中,对请求参数进行参数化。

 读取参数的代码(在runTest方法内):

 

3.5 详解runTest()格式

-        创建sampleResult:private SampleResult sampleResult;

-        给请求贴标签:sampleresult.setSampleLabel("Java请求");

-        把请求的信息,写到Jmeter的【察看结果树 – 请求】页面:

       sampleresult.setSamplerData(httpUrl);

       sampleresult.setDataType(SampleResult.TEXT);

-        发送请求时,开始计时:sampleresult.sampleStart();

-        收到应答后,结束统计响应时间:sampleresult.sampleEnd();

-        标记获得成功的应答,对应http 200:sampleresult.setResponseCodeOK();

-        把收到的应答内容,写到Jmeter的【察看结果树 – 响应数据】页面:

sampleresult.setResponseData("结果是:"+ result, "utf-8");

       sampleresult.setDataType(SampleResult.TEXT);

 

3.6 调试脚本的main()

1)首先要进行参数赋值,否则将直接使用getDefaultParameters()代码段中设置的参数默认值。建议赋值,与Jmeter的实际工作方式保持一致。

2)调用BaiduWeather_JavaSamplerV1,创建一次测试执行。

 

 

 4. 导出Maven工程

4.1 导出依赖包

选中工程,点击右键,在菜单中选择Run As -> Run Configuration:

 

1)    首先在左侧的列表中,选择Maven Build,然后点击左上方的新建图标;

2)    输入操作的名字,在本例中是:Jmeter_JavaSampler_exportDependency;

3)    定位当前操作的工程路径;可以点击Workspace…的按钮来定位;

4)    输入操作的具体命令:在本例中是为了导出依赖:dependency:copy-dependencies;

5)    检查Maven Runtime的信息是否正确;

6)    点击Apply按钮完成保存;

7)    点击Run按钮、进行依赖包的导出。

等待完成后,到工程所在的路径\target\dependency目录,查看的依赖jar包:

 

 4.2 导出测试类

导出测试类有两种方式:

1)Maven install命令:该命令会在工程所在的路径\target文件夹下,生成与工程同名的jar文件,如Jmeter_JavaSampler-0.0.1-SNAPSHOT.jar。

      不推荐这样的方式,因为这将导出工程中所有的类,不够精确。

2)直接导出单个接口测试类,注意是符合Jmeter JavaSampler的那个类。

      具体方法是:在Eclipse左侧的Package Explore选中该类,点击右键,选择Export:

输入要导出JAR file的路径和名称,点击Finish按钮,完成导出操作。

 

5. 在Jmeter创建测试计划

5.1 准备工作

首先,要将导出的依赖包,拷贝到jmeter\lib目录下。推荐将整个dependency文件夹拷过来,然后再引入到测试计划。

这样的好处在于大量的依赖包中存在与原有jmeter\lib目录下的同名或不同版本的干扰。如下图:

 

然后,将单独导出的接口测试类的jar文件复制到jmeter\lib\ext目录下,如下图:

这里的jar文件有个问题,先卖个关子,在后面分析解决思路。

完成后,进入下一环节。

 

5.2 创建测试计划

启动Jmeter,在测试计划的主窗口的靠下位置,添加依赖到classpath中;

通过点击浏览按钮,定位到依赖包的文件夹,全选所有的jar文件,点击打开按钮:

 

 

第一步完成后,添加线程组,并添加Java请求;

 

 

在类名称的下拉菜单中,找到我们开发的测试类BaiduWeather_JavaSamplerV1:

 

 

 5.3 调试脚本

填写请求参数,填充原本为空的参数、缺省值可以替换也可保留:

 

 

添加一个监听器 – 察看结果树,以便查看脚本调试的结果:

 

点击刚刚添加的察看结果树,将主画面切换到结果树:

 

 

在调试前,需要保存脚本成.jmx文件。点击保存按钮,将脚本存放到合适的位置。

点击上方工具条内的启动按钮,查看测试结果:

Text区域,每执行一次请求,就自动增加一条记录到尾部。

右侧的区域,有三个Tab页,方便查看测试请求和响应。我们分别查看一下,注意判断响应数据是否为正确的。

请求页面:

没问题,确实与预期的一样。

再看响应数据页面:

显示error -3, No result available,出错了。

 

5.4 解决问题

解决步骤:

先将请求内容,放到浏览器中,查看是否能获得正确的天气预报信息:

成功了,说明API 服务没问题,请求内容也没问题。是哪里不对呢?

首先想到的,是否因为百度天气预报API对不是浏览器访问的Request做了屏蔽?类似与反爬虫策略。那就需要在请求时,补全HTTP Header信息。

那么HTTP Header信息哪里能查看?

这里可以利用Chrome浏览器的开发工具,按F12后,刷新一下,浏览器会自动录制整个请求和应答。

 

这样就能捕获到HTTP Header信息,将它们逐条复制下来。在Jmeter的线程组下面添加一个配置元件 - HTTP头信息管理,再逐条添加进去。

再次执行脚本,错误依旧如此。

思路错了吗?其实没有,方法是正确的,再想想。

 

正确的方法如下:

仔细查看一下Request RUL,如下图:

和浏览器的地址栏中的内容比较一下,“location=上海”在Request中,被替换成了“location=%E4%B8%8A%E6%B5%B7”。

这是汉字没有转码所导致的:我们从Jmeter发出的汉字不是URL编码的格式。

 

再想想,我们在Eclipse调试接口脚本的时候,应答信息和浏览器中显示的内容是一样的;这意味着从Eclipse发出的Request,已经被自动转码了,有点坑啊!

 因此,我们需要对城市名称的汉字进行转码,而且要在接口请求的代码里完成。

为完成转码功能,需要再增加一个依赖:

import java.io.UnsupportedEncodingException;

runTest方法修改后,为如下图所示:

这里增加了一个转码的步骤,将接收到的城市名称从汉字转码为URL格式的。执行一下看看效果:

 

成功了!

重新将接口测试类导出成jar文件,删除先前存在于jmeter\lib\ext下的同名文件;再拷贝一遍。

Jmeter也要重启才会刷新Java请求中的类列表。

重启后,打开之前保存的脚本,再次运行调试;执行成功。

 

 

以上就是从API 接口请求,转化为Jmeter的JavaSampler的编写方法。完整代码如下:

package com.ane56.tester;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
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 BaiduWeather_JavaSamplerV2 extends AbstractJavaSamplerClient {

    private SampleResult sampleResult;
    private String parameter;
    
    /** Holds the result data (shown as Response Data in the Tree display). */
    private String resultData;
    
    private String httpArg_city;
    private String httpArg_outputType;
    
    SampleResult sampleresult = new SampleResult();
    
    /**
     * JMeter界面中可手工输入参数,代码里面通过此方法获取
     */
    public Arguments getDefaultParameters() {
        // 设置参数,并赋予默认值
        Arguments params = new Arguments();
        params.addArgument("httpUrl", "");
        params.addArgument("httpArg_city", "上海");
        params.addArgument("httpArg_outputType", "xml");
        params.addArgument("mykey", "");
        //System.out.println("Default params list: " + params);

        return params;
    }
    
    /**
     * 执行runTest()方法前会调用此方法,可放一些初始化代码
     */
    @Override
    public void setupTest(JavaSamplerContext arg0) {
        //parameter = arg0.getParameter("parameter");
        
        sampleresult.setDataEncoding("utf-8");

        long start = System.currentTimeMillis();
    }
    
    @Override
    public SampleResult runTest(JavaSamplerContext arg0) {
        
        sampleresult.setSampleLabel("Java请求");
        
        String httpUrl = arg0.getParameter("httpUrl");
        String location = arg0.getParameter("httpArg_city");
        String outputType = arg0.getParameter("httpArg_outputType");
        String mykey = arg0.getParameter("mykey");
        
        //对汉字转码,否则在Jmeter测试时,获得错误响应
        try {
            location = java.net.URLEncoder.encode(location, "utf-8");
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        String httpArg = "location=" + location + "&output=" + outputType + "&ak=" + mykey;
        httpUrl = httpUrl + "?" + httpArg;
        System.out.println("HttpURL is: " + httpUrl);
        
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        
        sampleresult.setSamplerData(httpUrl);
        sampleresult.setDataType(SampleResult.TEXT);
        
        try {
            sampleresult.sampleStart();
            sampleresult.getStartTime();
            
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
            System.out.println("结果是:"+ result);

            sampleresult.setResponseCodeOK();
            sampleresult.setResponseMessage("Java Sampler Response is done. ");
            sampleresult.setResponseData("结果是:"+ result, "utf-8");
            sampleresult.setDataType(SampleResult.TEXT);
            
            sampleresult.setSuccessful(true);
        } catch (Exception e) {
            sampleresult.setSuccessful(false);
            e.printStackTrace();
        } finally {
            sampleresult.sampleEnd(); // jmeter 结束统计响应时间标记
            sampleresult.getEndTime();
        }
        
        return sampleresult;
    }
    
    /**
     * 执行runTest()方法后会调用此方法.
     */
    @Override
    public void teardownTest(JavaSamplerContext arg0) {
        long end = System.currentTimeMillis();
    }
    
    /**
     * 主函数;打jar包之前,记得注释掉main
     */
    
    public static void main(String[] args) {
        Arguments params = new Arguments();
        params.addArgument("httpUrl", "http://api.map.baidu.com/telematics/v3/weather");
        params.addArgument("httpArg_city", "上海");
        params.addArgument("httpArg_outputType", "json");
        params.addArgument("mykey", "amMXVSEUGt6yU95x4DQOC2Um");
        
        JavaSamplerContext arg0 = new JavaSamplerContext(params);
        
        BaiduWeather_JavaSamplerV2 test = new BaiduWeather_JavaSamplerV2();
        test.setupTest(arg0);
        test.runTest(arg0);
        test.teardownTest(arg0);
        System.exit(0);
    }
    
}

 

相关文章
|
JSON 监控 API
掌握使用 requests 库发送各种 HTTP 请求和处理 API 响应
本课程全面讲解了使用 Python 的 requests 库进行 API 请求与响应处理,内容涵盖环境搭建、GET 与 POST 请求、参数传递、错误处理、请求头设置及实战项目开发。通过实例教学,学员可掌握基础到高级技巧,并完成天气查询应用等实际项目,适合初学者快速上手网络编程与 API 调用。
1254 130
|
移动开发 算法 API
淘宝/天猫:使用物流查询API实时显示包裹位置,减少客服咨询量
电商平台中物流咨询占客服工作40%以上,用户频繁追问包裹位置。本文介绍通过物流查询API实现包裹实时追踪,降低75.6%咨询量,提升用户体验与复购率,助力降本增效。(238字)
|
人工智能 JSON API
淘宝/天猫:使用物流查询API实时显示包裹位置,减少客服咨询量
在电商竞争激烈的环境下,淘宝、天猫通过集成物流查询API,实现实时追踪包裹位置,显著减少用户咨询量。本文解析其原理、实现步骤与效益,展示如何以技术手段提升用户体验、降低客服压力,助力平台高效运营。(238字)
|
监控 安全 算法
快递查询API|一次接通2700+快递服务商的物流轨迹
在物流数字化的浪潮中,企业对接多家快递服务商的痛点日益凸显:每新增一家合作物流商,技术团队就要投入 5-7 个工作日进行接口开发,不同服务商的接口协议差异导致系统稳定性差,物流轨迹数据分散在各平台难以整合分析。快递鸟快递查询 API 通过标准化接口架构,创新性地实现了 2700 + 国内外快递服务商的一键接入,将传统模式下的周级开发周期压缩至小时级,彻底重构了物流数据对接的技术范式。
757 0
|
人工智能 API
阿里云百炼API-KEY在哪查询?如何获取阿里云AI百炼大模型的API-KEY?
阿里云百炼是阿里云推出的AI大模型平台,用户可通过其管理控制台获取API-KEY。需先开通百炼平台及大模型服务,即可创建并复制API-KEY。目前平台提供千万tokens免费额度,详细操作流程可参考官方指引。
|
JSON 前端开发 API
汽车配件:使用VIN码查询API精准匹配车型配件,提升用户信任
VIN码是汽车的唯一“身份证”,通过API可精准解析车型信息,实现配件99.5%以上匹配度。本文详解VIN码API的工作流程、技术实现与信任提升价值,助力汽配销售从经验判断迈向数据驱动,降低退货率,提升用户体验与复购。
1309 0
|
JSON 监控 测试技术
亚马逊:调用订单退款API自动化处理售后请求,缩短用户等待时间
在电商运营中,售后效率直接影响用户体验与平台声誉。亚马逊订单退款API为卖家提供自动化工具,通过编程方式高效处理退款请求,显著缩短用户等待时间。本文详解如何集成该API,实现退款流程自动化,提升响应速度与用户满意度。
|
JSON 监控 API
淘宝/天猫:使用订单查询API实时追踪包裹状态,自动推送物流通知至用户
在淘宝/天猫平台,通过集成订单查询API实现物流状态实时监控,结合定时轮询与自动推送通知功能,可有效减少用户频繁刷新页面,提升购物体验。本文详解API调用原理、状态判断及Python代码实现,助力开发者构建高效、智能的物流通知系统。
1310 0
|
12月前
|
缓存 监控 前端开发
顺企网 API 开发实战:搜索 / 详情接口从 0 到 1 落地(附 Elasticsearch 优化 + 错误速查)
企业API开发常陷参数、缓存、错误处理三大坑?本指南拆解顺企网双接口全流程,涵盖搜索优化、签名验证、限流应对,附可复用代码与错误速查表,助你2小时高效搞定开发,提升响应速度与稳定性。
|
数据可视化 测试技术 API
从接口性能到稳定性:这些API调试工具,让你的开发过程事半功倍
在软件开发中,接口调试与测试对接口性能、稳定性、准确性及团队协作至关重要。随着开发节奏加快,传统方式已难满足需求,专业API工具成为首选。本文介绍了Apifox、Postman、YApi、SoapUI、JMeter、Swagger等主流工具,对比其功能与适用场景,并推荐Apifox作为集成度高、支持中文、可视化强的一体化解决方案,助力提升API开发与测试效率。