因为迁移的生产环境,在新的服务器发生了之前没有遇到的问题,这种问题是在异步文件上传的时候才会出现
错误信息如下
16:17:50.009 ERROR c.w.einv.minio.service.impl.MinioFileServiceImpl - 文件上传错误!
java.io.FileNotFoundException: /application/acc-statement-server/tmp/work/Tomcat/localhost/ROOT/upload_82aa4ea1_6e02_47b7_8d1f_26e9bd20c0ca_00000005.tmp (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.getInputStream(DiskFileItem.java:198)
at org.apache.catalina.core.ApplicationPart.getInputStream(ApplicationPart.java:100)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.getInputStream(StandardMultipartHttpServletRequest.java:254)
at com.whty.einv.minio.service.impl.MinioFileServiceImpl.upload(MinioFileServiceImpl.java:123)
at com.whty.acc.statement.dubbo.task.FileHandlerTaskImpl.handleIndividualTaxFile(FileHandlerTaskImpl.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
参考【报错记录】SpringBoot中MultipartFile上传报/tmp/tomcat.***.tmp (No such file or directory)
/tmp/tomcat /work/Tomcat/localhost/RooT/upload_*****.tmp (No such file or directory)
下面是异步操作的代码,注意这里的File要转换为java.io.File
@Async
@Override
public void handleIndividualTaxFile(String dataId, File file, File pic) {
log.info("===>异步处理更新个税申报状态文件开始<===");
AccIndividualTaxDeclare individualTaxDeclare = new AccIndividualTaxDeclare();
log.info("===>A1.处理综合所得预扣预缴表文件开始<===");
// 处理综合所得预扣预缴表文件
if (!CheckEmptyUtil.isEmpty(file)) {
log.info("RPA提供的file文件大小:{},文件名{}", file.getTotalSpace(), file.getName());
String withholdingFormPath = INDIVIDUAL_TAX_FOLDER + dataId + CommonSettingConstants.Split.SLASH + file.getName();
minioFileService.upload(bucketName, file, withholdingFormPath);
// 获取文件的完整路径
String withholdingFormUrl = this.getHttpUrl(endpointO, bucketName, withholdingFormPath);
individualTaxDeclare.setWithholdingFormUrl(withholdingFormUrl);
log.info("综合所得预扣预缴表url:{}", withholdingFormUrl);
所以需要在前面做更正
@WebLog
@ApiOperation("报税状态更新(新RPA调用)")
@PostMapping("/status/new")
public ResponseResult<?> updateTaxDeclareStatusNew(MultipartFile file, MultipartFile pic,
@Validated UpdateTaxReq updateTaxReq, BindingResult bindingResult) {
// 字段非空和规则的基本校验
if (bindingResult.hasErrors()) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
fieldErrors.forEach(e -> log.error("校验未通过字段:{},原因:{}", e.getField(), e.getDefaultMessage()));
return new ResponseResult<>(false, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
}
log.info("新RPA调用报税状态更新接口请求参数:{}", JSON.toJSONString(updateTaxReq));
ResponseResult<?> rs;
try {
// 文件
File excelFile = null;
if (!CheckEmptyUtil.isEmpty(file)){
String fileName = file.getOriginalFilename();
String prefix = fileName.substring(fileName.lastIndexOf("."));
excelFile = File.createTempFile(System.currentTimeMillis() + "", prefix);
file.transferTo(excelFile);
}
// 图片
File picFile = null;
if (!CheckEmptyUtil.isEmpty(pic)){
String picFileName = pic.getOriginalFilename();
String picPrefix = picFileName.substring(picFileName.lastIndexOf("."));
picFile = File.createTempFile(System.currentTimeMillis() + "", picPrefix);
pic.transferTo(picFile);
}
//
taxDeclarationService.updateTaxDeclareStatusForRpa(updateTaxReq, excelFile, picFile);
中间还有一个代码,可以看到
@Override
public void updateTaxDeclareStatusForRpa(UpdateTaxReq updateTaxReq, File file, File pic) {
// 参数
String dataId = updateTaxReq.getDataId();
String reportCode = updateTaxReq.getReportCode();
String taxType = updateTaxReq.getTaxType();
{
// 个税
AccIndividualTaxDeclare individualTaxDeclare = new AccIndividualTaxDeclare();
switch (reportCode) {
case StatementConstants.RpaReturnCode.DECLARE_SUCCESS:
individualTaxDeclare.setDeclareStatus(StatementConstants.DeclareStatus.DECLARED_SUCCESS);
fileHandlerTask.handleIndividualTaxFile(dataId, file, pic);
注意spring中tomcat的路径配置,当controller文件生成后,会把文件暂存在/application/acc-statement-server/tmp
中
server:
port: 8354
tomcat:
basedir: /application/acc-statement-server/tmp
uri-encoding: UTF-8
#最小空闲 socket 线程数(最小线程数)
min-spare-threads: 100
#最大空闲 socket 线程数
max-spare-threads: 300
#初始化的时候就初始化核心线程
prestartminSpareThreads: true
#最大线程数
max-threads: 300
#最大链接数
max-connections: 10000
#线程空闲时间
max-idle-time: 60000
address: 0.0.0.0