/**
* 异步处理嵌套图片及后续更新
*/
//获取当前请求上下文和租户信息,以便在线程池中复用
/**
* RequestContextHolder.getRequestAttributes():
* 从当前线程的 ThreadLocal 中取出 Spring MVC 持有的 RequestAttributes,包含了 HttpServletRequest、HttpServletResponse 等信息。
*
* requireNonNull(...):确保获取到的上下文不为 null,否则立刻抛出 NPE,避免后续空指针。
* getRequest():拿到底层的 HttpServletRequest 对象,以便取出当前用户等信息。
*/
HttpServletRequest request = ((ServletRequestAttributes) Objects
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
String username = SessionUtil.getUsername(request);//从token中解析出用户名
//完整的请求上下文,后面在线程池里要重新注入
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//多租户场景中当前使用的数据源标识,也要在线程里重新推入
String tenantCode = DynamicDataSourceContextHolder.peek(); // 主线程中获取
// 创建一个异步任务
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
try {
// 设置请求上下文
/**
* 将主线程中保存下来的 requestAttributes 重新绑定到当前异步线程,
* 让业务中依赖 RequestContextHolder 的工具(如 SessionUtil、某些 AOP)能正常工作。
*/
RequestContextHolder.setRequestAttributes(requestAttributes);
/**
* 恢复主线程的多租户数据源标识,确保后续数据库操作都跑在正确的库/schema 上。
*/
DynamicDataSourceContextHolder.push(tenantCode);
// 执行耗时操作
Map<Integer, File> imageFileMap = new HashMap<>();
String path = OsUtils.isWindows() ? "D:/upload/excel/" : "/opt";//拼接请求路径
log.info("path: {}", path);
//提取Excel中嵌入的图片
ExcelImportImgExtractor.readXlsxEmbeddedImages(file.getInputStream(), path, imageFileMap);
//遍历每张图片,上传并更新用户,发送消息
for (Integer rowNum : imageFileMap.keySet()) {
File imageFile = imageFileMap.get(rowNum);
SysUserExcelImportVO excel = excelVOList.get(rowNum - 1);//VO列表从0开始,Excel行号从1开始,需要减1
SysUser sysUser = baseMapper.selectById(excel.getUserId());//查出对应的SysUser
if (sysUser == null) continue;
String url = "";
try {
url = uploadFile(imageFile);//上传图片
sysUser.setFaceImage(url);//更新用户数据
} catch (IOException e) {
log.error("{}人脸上传失败", excel.getUsername(), e);
}
sysUser.setUpdateBy(username);
baseMapper.updateById(sysUser); // 确保 mapper 已注入
//修改发送给园区各个系统的消息,构造并发送MQ消息到各个系统
MqParkUser mqParkUser = new MqParkUser();
SysUserDTO sysUserDTO = excel.getSysUserDTO();
sysUserDTO.setFaceImage(url);
mqParkUser.setType(MqEnum.MessageType.UPDATE.getType());
BeanUtils.copyProperties(sysUserDTO, mqParkUser);
mqParkUser.setRoleIds(sysUserDTO.getRole());
mqMessageProducer.sendParkUserMessage(DynamicDataSourceContextHolder.peek(), mqParkUser);
}
} catch (Exception e) {
log.error("【异步任务异常】", e); // 主动打印日志
} finally {
// 清理线程局部变量,避免内存泄漏
RequestContextHolder.resetRequestAttributes();
}
return null;
}, taskExecutor);
使用CompletableFuture异步上传图片
最新推荐文章于 2025-12-03 14:55:31 发布
169万+

被折叠的 条评论
为什么被折叠?



