下面是该拦截器的intercept方法:
public String intercept(ActionInvocation invocation) throws Exception { ActionContext ac = invocation.getInvocationContext();//获取ActionContext对象 //获取request对象 HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST); //判断是否是文件上传请求 if (!(request instanceof MultiPartRequestWrapper)) { if (LOG.isDebugEnabled()) { ActionProxy proxy = invocation.getProxy(); LOG.debug(getTextMessage("struts.messages.bypass.request", new Object[]{proxy.getNamespace(), proxy.getActionName()}, ac.getLocale())); } //如果不是则直接调用下一个拦截器,因为不需要处理文件上传 return invocation.invoke(); } ValidationAware validation = null; Object action = invocation.getAction();//获取当前Action对象 //判断有无实现ValidationAware接口,当Action继承自ActionSupport类时是实现了该接口的 if (action instanceof ValidationAware) { validation = (ValidationAware) action; } //前面说了文件上传时request类型就是MultiPartRequestWrapper MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; //判断文件上传是否有错误,也就是是否符合上面的三个上传条件 if (multiWrapper.hasErrors()) { for (String error : multiWrapper.getErrors()) { if (validation != null) {//有错误则添加ActionError,注意validation就是当前Action对象 validation.addActionError(error); } LOG.warn(error); } } //获取上传文件参数名(input的name属性值)枚举,因为struts2支持一欠上传多个文件 Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {//迭代 // 当前文件参数名 String inputName = (String) fileParameterNames.nextElement(); // 获取上传文件类型,因为多个文件上传input的name属性可以相同,所以这里是数组 String[] contentType = multiWrapper.getContentTypes(inputName); if (isNonEmpty(contentType)) { // 获取上传文件的真实名称(在客户端文件系统中的名称),至于返回值为什么是数组与上同理 String[] fileName = multiWrapper.getFileNames(inputName); if (isNonEmpty(fileName)) { // 获取上传的文件 File[] files = multiWrapper.getFiles(inputName); if (files != null && files.length > 0) { List<File> acceptedFiles = new ArrayList<File>(files.length); List<String> acceptedContentTypes = new ArrayList<String>(files.length); List<String> acceptedFileNames = new ArrayList<String>(files.length); String contentTypeName = inputName + "ContentType"; String fileNameName = inputName + "FileName";//这时就是文件上传时接收文件类型与文件名称固定写法的原因 //迭代文件数组 for (int index = 0; index < files.length; index++) { //判断该文件是否合法,如果合法则添加到合法集合中 if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation, ac.getLocale())) { acceptedFiles.add(files[index]); acceptedContentTypes.add(contentType[index]); acceptedFileNames.add(fileName[index]); } } //如果合法文件集合不为空 if (!acceptedFiles.isEmpty()) { Map<String, Object> params = ac.getParameters(); //将上传的文件,文件类型,文件名称存储到ActionContext的parameters Map中 params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); } } } else { LOG.warn(getTextMessage(action, "struts.messages.invalid.file", new Object[]{inputName}, ac.getLocale())); } } else { LOG.warn(getTextMessage(action, "struts.messages.invalid.content.type", new Object[]{inputName}, ac.getLocale())); } } // 调用下一个拦截器,当然也调用了Action String result = invocation.invoke(); // 当Action执行完毕,拦截器执行依次返回又执行到该拦截器,清理文件上传时的临时文件 fileParameterNames = multiWrapper.getFileParameterNames(); while (fileParameterNames != null && fileParameterNames.hasMoreElements()) { String inputValue = (String) fileParameterNames.nextElement(); File[] files = multiWrapper.getFiles(inputValue); for (File currentFile : files) { if (LOG.isInfoEnabled()) { LOG.info(getTextMessage(action, "struts.messages.removing.file", new Object[]{inputValue, currentFile}, ac.getLocale())); } if ((currentFile != null) && currentFile.isFile()) { if (currentFile.delete() == false) {//这里调用了currentFile.delete()将临时文件删除,因为此时在Action对上传的文件处理已经完成 LOG.warn("Resource Leaking: Could not remove uploaded file '"+currentFile.getCanonicalPath()+"'."); } } } } //返回上一个拦截器 return result; }
protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation, Locale locale) { boolean fileIsAcceptable = false; // If it's null the upload failed if (file == null) { String errMsg = getTextMessage(action, "struts.messages.error.uploading", new Object[]{inputName}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else if (maximumSize != null && maximumSize < file.length()) { String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new Object[]{inputName, filename, file.getName(), "" + file.length()}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) { String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else if ((! allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) { String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else { fileIsAcceptable = true; } return fileIsAcceptable; }