FileUploadInterceptorÀ¹½ØÆ÷¼ò½é
¸ÃÀ¹½ØÆ÷´¦ÓÚdefaultStackµÚÊ®µÄλÖ㬿´ÆäÃû³Æ¾ÍÖªµÀÊÇÓÃÓÚ´¦ÀíÎļþÉÏ´«µÄ£¬¶ÔÓÚÎļþÉÏ´«ÓÐÒ»µã´ó¼ÒÓ¦¸ÃÒªÁ˽⣺struts2´¦ÀíÎļþÉÏ´«ÄÚ²¿Ê¹ÓõÄÊÇcommons-fileupload×é¼þ£¬µ±ÎÒÃÇÔÚform±íµ¥ÖаÑenctypeÊôÐÔÉèÖÃΪ"multipart/form-data"ʱ±íʾÕâÊÇÒ»¸öÎļþÉÏ´«ÇëÇ󣬵±struts2½ÓÊÕµ½ÕâÑùÒ»¸öÇëÇóºó°ÑÇëÇó°ü×°ÔÚÒ»¸öMultiPartRequestWrapper¶ÔÏóÖУ¬¶øMultiPartRequestWrapperÓÖ°ü×°ÁËJakartaMultiPartRequest£¬JakartaMultiPartRequest¶ÔÏó²ÅÊÇÕæÕý´¦ÀíÎļþÉÏ´«µÄrequest¶ÔÏó¡£
ÏÂÃæ˵һϸÃÀ¹½ØÆ÷ÖÐÈý¸öÖØÒªµÄÊôÐÔ£º
1.maximumSize-->ÔÊÐíÉÏ´«ÎļþÉÏ×î´ó´óС£¬µ¥Î»Îªbyte(×Ö½Ú)
2.allowedTypesSet-->ÔÊÐíÉÏ´«ÎļþÀàÐͼ¯ºÏ
3.allowedExtensionsSet-->ÔÊÐíÉÏ´«ÎļþÀ©Õ¹Ãû¼¯ºÏ
±ØÐëÒªÕâÈý¸öÌõ¼þ¶¼·ûºÏ£¬ÎļþÉÏ´«²ÅÄܳɹ¦¡£
ÏÂÃæÊǸÃÀ¹½ØÆ÷µÄintercept·½·¨£º
±í1
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()) { //ÓдíÎóÔòÌí¼ÓActionError£¬×¢Òâvalidation¾ÍÊǵ±Ç°Action¶ÔÏó if (validation != null) { 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()) { //ÕâÀïµ÷ÓÃÁËcurrentFile.delete()½«ÁÙʱÎļþɾ³ý //ÒòΪ´ËʱÔÚAction¶ÔÉÏ´«µÄÎļþ´¦ÀíÒѾÍê³É if (currentFile.delete() == false) { LOG.warn("Resource Leaking: Could not remove uploaded file '"+currentFile.getCanonicalPath()+"'."); } } }` } //·µ»ØÉÏÒ»¸öÀ¹½ØÆ÷ return result; } |
ÏÂÃæÔÙÈ¥¿´Ò»Ï¸ÃÀ¹½ØÆ÷ÊÇÈçºÎÅжÏÉÏ´«µÄÎļþÊÇ·ñºÏ·¨µÄ£¬¼´acceptFile·½·¨£º
±í2
protectedboolean 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); } elseif (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); } elseif ((!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); } elseif ((! 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; } |
¸Ã·½·¨Âß¼ºÜ¼òµ¥£¬¾ÍÊÇÒÀ´ÎÅжÏÉÏ´«µÄÎļþÊÇ·ñΪnull£¬ÊÇ·ñ·ûºÏÉ趨µÄÎļþ´óС£¬ÊÇ·ñ·ûºÏÉ趨µÄÎļþÀàÐÍ£¬ÊÇ·ñ·ûºÏÉ趨µÄÎļþÀ©Õ¹Ãû¡£Èç¹ûûÓÐÉ趨ÎļþÀàÐÍÓëÎļþÀ©Õ¹ÃûÔò±íʾÎļþÀàÐÍÓëÎļþÀ©Õ¹ÃûûÓÐÏÞÖÆ£¬¶øÔÚdefaultStackÖУ¬¸ÃÀ¹½ØÆ÷µÄÕâÁ½¸ö¶¼ÊÇûÓнøÐÐÉ趨µÄ£¬µ«ÊÇÉÏ´«ÎļþµÄ×î´ó´óСÊÇÉèÖÃÁ˵ģ¬¿Ï¶¨ÓÐÈË»á˵maximumSize²»ÊÇҲûÓÐÉèÖÃÂð£¿
û´í£¬ÔÚ¸ÃÀ¹½ØÆ÷maximumSizeµÄȷûÓÐÉèÖã¬Ä¬ÈÏÖµ¾ÍÊÇΪnull£¬¸Õ¸ÕҲ˵ÁË£¬ÕæÕý´¦ÀíÎļþÉÏ´«µÄrequest¶ÔÏóÊÇJakartaMultiPartRequest£¬ÔÚJakartaMultiPartRequestÖÐÓÐÒ»¸öÏàÓ¦µÄmaxSizeÊôÐÔÔÚʵÀý»¯JakartaMultiPartRequest¶ÔÏóµÄʱºòͨ¹ýstruts2µÄÈÝÆ÷°Ñ¸ÃÖµ×¢Èë½øÀ´ÁË£¬¸ÃÖµµÄÅäÖÃÔÚstruts2-core.jarÖеÄorg.apache.struts2°üÖеÄdefault.propertiesÎļþÖÐ(struts.multipart.maxSize=2097152)£¬Ä¬ÈÏֵΪ2097152£¬¼´2M´óС¡£
ÎÒÃÇÔÚ½øÐÐÎļþÉÏ´«µÄʱºòÊÇÔÚActionÖж¨ÒåÏàÓ¦µÄÊôÐÔÀ´½ÓÊÕÉÏ´«µÄÎļþ£¬ÎļþµÄÀàÐÍÓëÎļþÃû£¬µ«ÔÚ´ó¼Ò·¢ÏÖûÓÐÔÚ¸ÃÀ¹½ØÆ÷²¢Ã»Óе÷Óõ±Ç°ActionÉèÖõ±Ç°ÉÏ´«ÎļþµÄ·½·¨£¬¼´Ã»Óе÷ÓÃÏàÓ¦µÄsetXxx()¡¢setXxxContentType()¡¢setXxxFileName()·½·¨£¬xxxΪinputµÄnameÊôÐÔÖµ£¬Ö»Êǽ«ÉÏ´«µÄÎļþ£¬ÎļþÀàÐÍ£¬ÎļþÃû³Æ´æ´¢µ½ActionContextµÄparameters MapÖУ¬Õâ¸öÎÊÌâÔÚParametersInterceptorÀ¹½ØÆ÷½øÐн²½â¡£
Õâ¸öÀ¹½ØÆ÷ÓëÇ°Ã漸¸öÀ¹½ØÆ÷ÓÐÒ»µã²»Ò»Ñù¾ÍÊÇÔÚÖ´ÐÐÁËÒ»¶¨µÄÂß¼ºóµ÷ÓÃÁËÏÂÒ»¸öÀ¹½ØÆ÷¡¢Action£¬ÔÚÖ´ÐÐÍêActionÀ¹½ØÆ÷ÒÀ´Î·µ»ØÔÙ·µ»Øµ½¸ÃÀ¹½ØÆ÷¼ÌÐøÖ´ÐÐÇåÀíÉÏ´«Îļþʱ²úÉúµÄÁÙʱÎļþ£¬ÕâÊÇÓɸÃÀ¹½ØÆ÷ҪʵÏֵŦÄÜËù¾ö¶¨µÄ¡£
µ½´Ë¸ÃÀ¹½ØÆ÷¾Í½²½âÍê±ÏÁË£¬×¼±¸ÏÂÒ»¸öÀ¹½ØÆ÷À²......