当前位置: 首页 > news >正文

EasyExcel listener无法通过Autowired注入xxMapper

easyexcel listener无法通过Autowired注入xxMapper

文章目录

  • easyexcel listener无法通过Autowired注入xxMapper
    • bug记录:
    • 解决方案:
    • easyexcel 使用例子
      • controller
      • ServiceImpl
      • listener

bug记录:

productMapper注入一直为null,而procureDetailMapper却正常注入?

@Slf4j
@Component
public class ProductInfoExcelListener<T> extends AnalysisEventListener<T> {/*** 缓存的数据*/private List<ProductEntity> cachedDataList = ListUtils.newArrayList();/*** 存临时表的数据*/
//    private List<ProcureDetailEntity> tempDataList = ListUtils.newArrayList();private final StringBuilder errMsg = new StringBuilder();private boolean hasException = false;private boolean hasNext = true;private IProcureDetailMapper procureDetailMapper;@Autowiredprivate IProductMapper productMapper;public ProductInfoExcelListener(IProcureDetailMapper procureDetailMapper) {this.procureDetailMapper = procureDetailMapper;}// 每解析一行数据就会调用一次该方法 todo@Overridepublic void invoke(T t, AnalysisContext analysisContext) {// 获取行号int index = analysisContext.readRowHolder().getRowIndex() + 1;ProductExcelVo data = (ProductExcelVo) t;String productId = data.getProductId();String productNum = data.getProductNum();String categoryName = data.getCategoryName();String specName = data.getSpecName();if (!StringUtils.hasText(productId)) {hasException = true;setErrMsg(index, ":商品条码不能为空");return;}if (!StringUtils.hasText(productNum)) {hasException = true;setErrMsg(index, ":商品数量不能为空");return;}if (StringUtils.hasText(productNum)) {int productNumInteger = Integer.parseInt(productNum);if (productNumInteger <= 0) {hasException = true;setErrMsg(index, ":商品数量不能小于0");return;}}if (!StringUtils.hasText(categoryName)) {hasException = true;setErrMsg(index, ":分类名称不能为空");return;}//根据商品条码查询对应的分类信息ProductEntity productBaseDByProductId = productMapper.findProductBaseDByProductId(productId);if (productBaseDByProductId == null) {hasException = true;setErrMsg(index, ":该商品不存在");return;}if (!productBaseDByProductId.getCategoryName().equals(categoryName)) {hasException = true;setErrMsg(index, ":该商品的分类名称有误");return;}cachedDataList.add(productBaseDByProductId);log.info("invoke" + index);}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// excel解析完毕以后需要执行的代码
//        saveData()log.info("doAfterAllAnalysed ");}public List getCachedDataList() {return cachedDataList;}private void setErrMsg(int index, String msg) {this.hasNext = false;this.hasException = true;errMsg.append("第").append(index).append(msg);log.error("row {} org data verify failure:{};", index, msg);}public StringBuilder getErrMsg() {return errMsg;}public boolean isHasException() {return hasException;}
}
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureDetailServiceImpl implements IProcureDetailService {private final IProcureDetailMapper procureDetailMapper;@Overridepublic ProductInfo uploadAndParseExcel(MultipartFile file) throws IOException, CustomException {ProductInfoExcelListener<ProductExcelVo> listener = new ProductInfoExcelListener<>(procureDetailMapper);EasyExcel.read(file.getInputStream(),ProductExcelVo.class,listener).sheet().doRead();System.out.println("*******************");System.out.println(listener.getCachedDataList().size() == 0);System.out.println("1111111111111111111");List<ProductEntity> cachedDataList = listener.getCachedDataList();log.info("isHasException:{}", listener.getErrMsg());if(listener.isHasException()){throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), listener.getErrMsg().toString());}for (ProductEntity p: cachedDataList){System.out.println(p.toString());}return null;}
}

springboot在listener和filter中注入mapper会为null?

解决方案:

  1. https://codeleading.com/article/13375080759/
  2. 构造器注入

easyexcel 使用例子

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>

controller

 @Slf4j
@RestController
@RequestMapping("/api-procure/procureController")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureController extends BaseController {private final IProcureDetailService procureDetailService;/*** 上传excel并且校验解析 procure** @param file      excel* @param loginUser 登录用户* @return* @throws Exception*/@PostMapping("/uploadExcel/procure")public Result<ProductInfo> uploadExcelP(@RequestBody MultipartFile file, @LoginUser LoginUserBean loginUser) throws Exception {log.info("upload excel file:{}", file.getName());ProductInfo data = procureDetailService.uploadAndParseExcel(file, loginUser, CommonConstant.Type.PROCURE.getCode());return Result.succeed(data, "上传成功");}
}

ServiceImpl

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ProcureDetailServiceImpl implements IProcureDetailService {private final IProcureDetailMapper procureDetailMapper;@Overridepublic ProductInfo uploadAndParseExcel(MultipartFile file, LoginUserBean loginUser, String type) throws IOException, CustomException {ProductInfoExcelListener<ProductExcelVo> listener = new ProductInfoExcelListener<>(procureDetailMapper, productMapper);EasyExcel.read(file.getInputStream(),ProductExcelVo.class,listener).sheet().doRead();if (listener.getCachedDataList().size() == 0) {throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), "没有有效数据");}List<ProcureDetailEntity> cachedDataList = listener.getCachedDataList();log.info("isHasException:{}", listener.getErrMsg());if (listener.isHasException()) {throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), listener.getErrMsg().toString());}
//        for (ProductEntity p : cachedDataList) {
//            System.out.println(p.toString());
//        }if (cachedDataList == null || cachedDataList.size() == 0) {throw new CustomException(CommonConstant.ErrorConstants.EXCEL_UNKNOWN_ERROR.getCode(), "未检测到有效数据");}String userId = loginUser.getUserId();Date date = new Date();//申请标号采购申请单ID 订单//“P”+YYYYMMDDHHMMSS+6位随机数  “PO”+YYYYMMDDHHMMSS+6位随机数String pattern = "YYYYMMDDHHMMSS";SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);String format = dateFormat.format(date);int i = (int) ((Math.random() * 9 + 1) * 100000);String procureId;if (type.equals(CommonConstant.Type.PROCURE.getCode())) {procureId = "P" + format + i;} else if (type.equals(CommonConstant.Type.ORDER.getCode())) {procureId = "PO" + format + i;} else {procureId = null;log.info("这一步执行到就完蛋了");}//存入t_procure_detail_tmp表procureDetailMapper.batchInsertProcureDetailTempList(procureId, userId, date, cachedDataList);//返回响应实体列表ProductInfo productInfo = new ProductInfo();List<ProcureDetailEntity> list = cachedDataList.stream().map(e -> {e.setProcureId(procureId);return e;}).collect(Collectors.toList());productInfo.setProductList(list);return productInfo;}
}

listener

/*** @description <采购申请解析返回的excel信息监听器>* <p>* <p>* 解析模板导入的数据,对商品条码、分类名称、规格名称校验其有效性是否存在,对数量校验大于0.其数据保存在采购单商品临时表.* @author: zhouchaoyu* @Date: 2023-11-14*/
@Slf4j
@Component
public class ProductInfoExcelListener<T> extends AnalysisEventListener<T> {/*** 缓存的数据*/private List<ProcureDetailEntity> cachedDataList = ListUtils.newArrayList();/*** 存临时表的数据*/
//    private List<ProcureDetailEntity> tempDataList = ListUtils.newArrayList();private final StringBuilder errMsg = new StringBuilder();private boolean hasException = false;private boolean hasNext = true;private IProcureDetailMapper procureDetailMapper;private IProductMapper productMapper;public ProductInfoExcelListener(IProcureDetailMapper procureDetailMapper, IProductMapper productMapper) {this.procureDetailMapper = procureDetailMapper;this.productMapper = productMapper;}// 每解析一行数据就会调用一次该方法 todo@Overridepublic void invoke(T t, AnalysisContext analysisContext) {// 获取行号int index = analysisContext.readRowHolder().getRowIndex() + 1;ProductExcelVo data = (ProductExcelVo) t;String productId = data.getProductId();String productNum = data.getProductNum();String categoryName = data.getCategoryName();String specName = data.getSpecName();if (!StringUtils.hasText(productId)) {hasException = true;setErrMsg(index, ":商品条码不能为空");return;}if (!StringUtils.hasText(productNum)) {hasException = true;setErrMsg(index, ":商品数量不能为空");return;}if (StringUtils.hasText(productNum)) {int productNumInteger = Integer.parseInt(productNum);if (productNumInteger <= 0) {hasException = true;setErrMsg(index, ":商品数量不能小于0");return;}}if (!StringUtils.hasText(categoryName)) {hasException = true;setErrMsg(index, ":分类名称不能为空");return;}//根据商品条码查询对应的分类信息ProductEntity productBaseDByProductId = productMapper.findProductBaseDByProductId(productId);if (productBaseDByProductId == null) {hasException = true;setErrMsg(index, ":该商品不存在");return;}if (!productBaseDByProductId.getCategoryName().equals(categoryName)) {hasException = true;setErrMsg(index, ":该商品的分类名称有误");return;}String uid = IdGenerator.getIdStr() ;ProcureDetailEntity procureDetailEntity = new ProcureDetailEntity();procureDetailEntity.setId(uid);procureDetailEntity.setProductId(productBaseDByProductId.getProductId());procureDetailEntity.setProductNum(Integer.parseInt(productNum));procureDetailEntity.setCategoryId(productBaseDByProductId.getCategoryId());procureDetailEntity.setSpecId(specName);procureDetailEntity.setRowStatus("1");procureDetailEntity.setProductName(productBaseDByProductId.getProductName());procureDetailEntity.setCategoryName(productBaseDByProductId.getCategoryName());procureDetailEntity.setInventoryCount(productBaseDByProductId.getInventoryCount());BigDecimal costPrice = productBaseDByProductId.getCostPrice();BigDecimal totalPrice = costPrice.multiply(new BigDecimal(productNum)).setScale(2, RoundingMode.HALF_UP);procureDetailEntity.setTotalPrice(totalPrice);cachedDataList.add(procureDetailEntity);log.info("invoke" + index);}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// excel解析完毕以后需要执行的代码
//        saveData()log.info("doAfterAllAnalysed ");}public List<ProcureDetailEntity> getCachedDataList() {return cachedDataList;}private void setErrMsg(int index, String msg) {this.hasNext = false;this.hasException = true;errMsg.append("第").append(index).append(msg);log.error("row {} org data verify failure:{};", index, msg);}public StringBuilder getErrMsg() {return errMsg;}public boolean isHasException() {return hasException;}
}

相关文章:

EasyExcel listener无法通过Autowired注入xxMapper

easyexcel listener无法通过Autowired注入xxMapper 文章目录 easyexcel listener无法通过Autowired注入xxMapperbug记录&#xff1a;解决方案&#xff1a;easyexcel 使用例子controllerServiceImpllistener bug记录&#xff1a; productMapper注入一直为null,而procureDetailM…...

Android Spannable 使用​注意事项

1、当前示例中间的 "评论"&#xff0c;使用SpannableStringBuilder实现&#xff0c;点击评论会有高亮效果加粗&#xff0c;但再点击其它Bar时无法恢复默认样式。 2、因为SpannableString或SpannableStringBuilder中的效果是叠加的&#xff0c;恢复默认样式需要先移除…...

Apache访问控制

服务器相关的访问控制 Options指令 Options指令是Apache服务器配置文件中的一个重要指令,它可以用于控制特定目录启用哪些服务器特性。Options指令可以在Apache服务器的核心配置、虚拟主机配置、特定目录配置以及.htaccess文件中使用。 以下是一些常用的服务器特性选项: N…...

二、类与对象(二)

8 this指针 8.1 this指针的引入 我们先来定义一个日期的类Date&#xff1a; #include <iostream> using namespace std; class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout << _year <&l…...

Pytorch从零开始实战10

Pytorch从零开始实战——ResNet-50算法实战 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——ResNet-50算法实战环境准备数据集模型选择开始训练可视化模型预测总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c…...

设计模式-单例模式实战

目录 一、引言二、适用场景三、代码实战饿汉式单例模式懒汉式单例模式双重检查锁定单例模式静态内部类单例模式 四、实际应用举例Runtime解析 五、结论 一、引言 单例模式是一种创建型设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;且提供全局访问点以访问该实例…...

requests库出现AttributeError问题的修复与替代方法

在使用App Engine时&#xff0c;开发者们通常会面临需要发送爬虫ip请求的情况&#xff0c;而Python中的requests库是一个常用的工具&#xff0c;用于处理爬虫ip请求。然而&#xff0c;在某些情况下&#xff0c;开发者可能会遇到一个名为AttributeError的问题&#xff0c;特别是…...

opencv-2D直方图

cv2.calcHist() 是 OpenCV 中用于计算直方图的函数。它可以计算一维或多维直方图&#xff0c;用于分析图像中像素值的分布。 基本的语法如下&#xff1a; hist cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])参数说明&#xff1a; images:…...

读像火箭科学家一样思考笔记06_初学者之心

1. 专业化是目前流行的趋势 1.1. 通才&#xff08;generalist&#xff09;是指博而不精之人 1.2. 懂得的手艺越多&#xff0c;反而会家徒四壁 1.2.1. 希腊谚语 1.3. 这种态度代价很大&#xff0c;它阻断了不同学科思想的交融 2. 组合游戏 2.1. 某个行业的变革可能始于另一…...

中职组网络安全 Server-Hun-1.img Server-Hun-2.img

一串密码 smbuser用户和密码登录ssh还是失败提示需要密钥&#xff0c;尝试ftp登录成功 发现密钥存放在.ssh/下&#xff0c;在kali上生成一个密钥&#xff0c;通过上传到.ssh/下&#xff0c;将其替换掉 使用kali生成密钥 登录成功,但是无法拿到root目录下的flag 获取root用户权限…...

基于区域划分的GaN HEMT 准物理大信号模型

GaN HEMT器件的大信号等效电路模型分为经验基模型和物理基模型。经验基模型具有较高精度但参数提取困难&#xff0c;特别在GaN HEMT器件工艺不稳定的情况下不易应用。相比之下&#xff0c;物理基模型从器件工作机理出发&#xff0c;参数提取相对方便&#xff0c;且更容易更新和…...

laravel引入element-ui后,blade模板中使用elementui时,事件未生效问题(下载element-ui到本地直接引入项目)

背景 重构公司后台项目&#xff0c;使用了dcat-admin&#xff0c;但是dcat-admin有些前端功能不能满足需求。因此引入element-ui进行相关界面的优化 具体流程 1.下载element-ui到本地 2.进入如下目录 打开 node_modules\element-ui\lib 复制index.js 打开 node_modules/ele…...

【计算机网络笔记】路由算法之层次路由

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…...

【华为OD机试python】分糖果【2023 B卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 小明从糖果盒中随意抓一把糖果,每次小明会取出一半的糖果分给同学们。 当糖果不能平均分配时,小明可以选择从糖果盒中(假设盒中糖果足够) 取出一个糖果或放回一个糖果。 小明最少需要多…...

ARM 汇编基础

我们在学习 STM32 的时候几乎没有用到过汇编&#xff0c;可能在学习 UCOS 、 FreeRTOS 等 RTOS 类操作系统移植的时候可能会接触到一点汇编。但是我们在进行嵌入式 Linux 开发的时候是绝 对要掌握基本的 ARM 汇编&#xff0c;因为 Cortex-A 芯片一上电 SP 指针还…...

虹科Pico汽车示波器 | 汽车免拆检修 | 2017款东风本田XR-V车转向助力左右不一致

一、故障现象 一辆2017款东风本田XR-V车&#xff0c;搭载R18ZA发动机&#xff0c;累计行驶里程约为4万km。车主反映&#xff0c;车辆行驶或静止时&#xff0c;向右侧转向比向左侧转向沉重。 二、故障诊断 接车后试车&#xff0c;起动发动机&#xff0c;组合仪表上无故障灯点亮&…...

阿里云服务器ECS经济型e实例优惠99元性能怎么样?

阿里云服务器ECS经济型e实例优惠99元性能怎么样&#xff1f;阿里云服务器优惠99元一年&#xff0c;配置为云服务器ECS经济型e实例&#xff0c;2核2G配置、3M固定带宽和40G ESSD Entry系统盘&#xff0c;CPU采用Intel Xeon Platinum架构处理器&#xff0c;2.5 GHz主频&#xff0…...

vue3引入vuex基础

一&#xff1a;前言 使用 vuex 可以方便我们对数据的统一化管理&#xff0c;便于各组件间数据的传递&#xff0c;定义一个全局对象&#xff0c;在多组件之间进行维护更新。因此&#xff0c;vuex 是在项目开发中很重要的一个部分。接下来让我们一起来看看如何使用 vuex 吧&#…...

C++二维数组中的查找

4. 二维数组中的查找 题目链接 牛客网 题目描述 给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。 Consider the following matrix: [[1, 4, 7, 11, 15],[2, 5, 8, 12, 19],[3, 6, 9, 16, 22],[1…...

【计算思维】蓝桥杯STEMA 科技素养考试真题及解析 2

1、兰兰有一些数字卡片&#xff0c;从 1 到 100 的数字都有&#xff0c;她拿出几张数字卡片按照一定顺序摆放。想一想&#xff0c;第 5 张卡片应该是 A、11 B、12 C、13 D、14 答案&#xff1a;C 2、按照下图的规律&#xff0c;阴影部分应该填 A、 B、 C、 D、 答案&am…...

你知道吗?其实这些都是AI——物流优化系统

物流优化系统 背景介绍 在全球化经济和电子商务快速发展的背景下,物流成为了商业运作的重要环节。高效的物流系统不仅能够降低企业成本,还能提高客户满意度。然而,传统的物流管理方式通常依赖于人工调度和经验决策,难以应对复杂多变的物流需求和庞大的数据处理量。现代科…...

Tidyverse 2.0正式版深度适配手册:从CRAN安装到PDF/HTML自动发布(含内部调试钩子清单)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Tidyverse 2.0正式版核心演进与自动化报告范式转型 Tidyverse 2.0 不再是模块的松散集合&#xff0c;而是一个语义一致、生命周期协同演进的统一生态系统。其核心突破在于引入 lifecycle 驱动的 API 稳…...

为AI智能体注入元认知能力:基于开源模板的架构设计与工程实践

1. 项目概述&#xff1a;一个为AI智能体注入“元认知”能力的开源模板最近在折腾AI智能体开发的朋友&#xff0c;可能都遇到过这样的困境&#xff1a;你精心设计了一个Agent&#xff0c;给了它清晰的指令和强大的工具&#xff0c;但它执行任务时总感觉“缺根弦”。比如&#xf…...

FigmaCN中文插件终极指南:5种用户场景下的完美汉化解决方案

FigmaCN中文插件终极指南&#xff1a;5种用户场景下的完美汉化解决方案 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的英文界面感到困惑&#xff1f;专业术语看不懂&…...

2026年必看:精选靠谱电商公司,购物无忧新选择

随着电商行业的发展进入精细化、全域化运营阶段&#xff0c;品牌对第三方代运营公司的专业度和技术能力要求越来越高。在这样的背景下&#xff0c;我们为大家精选了几家在特定领域或区域市场具备显著特色的电商代运营企业&#xff0c;帮助大家更好地理解当前市场上的优质服务商…...

NoFences:免费开源桌面分区工具终极指南

NoFences&#xff1a;免费开源桌面分区工具终极指南 【免费下载链接】NoFences &#x1f6a7; Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 还在为Windows桌面上杂乱无章的图标而烦恼吗&#xff1f;NoFences是一款完…...

【紧急预警】Tidyverse 2.0.0–2.0.3版本中purrr::map_dfr静默失败漏洞(附已验证patch及CRAN临时降级方案)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;【紧急预警】Tidyverse 2.0.0–2.0.3版本中purrr::map_dfr静默失败漏洞&#xff08;附已验证patch及CRAN临时降级方案&#xff09; purrr::map_dfr 在 Tidyverse 2.0.0 至 2.0.3 版本中存在一个高危静…...

在智能客服场景中利用 Taotoken 多模型能力优化对话 agent 响应

在智能客服场景中利用 Taotoken 多模型能力优化对话 agent 响应 1. 智能客服场景中的模型选型挑战 现代智能客服系统需要处理多样化的用户查询&#xff0c;从简单的FAQ解答到复杂的多轮对话。单一模型往往难以在所有场景下都达到最佳效果。开发者通常面临两个核心问题&#x…...

open-interpreter:用自然语言操控电脑的本地AI助手实战指南

1. 项目概述&#xff1a;当你的电脑拥有了“自然语言”操作系统如果你用过ChatGPT&#xff0c;一定对那种用对话就能完成复杂任务的感觉印象深刻。但很多时候&#xff0c;这种对话被限制在了一个网页对话框里&#xff0c;它知道很多&#xff0c;却无法直接“动手”操作你的电脑…...

破解类风湿关节炎的分子密码:生物标志物全景与高通量检测新策略

一、引言类风湿关节炎的早期诊断与精准治疗长期面临挑战&#xff0c;其核心难题在于该疾病具有高度异质性。单一生物标志物难以全面反映患者体内复杂的免疫网络紊乱与组织破坏进程。随着多因子高通量检测技术的发展&#xff0c;研究者能够在同一份微量样本中同时捕捉数十种病理…...