restful接口模拟并发请求测试 支持导出测试结果到excel http请求 和导出excel用了hutool工具类 5.*版本
效果:
1.顶层的接口
public interface RequestService { /** * 返回测试结果 * @param requestVo * @return */ List<ResponseVo> doRequest(RequestVo requestVo); /** * 导出测试结果 * @param requestVo */ void doExportRequest(RequestVo requestVo); }
--------------------------------------------------------------------------------------------------------------------------------------------------------
2.抽象类
public abstract class AbstactRequestServiceImpl implements RequestService { @Override public abstract List<ResponseVo> doRequest(RequestVo requestVo); @Override public abstract void doExportRequest(RequestVo requestVo); void downLoadExcel(List<ResponseVo> list){ HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); try { FileUtil.downloadExcel(BuildUtil.buildListMap(list), resp, "测试结果"); } catch (IOException e) { e.printStackTrace(); } } List<ResponseVo> buildResponseList(List<Future<ResponseVo>> resultList){ List<ResponseVo> list=new ArrayList<>(); for(Future<ResponseVo> future:resultList){ try { list.add(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } return list; } }
--------------------------------------------------------------------------------------------------------------------------------------------------------
实现类
/** * @author dhc */ public class GetRequestServiceImpl extends AbstactRequestServiceImpl { private ThreadPoolTaskExecutor threadPoolTaskExecutor; public GetRequestServiceImpl(ThreadPoolTaskExecutor threadPoolTaskExecutor) { this.threadPoolTaskExecutor = threadPoolTaskExecutor; } /** * 请求次数要大于并发次数才会执行 * @param requestVo * @return */ @Override public List<ResponseVo> doRequest(RequestVo requestVo) { int count =requestVo.getRequestCount(); int threadCount = requestVo.getThreadCount(); CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount); List<Future<ResponseVo>> resultList = new ArrayList<Future<ResponseVo>>(); return getResponseVoList(count,threadCount,resultList,requestVo,cyclicBarrier); } /** * 导出结果 **/ @Override public void doExportRequest(RequestVo requestVo) { int count =requestVo.getRequestCount(); int threadCount = requestVo.getThreadCount(); CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount); List<Future<ResponseVo>> resultList = new ArrayList<Future<ResponseVo>>(); List<ResponseVo> responseVos=getResponseVoList(count,threadCount,resultList,requestVo,cyclicBarrier); downLoadExcel(responseVos); } private List<ResponseVo> getResponseVoList(Integer count,Integer threadCount,List<Future<ResponseVo>> resultList,RequestVo requestVo,CyclicBarrier cyclicBarrier){ //请求次数要能被线程数整除 List<ResponseVo> list=new ArrayList<>(); if (threadCount != 0 && count > threadCount && count % threadCount == 0) { //模拟并发 for (int i = 0; i < count; i++) { resultList.add(threadPoolTaskExecutor.submit(new DoRequestTask(requestVo, cyclicBarrier))); } if(resultList.size()>0){ list.addAll(buildResponseList(resultList)); } } else { //非并发请求 for (int i = 0; i < count; i++) { list.add(DoRequest.doGetRequest(requestVo)); } } return list; } }
--------------------------------------------------------------------------------------------------------------------------------------------------------
任务类
public class DoRequestTask implements Callable { private RequestVo requestVo; private CyclicBarrier cyclicBarrier; public DoRequestTask(RequestVo requestVo, CyclicBarrier cyclicBarrier) { this.requestVo = requestVo; this.cyclicBarrier = cyclicBarrier; } @Override public ResponseVo call() { try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } String requestType= requestVo.getRequestType(); if(HappyHttpConstant.POST.equals(requestType)){ return DoRequest.doPostRequest(requestVo); }else if(HappyHttpConstant.GET.equals(requestType)){ return DoRequest.doGetRequest(requestVo); } return null; } }
工具类
--------------------------------------------------------------------------------------------------------------------------------------------------------
@Component public class DoRequest { /** * 具体执行get请求 * @param requestVo * @return */ public static ResponseVo doGetRequest(RequestVo requestVo){ ResponseVo responseVo=new ResponseVo(); try { HttpRequest httpRequest = new HttpRequest(requestVo.getUrl()); Map<String, String> headers = new HashMap<>(3); BuildUtil.buildHeaders(headers, requestVo); Long start = System.currentTimeMillis(); HttpResponse httpResponse = httpRequest.execute(); Long end = System.currentTimeMillis(); responseVo.setTimeCount(end-start); responseVo.setStatus(httpResponse.getStatus()); buildResponseVo(requestVo,responseVo,httpResponse.body()); }catch (Exception e){ System.out.println("请求路径:"+requestVo.getUrl()+"请求异常:"+e.getMessage()); responseVo.setException(e.getMessage()); } return responseVo; } /** * 具体执行get请求 * @param requestVo * @return */ public static ResponseVo doPostRequest(RequestVo requestVo){ ResponseVo responseVo=new ResponseVo(); try { Map<String, String> headers = new HashMap<>(3); Long start = System.currentTimeMillis(); String result = HttpRequest.post(requestVo.getUrl()).addHeaders(BuildUtil.buildHeaders(headers, requestVo)) .body(requestVo.getRequestParam().toJSONString()).timeout(5000).execute().body(); Long end = System.currentTimeMillis(); responseVo.setTimeCount(end-start); responseVo.setStatus(getCode(result)); buildResponseVo(requestVo,responseVo,result); }catch (Exception e){ System.out.println("请求路径:"+requestVo.getUrl()+"请求异常:"+e.getMessage()); responseVo.setException(e.getMessage()); } return responseVo; } private static Integer getCode(String result){ if(null==result||"".equals(result)){ return HttpCode.ERRO; } JSONObject jsonObject = JSONObject.parseObject(result); Integer code = jsonObject.getInteger("code"); return code; } private static void buildResponseVo(RequestVo requestVo,ResponseVo responseVo,String body){ responseVo.setBody(body); responseVo.setUrl(requestVo.getUrl()); responseVo.setCurrentThread(Thread.currentThread().getName()); responseVo.setCurrentTime(DateUtil.now()); responseVo.setRequestType(requestVo.getRequestType()); } }
--------------------------------------------------------------------------------------------------------------------------------------------------------
工厂类
/** * 工厂 */ public class RequestServiceFactory { private static final Map<String,RequestService> requestServiceMap=new ConcurrentHashMap<>(8); private RequestServiceFactory(ThreadPoolTaskExecutor threadPoolTaskExecutor){this.threadPoolTaskExecutor=threadPoolTaskExecutor;} private static volatile RequestServiceFactory requestServiceFactory; private ThreadPoolTaskExecutor threadPoolTaskExecutor; /** * 双重效验单例模式 * @return requestServiceFactory */ public static RequestServiceFactory getNewInstance(ThreadPoolTaskExecutor threadPoolTaskExecutor){ if (requestServiceFactory == null) { synchronized (RequestServiceFactory.class){ if (null == requestServiceFactory) { requestServiceFactory = new RequestServiceFactory(threadPoolTaskExecutor); } } } return requestServiceFactory; } public List<ResponseVo> doRequest(RequestVo requestVo){ RequestService requestService; List<ResponseVo> responseVos; if (requestServiceMap.size() > 0) { requestService = requestServiceMap.get(requestVo.getRequestType()); if (null != requestService) { responseVos = requestService.doRequest(requestVo); return responseVos; } requestService = getRequestService(requestVo.getRequestType()); responseVos = requestService.doRequest(requestVo); requestServiceMap.put(requestVo.getRequestType(), requestService); return responseVos; } else { requestService = getRequestService(requestVo.getRequestType()); requestServiceMap.put(requestVo.getRequestType(), requestService); return requestService.doRequest(requestVo); } } public void doExportRequest(RequestVo requestVo){ RequestService requestService; if (requestServiceMap.size() > 0) { requestService = requestServiceMap.get(requestVo.getRequestType()); if (null != requestService) { requestService.doExportRequest(requestVo); } requestService = getRequestService(requestVo.getRequestType()); requestService.doExportRequest(requestVo); requestServiceMap.put(requestVo.getRequestType(), requestService); } else { requestService = getRequestService(requestVo.getRequestType()); requestServiceMap.put(requestVo.getRequestType(), requestService); requestService.doExportRequest(requestVo); } } private RequestService getRequestService(String type){ switch (type) { case HappyHttpConstant.DELET: // return new DeleteRequestServiceImpl(this.threadPoolTaskExecutor); case HappyHttpConstant.GET: return new GetRequestServiceImpl(this.threadPoolTaskExecutor); case HappyHttpConstant.PUT: // return new PutRequestServiceImpl(this.threadPoolTaskExecutor); case HappyHttpConstant.POST: // return new PostReuqestServiceImpl(this.threadPoolTaskExecutor); default: // return new PostReuqestServiceImpl(this.threadPoolTaskExecutor); } } }
--------------------------------------------------------------------------------------------------------------------------------------------------------
controller层
@RestController @RequestMapping("/test") public class TestConroller { @Resource(name = "threadPoolTaskExecutor") private ThreadPoolTaskExecutor threadPoolTaskExecutor; @PostMapping("/do") @ApiOperation("测试接口(非导出结果)") public Result doTestUrl(@RequestBody RequestVo requestVo){ Optional<RequestVo> optional = Optional.ofNullable(requestVo).filter(requestVo1 -> requestVo1.getRequestType() != null && !"".equals(requestVo1)) .filter(requestVo1 -> null != requestVo1.getUrl() && !"".equals(requestVo1.getUrl())); if(!optional.isPresent()){ return Result.failure("请检查参数"); } List<ResponseVo> responseVoList=RequestServiceFactory.getNewInstance(threadPoolTaskExecutor).doRequest(requestVo); return requestVo.isExcel() ? null : Result.success(responseVoList); } @PostMapping("/doExport") @ApiOperation("测试接口(导出结果)") public void doTestUrlExport(@RequestBody RequestVo requestVo)throws Exception{ Optional<RequestVo> optional = Optional.ofNullable(requestVo).filter(requestVo1 -> requestVo1.getRequestType() != null && !"".equals(requestVo1)) .filter(requestVo1 -> null != requestVo1.getUrl() && !"".equals(requestVo1.getUrl())); if(!optional.isPresent()){ throw new Exception("请检查参数"); } RequestServiceFactory.getNewInstance(threadPoolTaskExecutor).doExportRequest(requestVo); } }