未传文件时如何调整try-catch避免异常并正常读取AJAX参数
问题根因
无文件请求抛出异常的核心原因有两点:
- 请求未携带上传文件时,框架注入的文件对象
myFile、文件名属性myFileFileName为null,直接操作这两个对象会触发空指针 - 原代码将普通参数处理和文件处理逻辑强绑定,要么注释掉文件逻辑废掉上传能力,要么无文件时直接报错
修改方案
核心思路是将文件处理逻辑和普通参数处理逻辑完全解耦,仅在检测到有效上传文件时才执行文件存储操作,普通参数无论是否有文件上传都会正常解析。
修改后的完整代码
public String upload_via_ajax() { try { String tempDir = System.getProperty("java.io.tmpdir"); String html = "inside upload via ajax"; // 仅当文件、文件名均非空时,才执行文件上传逻辑 if (myFile != null && myFileFileName != null && !myFileFileName.trim().isEmpty()) { try { // 兼容无后缀文件名,避免字符串截取越界 int dotIndex = myFileFileName.lastIndexOf("."); String destFileName = dotIndex > 0 ? myFileFileName.substring(0, dotIndex) + ".csv" : myFileFileName + ".csv"; File destFile = new File(tempDir, destFileName); FileUtils.copyFile(myFile, destFile); getRequest().getSession().setAttribute("filePath", destFile.getPath()); html = "file uploaded"; } catch (IOException e) { html = "error in uploading file"; e.printStackTrace(); } } // 普通参数处理逻辑独立,不受文件存在与否影响 // POUR REFERENCE DECLARATION if(annee != null) { TableReferentielDto tableReferentielDto = new TableReferentielDto(); tableReferentielDto.setId(Long.parseLong(annee)); TableReferentielDto anneeLabel = (TableReferentielDto) tableReferentielGetByIdCmd.execute(tableReferentielDto); getRequest().getSession().setAttribute("annee", anneeLabel.getLibelle()); } // POUR DATE DEBUT DECLARATION if(moisDebutDeclaration != null){ getRequest().getSession().setAttribute("moisDebutDeclaration", moisDebutDeclaration); } // POUR DATE FIN DECLARATION if(moisFinDeclaration != null){ getRequest().getSession().setAttribute("moisFinDeclaration", moisFinDeclaration); } // ID POLICE if(idPolice != null){ getRequest().getSession().setAttribute("idPolice", idPolice); } if(idTabPrest != null) { getRequest().getSession().setAttribute("idTabPrest", idTabPrest); } if(idTabTarif != null){ getRequest().getSession().setAttribute("idTabTarif", idTabTarif); } return SUCCESS; } catch (Exception e) { e.printStackTrace(); // 禁止吞异常,保留栈信息方便排查问题 return SUCCESS; } }
配置校验
如果加完非空判断后无文件请求仍报错,检查框架配置:
- 如果你用的是Struts2框架,默认的
fileUpload拦截器本身不强制要求请求必须携带文件,不要给Action中的myFile、myFileFileName字段加必填校验 - 前端AJAX无论是否传文件,都统一用
FormData对象封装参数即可,不需要为无文件场景单独切换请求编码格式 - 不要把普通参数的解析逻辑放在文件操作的try块内部,避免文件操作报错阻断正常参数的存储流程
内容的提问来源于stack exchange,提问作者Da reen
相关产品推荐
相关产品推荐

