通过webAsyncTask实现异步请求
场景:图片是上传到腾讯云cos,上传后需要经过腾讯云的审核,审核后才能获取上传结果,主线程等待结果会占用大量的系统资源。
解决方案:通过异步请求来处理,所谓异步请求,就是在当前线程调用之后直接返回,继续处理其余任务,当前调用处理成功之后再经过一个回调线程来处理返回结果。
我们通过实现Callable接口的call方法来定义Web请求返回结果的任务,并通过WebAsyncTask来执行任务,当调用任务以后立即返回,即可并行执行其他任务,最终当webAsyncTask执行完成以后,Web请求获得返回,详情如下:
代码:
@ResponseBody public WebAsyncTask<RespDTO> fs_out_files_upload(HttpServletRequest request) throws Exception { RespDTO baseRespDTO = RespDTO.getInstance(null); MultipartFile fileList = ((MultipartHttpServletRequest) request).getFile("file"); log.info("外部线程:" + Thread.currentThread().getName()); Callable<RespDTO> result = () -> { String requestId= IdUtil.fastSimpleUUID(); MDC.put("requestId", requestId); log.info("内部线程:" + Thread.currentThread().getName()); try { return commonFileService.fsOutFilesUpload(fileList); } catch (Exception e) { log.error("上传文件文件异常", e); } log.info("内部线程返回:" + Thread.currentThread().getName()); baseRespDTO.setMsg("处理失败"); return baseRespDTO; }; WebAsyncTask<RespDTO> wat = new WebAsyncTask<RespDTO>(5000L, result); wat.onTimeout(() -> { log.error("文件上传超时,内部线程:" + Thread.currentThread().getName()); baseRespDTO.setMsg("处理失败,超时"); baseRespDTO.setSubMsg("文件上传失败"); return baseRespDTO; }); wat.onError(() -> { // 错误回调 log.error("文件上传发生错误,内部线程:" + Thread.currentThread().getName()); baseRespDTO.setMsg("处理失败,上传出错"); baseRespDTO.setSubMsg("文件上传失败"); return baseRespDTO; }); return wat; } }