ITPub博客

首页 > 数据库 > 数据库开发技术 > 如何保存HTTPrequestbase和CloseableHttpResponse

如何保存HTTPrequestbase和CloseableHttpResponse

原创 数据库开发技术 作者:FunTester 时间:2020-01-02 09:45:08 0 删除 编辑

在测试过程中,有一个重要的工作就是保存记录“现场”,以方便开发人员更快发现BUG解决问题。在接口测试中更是如此,如果开发人员能够根据BUG的信息直接复现请求,是一件很方便的事情。为此我想了一个再框架中增加保存HTTPrequestbase和CloseableHttpResponse两个对象的功能,其中主要是HTTPrequestbase的信息,CloseableHttpResponse以响应内容为主,因为每次请求我都会把必要信息(host,API,HTTP code,响应code,响应时间等等记录)。

下面是更新过的funrequest类的代码,更新内容时后面几个静态方法:

package com.fun.frame.httpclient
import com.fun.base.bean.RequestInfoimport com.fun.base.exception.RequestExceptionimport com.fun.config.HttpClientConstantimport com.fun.config.RequestTypeimport com.fun.frame.Saveimport com.fun.utils.Timeimport net.sf.json.JSONObjectimport org.apache.commons.lang3.StringUtilsimport org.apache.http.Headerimport org.apache.http.HttpEntityimport org.apache.http.client.methods.HttpPostimport org.apache.http.client.methods.HttpRequestBaseimport org.apache.http.util.EntityUtilsimport org.slf4j.Loggerimport org.slf4j.LoggerFactory
/** * 重写FanLibrary,使用面对对象思想 */public class FunRequest extends FanLibrary implements Serializable, Cloneable {
private static final long serialVersionUID = -4153600036943378727L;
static Logger logger = LoggerFactory.getLogger(FunRequest.class)
/** * 请求类型,true为get,false为post */
RequestType requestType
/** * 请求对象 */
HttpRequestBase request
/** * host地址 */
String host = EMPTY
/** * 接口地址 */
String apiName = EMPTY
/** * 请求地址,如果为空则由host和apiname拼接 */
String uri = EMPTY
/** * header集合 */
List<Header> headers = new ArrayList<>()
/** * get参数 */
JSONObject args = new JSONObject()
/** * post参数,表单 */
JSONObject params = new JSONObject()
/** * json参数 */
JSONObject json = new JSONObject()
/** * 响应,若没有这个参数,从将funrequest对象转换成json对象时会自动调用getresponse方法 */
JSONObject response = new JSONObject()
/** * 构造方法 * * @param requestType */ private FunRequest(RequestType requestType) { this.requestType = requestType }
/** * 获取get对象 * * @return */ static FunRequest isGet() { new FunRequest(RequestType.GET) }
/** * 获取post对象 * * @return */ static FunRequest isPost() { new FunRequest(RequestType.POST) }
/** * 设置host * * @param host * @return */ FunRequest setHost(String host) { this.host = host this }
/** * 设置接口地址 * * @param apiName * @return */ FunRequest setApiName(String apiName) { this.apiName = apiName this }
/** * 设置uri * * @param uri * @return */ FunRequest setUri(String uri) { this.uri = uri this }
/** * 添加get参数 * * @param key * @param value * @return */ FunRequest addArgs(Object key, Object value) { args.put(key, value) this }
/** * 添加post参数 * * @param key * @param value * @return */ FunRequest addParam(Object key, Object value) { params.put(key, value) this }
/** * 添加json参数 * * @param key * @param value * @return */ FunRequest addJson(Object key, Object value) { json.put(key, value) this }
/** * 添加header * * @param key * @param value * @return */ FunRequest addHeader(Object key, Object value) { headers << getHeader(key.toString(), value.toString()) this }
/** * 添加header * * @param header * @return */ public FunRequest addHeader(Header header) { headers.add(header) this }
/** * 批量添加header * * @param header * @return */ FunRequest addHeader(List<Header> header) { header.each {h -> headers << h} this }
/** * 增加header中cookies * * @param cookies * @return */ FunRequest addCookies(JSONObject cookies) { headers << getCookies(cookies) this }
FunRequest setHeaders(List<Header> headers) { this.headers.addAll(headers) this }
FunRequest setArgs(JSONObject args) { this.args.putAll(args) this }
FunRequest setParams(JSONObject params) { this.params.putAll(params) this }
FunRequest setJson(JSONObject json) { this.json.putAll(json) this }
/** * 获取请求响应,兼容相关参数方法,不包括file * * @return */ JSONObject getResponse() { response = response.isEmpty() ? getHttpResponse(request == null ? getRequest() : request) : response response }

/** * 获取请求对象 * * @return */ HttpRequestBase getRequest() { if (request != null) request; if (StringUtils.isEmpty(uri)) uri = host + apiName switch (requestType) { case RequestType.GET: request = FanLibrary.getHttpGet(uri, args) break case RequestType.POST: request = !params.isEmpty() ? FanLibrary.getHttpPost(uri + changeJsonToArguments(args), params) : !json.isEmpty() ? getHttpPost(uri + changeJsonToArguments(args), json.toString()) : getHttpPost(uri + changeJsonToArguments(args)) break } for (Header header in headers) { request.addHeader(header) } logger.debug("请求信息:{}", new RequestInfo(this.request).toString()) request }
@Override FunRequest clone() { def fun = new FunRequest() fun.setRequest(cloneRequest(getRequest())) fun }
@Override public String toString() { return "{" + "requestType='" + requestType.getName() + '\'' + ", host='" + host + '\'' + ", apiName='" + apiName + '\'' + ", uri='" + uri + '\'' + ", headers=" + header2Json(headers).toString() + ", args=" + args.toString() + ", params=" + params.toString() + ", json=" + json.toString() + ", response=" + getResponse().toString() + '}'; }

/** * 从requestbase对象从初始化funrequest * @param base * @return */ static FunRequest initFromRequest(HttpRequestBase base) { FunRequest request = null; String method = base.getMethod(); RequestType requestType = RequestType.getRequestType(method); String uri = base.getURI().toString(); List<Header> headers = Arrays.asList(base.getAllHeaders()); if (requestType == requestType.GET) { request = FunRequest.isGet().setUri(uri).setHeaders(headers); } else if (requestType == RequestType.POST || requestType == RequestType.FUN) { HttpPost post = (HttpPost) base; HttpEntity entity = post.getEntity(); String value = entity.getContentType().getValue(); String content = null; try { content = EntityUtils.toString(entity); } catch (IOException e) { logger.error("解析响应失败!", e) fail(); } if (value.equalsIgnoreCase(HttpClientConstant.ContentType_TEXT.getValue()) || value.equalsIgnoreCase(HttpClientConstant.ContentType_JSON.getValue())) { request = FunRequest.isPost().setUri(uri).setHeaders(headers).setJson(JSONObject.fromObject(content)); } else if (value.equalsIgnoreCase(HttpClientConstant.ContentType_FORM.getValue())) { request = FunRequest.isPost().setUri(uri).setHeaders(headers).setParams(getJson(content.split("&"))); } } else { RequestException.fail("不支持的请求类型!"); } return request; }

/** * 拷贝HttpRequestBase对象 * @param base * @return */ static HttpRequestBase cloneRequest(HttpRequestBase base) { return initFromRequest(base).getRequest() }
/** * 保存请求和响应 * @param base * @param response */ public static void save(HttpRequestBase base, JSONObject response) { FunRequest request = initFromRequest(base) request.setResponse(response); Save.info("/request/" + Time.getDate().substring(8) + SPACE_1 + request.getUri().replace(OR, PART), request.toString()); }
}

然后在框架是添加一个key来控制是否保存响应,然后调用保存方法:if (SAVE_KEY) FunRequest.save(request, res);其中,res是响应内容,已经解析为json格式,对于非json格式响应做了兼容。同事在保存路径和保存量也做配置初始化的过程中做了校验,这个太简单就不发了。其中一个header2Json方法是为了解决保存header时候不必须信息太多的问题,内容如下:

    /**     * 将header转成json对象     *     * @param headers     * @return     */    public static JSONObject header2Json(List<Header> headers) {        JSONObject h = new JSONObject();        headers.forEach(x -> h.put(x.getName(), x.getValue()));        return h;    }

这个是内容:{requestType='post', host='', apiName='', uri='https://cn.bing.com/search', headers={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}, args={}, params={"q":"fun"}, json={}, response={"3242":"234"}}

这样做的好处就是,如果想复现某个出现问题的request,直接从文件中读取保存的request信息,借由funrequest类对象即可复现这个请求,还可以跟记录的response做对比。


  • 郑重声明:文章首发于公众号“FunTester”,禁止第三方(腾讯云除外)转载、发表。

技术类文章精选

非技术文章精选

原文作者:FunTester;如有侵权,请联系管理员删除。

下一篇: 如何学习Java基础
请登录后发表评论 登录
全部评论

注册时间:2019-07-07

  • 博文量
    1037
  • 访问量
    420835