⽂件异步导⼊及springbootMultipartFile上传⽂件后@Async异步处理。。。第⼀个问题
当excel中的数据量⽐较⼤时,java后台解析的过程可能要持续很久,但是⼜不需要⽤户去进⾏等待,这时就考虑⽂件的异步导⼊
⽂件异步⽅法的实现有着⼏种实现⽅式,这⾥是通过指定异步线程池实现的,即@Async(“线程池名称”)标注异步⽅法。
然⽽,在经过测试时发现,该标注的注解也都标注了,但是就是不能实现异步效果。
⼏经波折,发现异步⽅法可以调⽤⾮异步⽅法,是可以实现异步效果;⽽先是⾮异步⽅法去调⽤异步⽅法,这样就会失效。这⾥所说的是在同⼀个java类⾥⾯。
⽽在不同的java类⾥⾯,就不存在上⾯的问题
第⼆个问题
使⽤了异步⽅法,通过controller接收⽂件,service层进⾏处理,这时controller已经将执⾏成功的结果返回,剩下的就是service层中去进⾏解析⼊库,结果,万万没想到,在service中报了⼀个错
NoSuchFileException: D:\UserData\Temp\undertow.1407321862395783323.8400\undertow4517937229384702645upload
Controller中的⽅法
@PostMapping("/test")
public R<String>test(MultipartFile file){
return R.success("导⼊成功");
}
Service中的⽅法
@Async("asyncImportExecutor")
public void test(MultipartFile file){
try{
.sheet().doRead();
}catch(Exception ex){
<("[test]异步导⼊异常:", ex);
}
}
看到这个异常NoSuchFileException后就⼀脸懵逼,测试是通过postman进⾏的,就开始怀疑postman的问题,已经排查后postman、路径啥的都没有问题,异步调⽤的流程也是ok的
然后就想这个异常的提⽰,就是不到⽂件,根据打印出来的⽇志去本地也确实没有到。后来就有了下⾯的写法
Controller中的⽅法
@PostMapping("/test")
public R<String>test(MultipartFile file){
try{
}catch(IOException e){
springboot是啥<("[test]异常⽇志:", e);
return R.fail("导⼊失败");
}
return R.success("导⼊成功");
}
Service中的⽅法
@Async("asyncImportExecutor")
public void test(InputStream file){
try{
.sheet().doRead();
}catch(Exception ex){
<("[test]异步导⼊异常:", ex);
}
}
这样就不报错了。。。
后来就进⾏debug调试,发现临时⽂件是controller层中的MultipartFile对象⽣成,⼀直在写同步⽅法,也没注意这个MultipartFile对象会⽣成临时⽂件。后来发现这个controller中返回结果后,临时⽂件也就没有了。
错误总结:
因为使⽤的是异步⽅法,这样就会有⼀个主线程和⼀个异步线程。在上传⽂件后会形成MultipartFile类型的实例,同时⽣成临时⽂件,此时是在主线程中。MultipartFile的实例交给异步线程处理后,该临时⽂件会被springboot(spring)销毁,在异步线程中去getInputStream就会出现上⾯的异常。
⽽在下⾯的写法是将InputStream流作为了⼊参,就不会产⽣不到⽂件的情况。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论