All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dadiyang.httpinvoker.mocker.MockRequestor Maven / Gradle / Ivy

There is a newer version: 1.2.4
Show newest version
package com.github.dadiyang.httpinvoker.mocker;

import com.github.dadiyang.httpinvoker.requestor.DefaultHttpRequestor;
import com.github.dadiyang.httpinvoker.requestor.HttpRequest;
import com.github.dadiyang.httpinvoker.requestor.HttpResponse;
import com.github.dadiyang.httpinvoker.requestor.Requestor;
import com.github.dadiyang.httpinvoker.util.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Mock 请求器,使用这个请求器可以配置一些规则,当发起的请求符合这个规则时,直接返回给定的结果而不发起真实请求
 * 

* 没有匹配的规则才发起真实请求 *

* 注:只用于开发环境使用,生产环境千万不要使用此请求器!! * * @author dadiyang * @since 2019-05-31 */ public class MockRequestor implements Requestor { private static final Logger log = LoggerFactory.getLogger(MockRequestor.class); /** * 是否忽略环境警告信息,默认每次使用本请求器时都会打印警告 */ private boolean ignoreWarning; private final List mockRules; private final Requestor realRequestor; public MockRequestor() { this(new ArrayList(), new DefaultHttpRequestor()); } public MockRequestor(List mockRules, Requestor realRequestor) { if (realRequestor == null) { throw new IllegalArgumentException("必须配置一个真实请求的请求器"); } this.mockRules = mockRules; this.realRequestor = realRequestor; log.info("初始化 MOCK 请求器,注意:一般只用于开发环境使用,生产环境千万不要使用此请求器!!"); } public MockRequestor(List mockRules) { this(new ArrayList(mockRules), new DefaultHttpRequestor()); } public void addRule(MockRule rule) { mockRules.add(rule); } @Override public HttpResponse sendRequest(HttpRequest request) throws IOException { ObjectUtils.requireNonNull(request, "请求不能为 null"); ObjectUtils.requireNonNull(request.getUrl(), "请求 url 不能为 null"); if (!ignoreWarning) { log.warn("当前使用 MOCK 请求器,注意:一般只在开发环境使用,生产环境千万不要使用此请求器!!"); } List matchedRule = new LinkedList(); for (MockRule rule : mockRules) { if (isMatch(request, rule)) { matchedRule.add(rule); } } // 没有匹配则发起真实请求 if (matchedRule.isEmpty()) { log.info("请求没有找到对应的 mock,所以发起真实请求: " + request.getUrl()); return realRequestor.sendRequest(request); } if (matchedRule.size() > 1) { List exactlyMatches = new LinkedList(); // 在匹配到的规则器里找url或uri完全匹配的 for (MockRule rule : matchedRule) { if (ObjectUtils.equals(rule.getUrlReg(), request.getUrl()) || ObjectUtils.equals(rule.getUriReg(), getUri(request.getUrl()))) { exactlyMatches.add(rule); } } matchedRule = exactlyMatches; // 如果还是有多个,则抛出异常 if (matchedRule.size() > 1) { throw new IllegalStateException("一个请求匹配到 " + matchedRule.size() + " 个 mock 规则,请确认是否重复添加: " + request.getUrl()); } } MockRule rule = matchedRule.get(0); log.info("mock匹配成功,使用匹配到的规则,请求url: " + request.getUrl() + ", 规则: " + rule); return rule.getResponse(); } private String getUri(String url) { try { return new URL(url).getPath(); } catch (MalformedURLException e) { return url; } } private boolean isMatch(HttpRequest request, MockRule rule) { if (rule == null) { return false; } if (rule.getMethod() != null && !rule.getMethod().isEmpty() && !ObjectUtils.equals(request.getMethod().toUpperCase(), rule.getMethod().toUpperCase())) { log.info("请求方法规则不匹配: requestMethod: " + request.getMethod() + ", ruleMethod: " + rule.getMethod()); return false; } if (!isUrlOrUriMatch(request, rule)) { return false; } if (!isMapMatch(rule.getData(), request.getData())) { log.info("参数规则不匹配: requestData: " + request.getData() + ", ruleData: " + rule.getData()); return false; } if (!ObjectUtils.equals(rule.getBody(), request.getBody())) { log.info("请求体规则不匹配: requestBody: " + request.getBody() + ", ruleBody: " + rule.getBody()); return false; } // 校验 cookie if (!isMapMatch(rule.getCookies(), request.getCookies())) { log.info("Cookie规则不匹配: requestCookies: " + request.getCookies() + ", ruleCookies: " + rule.getCookies()); return false; } // 校验 header if (!isMapMatch(rule.getHeaders(), request.getHeaders())) { log.info("Header规则不匹配: requestHeaders: " + request.getHeaders() + ", ruleHeaders: " + rule.getHeaders()); return false; } // 全部校验通过,则匹配 return true; } private boolean isUrlOrUriMatch(HttpRequest request, MockRule m) { // url 规则 if (m.getUrlReg() != null && !m.getUrlReg().isEmpty()) { boolean urlMatch = isStringMatch(request.getUrl(), m.getUrlReg()); if (!urlMatch) { log.info("url规则不匹配: requestUrl: " + request.getUrl() + ", ruleUrl: " + m.getUrlReg()); return false; } } else if (m.getUriReg() != null && !m.getUriReg().isEmpty()) { // uri 规则 String uri = getUri(request.getUrl()); boolean uriMatch = isStringMatch(uri, m.getUriReg()); if (!uriMatch) { log.info("uri 规则不匹配: requestUri: " + uri + ", ruleUri: " + m.getUriReg()); return false; } } else { log.info("url 和 uri 规则不能同时为空不匹配: requestUrl: " + request.getUrl() + ", ruleUrl: " + m.getUrlReg()); return false; } return true; } private boolean isStringMatch(String uri, String urlReg) { return ObjectUtils.equals(uri, urlReg) || uri.matches(urlReg); } private boolean isMapMatch(Map mapFromMockRule, Map mapFromRequest) { // 无需匹配 if (mapFromMockRule == null || mapFromMockRule.isEmpty()) { return true; } // 请求中没有 cookies if (mapFromRequest == null || mapFromRequest.isEmpty()) { return false; } for (Map.Entry entry : mapFromMockRule.entrySet()) { Object value = mapFromRequest.get(entry.getKey()); // 只要有一个 cookie 与请求不符,则不匹配 if (!ObjectUtils.equals(entry.getValue(), value)) { return false; } } return true; } public void setIgnoreWarning(boolean ignoreWarning) { this.ignoreWarning = ignoreWarning; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy