Spring Batch处理MultipartFile报错:'reader处于strict模式'
解决Spring Batch FlatFileItemReader的"strict mode"错误
嘿,我来帮你搞定这个报错!你遇到的问题核心在于FlatFileItemReader默认开启了strict模式,而你的代码里犯了一个常见的小错误:直接用上传文件的原文件名创建了File对象,但这个文件在服务器的文件系统里根本不存在——因为MultipartFile是前端上传到内存里的文件,你还没把它写入磁盘呢!
先看你代码里的问题点
这段代码是问题根源:
File fileToImport = new File(batchFile[0].getOriginalFilename()); String pathToFile = fileToImport.getAbsolutePath(); reader.setResource(new FileSystemResource(pathToFile));
new File(batchFile[0].getOriginalFilename())只是创建了一个指向当前项目运行目录下、和上传文件同名的空File对象,这个文件并没有实际内容,甚至可能根本不存在。而strict模式下,FlatFileItemReader会严格检查文件是否存在、是否可读,一旦不满足就抛出你看到的错误。
给你三个解决方案,按需选择
方案1:写入临时文件(推荐,适合大文件)
先把上传的文件写入服务器的临时目录,再让reader读取这个真实存在的文件:
public @ResponseBody void customerBatchUpload(@RequestParam("batchFile") MultipartFile[] batchFile) throws Exception { MultipartFile uploadFile = batchFile[0]; // 创建临时文件,自动生成唯一前缀,避免重名 File tempFile = File.createTempFile("batch-customer-", "." + FilenameUtils.getExtension(uploadFile.getOriginalFilename())); // 把上传文件的内容写入临时文件 uploadFile.transferTo(tempFile); // 初始化FlatFileItemReader FlatFileItemReader<Customer> reader = new FlatFileItemReader<>(); reader.setResource(new FileSystemResource(tempFile)); // 必须配置LineMapper,不然没法解析文件内容 reader.setLineMapper(new DefaultLineMapper<Customer>() {{ setLineTokenizer(new DelimitedLineTokenizer() {{ // 替换成你文件里的字段名 setNames("id", "name", "phone", "email"); }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<Customer>() {{ setTargetType(Customer.class); }}); }}); reader.open(new ExecutionContext()); // 开始读取处理... Customer customer; while ((customer = reader.read()) != null) { // 处理每个Customer对象 } // 最后记得标记临时文件在JVM退出时删除,避免磁盘占用 tempFile.deleteOnExit(); }
方案2:直接读取内存中的文件(适合小文件)
如果上传的文件不大,可以直接把MultipartFile的字节流转换成ByteArrayResource,不用写入磁盘,效率更高:
public @ResponseBody void customerBatchUpload(@RequestParam("batchFile") MultipartFile[] batchFile) throws Exception { MultipartFile uploadFile = batchFile[0]; // 直接用ByteArrayResource包装上传文件的字节流 ByteArrayResource fileResource = new ByteArrayResource(uploadFile.getBytes()); FlatFileItemReader<Customer> reader = new FlatFileItemReader<>(); reader.setResource(fileResource); // 同样配置LineMapper // ... reader.open(new ExecutionContext()); // 读取处理逻辑... }
方案3:关闭strict模式(仅临时测试用,不推荐生产)
如果你只是想临时绕过这个检查,可以关闭strict模式,但这会隐藏真实的文件不存在、不可读等问题,生产环境绝对不要用:
reader.setStrict(false);
内容的提问来源于stack exchange,提问作者Jacel
相关产品推荐
相关产品推荐

