Problems loading Struts 2 File Interceptor files

I am having two problems when trying to configure the Struts 2 file upload interceptor in my application. I want to change the maximumSize parameter (the default value is 2 MB, I need it to be 5 MB) and the message resource struts.messages.error.file.too.large (the application locale is pt_BR, so the message is in Portuguese, not in English).

The following application configuration:

struts.properties

 struts.locale=pt_BR struts.custom.i18n.resources=MessageResources 

struts.xml

 <package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="login" class="br.com.probank.interceptor.LoginInterceptor"/> <interceptor-stack name="defaultLoginStack"> <interceptor-ref name="login" /> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultLoginStack" /> ... </package> ... <package name="proposta" namespace="/proposta" extends="default"> <action name="salvarAnexoProposta" method="salvarAnexoProposta" class="br.com.probank.action.AnexoPropostaAction"> <interceptor-ref name="defaultLoginStack"> <param name="fileUpload.maximumSize">5242880</param> </interceptor-ref> <result name="success">/jsp/listagemAnexosPropostaForm.jsp</result> <result name="input">/jsp/crudAnexoPropostaForm.jsp</result> <result name="error">/jsp/error.jsp</result> <result name="redirect" type="redirect">${redirectLink}</result> </action> </package> 

MessageResources.properties

 ... struts.messages.error.file.too.large=O tamanho do arquivo... 

There is nothing special about my Action implementation and my JSP code. They follow the example of http://struts.apache.org/2.1.6/docs/file-upload-interceptor.html . When I try to download a file with more than 5 MB, the application displays the message "the request was rejected because its size (6229458) exceeds the configured maximum (2097152)" - the default message is "Download files" with the maximum default value.

I am trying to put the message resource struts.messages.error.file.too.large in struts-messages.properties, but after that the message has not changed. What is the correct way to configure a file upload interceptor? I am using Struts 2 2.1.7. Thanks in advance.

+7
file-upload configuration struts2 interceptor interceptorstack
source share
4 answers

Finally solved the whole riddle! struts.xml and MessageResource.properties were correctly configured. The problem was the struts.multipart.maxSize value . This value should be greater than the desired download limit (5242880 in my application), so I set it to 10000000. If struts.multipart.maxSize is equal to or less than fileUpload.maximumSize , the library used by Struts 2 to stop stops (and writes error message) before the file upload interceptor can do its job.

+9
source share

The solution you provided is not entirely correct in the sense that if I need strict download restrictions with i18n, this will not work. I also created a problem with strut2 for this. See the following link https://issues.apache.org/jira/browse/WW-3177 . This should be fixed in struts2.1.9 and already assigned to the struts team member.

In between, I use hack. I looked at struts2 source code and found code for FileUploadInterceptor. Using this code, I created my own. Here is the code below. Detailed information about the problem can be found at the link above. Hope this helps.

 import java.io.File; import java.util.*; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ValidationAware; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.util.LocalizedTextUtil; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class CustomFileUploaderInterceptor extends AbstractInterceptor { private static final long serialVersionUID = -4764627478894962478L; protected static final Logger LOG = LoggerFactory.getLogger(CustomFileUploaderInterceptor.class); private static final String DEFAULT_MESSAGE = "no.message.found"; protected boolean useActionMessageBundle; protected Long maximumSize; protected Set<String> allowedTypesSet = Collections.emptySet(); protected Set<String> allowedExtensionsSet = Collections.emptySet(); public void setUseActionMessageBundle(String value) { this.useActionMessageBundle = Boolean.valueOf(value); } /** * Sets the allowed extensions * * @param allowedExtensions A comma-delimited list of extensions */ public void setAllowedExtensions(String allowedExtensions) { allowedExtensionsSet = TextParseUtil.commaDelimitedStringToSet(allowedExtensions); } /** * Sets the allowed mimetypes * * @param allowedTypes A comma-delimited list of types */ public void setAllowedTypes(String allowedTypes) { allowedTypesSet = TextParseUtil.commaDelimitedStringToSet(allowedTypes); } /** * Sets the maximum size of an uploaded file * * @param maximumSize The maximum size in bytes */ public void setMaximumSize(Long maximumSize) { this.maximumSize = maximumSize; } /* (non-Javadoc) * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation) */ public String intercept(ActionInvocation invocation) throws Exception { ActionContext ac = invocation.getInvocationContext(); Map<String, Object> params1 = ac.getParameters(); Set<String> keySet = params1.keySet(); for(String s : keySet){ LOG.debug("Key: "+ s +", Value: " + params1.get(s).toString()); } 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(); if (action instanceof ValidationAware) { validation = (ValidationAware) action; } MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; if (multiWrapper.hasErrors()) { String inputName = null; if(multiWrapper.getFileParameterNames().hasMoreElements()){ inputName = (String)multiWrapper.getFileParameterNames().nextElement(); } for (String error : multiWrapper.getErrors()) { if (validation != null) { Object[] args = new Object[]{inputName}; validation.addActionError(getTextMessage(action, "struts.messages.error.file.too.large", args, ac.getLocale())); } LOG.error(error); } } // bind allowed Files Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); while (fileParameterNames != null && fileParameterNames.hasMoreElements()) { // get the value of this input tag String inputName = (String) fileParameterNames.nextElement(); // get the content type String[] contentType = multiWrapper.getContentTypes(inputName); if (isNonEmpty(contentType)) { // get the name of the file from the input tag String[] fileName = multiWrapper.getFileNames(inputName); if (isNonEmpty(fileName)) { // get a File object for the uploaded File 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(); 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.error(getTextMessage(action, "struts.messages.invalid.file", new Object[]{inputName}, ac.getLocale())); } } else { LOG.error(getTextMessage(action, "struts.messages.invalid.content.type", new Object[]{inputName}, ac.getLocale())); } } // invoke action String result = invocation.invoke(); // cleanup 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(); } } } return result; } /** * Override for added functionality. Checks if the proposed file is acceptable based on contentType and size. * * @param action - uploading action for message retrieval. * @param file - proposed upload file. * @param contentType - contentType of the file. * @param inputName - inputName of the file. * @param validation - Non-null ValidationAware if the action implements ValidationAware, allowing for better * logging. * @param locale * @return true if the proposed file is acceptable by contentType and size. */ protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation, Locale locale) { boolean fileIsAcceptable = false; // If it 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.error(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.error(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.error(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.error(errMsg); } else { fileIsAcceptable = true; } return fileIsAcceptable; } /** * @param extensionCollection - Collection of extensions (all lowercase). * @param filename - filename to check. * @return true if the filename has an allowed extension, false otherwise. */ private static boolean hasAllowedExtension(Collection<String> extensionCollection, String filename) { if (filename == null) { return false; } String lowercaseFilename = filename.toLowerCase(); for (String extension : extensionCollection) { if (lowercaseFilename.endsWith(extension)) { return true; } } return false; } /** * @param itemCollection - Collection of string items (all lowercase). * @param item - Item to search for. * @return true if itemCollection contains the item, false otherwise. */ private static boolean containsItem(Collection<String> itemCollection, String item) { return itemCollection.contains(item.toLowerCase()); } private static boolean isNonEmpty(Object[] objArray) { boolean result = false; for (int index = 0; index < objArray.length && !result; index++) { if (objArray[index] != null) { result = true; } } return result; } private String getTextMessage(String messageKey, Object[] args, Locale locale) { return getTextMessage(null, messageKey, args, locale); } private String getTextMessage(Object action, String messageKey, Object[] args, Locale locale) { if (args == null || args.length == 0) { if ( action != null && useActionMessageBundle) { return LocalizedTextUtil.findText(action.getClass(), messageKey, locale); } return LocalizedTextUtil.findText(this.getClass(), messageKey, locale); } else { if ( action != null && useActionMessageBundle) { return LocalizedTextUtil.findText(action.getClass(), messageKey, locale, DEFAULT_MESSAGE, args); } return LocalizedTextUtil.findText(this.getClass(), messageKey, locale, DEFAULT_MESSAGE, args); } } } 
+6
source share

Try this in struts.xml , where xxxxxxxx is the limit:

 <constant name="struts.multipart.maxSize" value="xxxxxxxxx" /> 
+3
source share

First apply the validation method in the action file ........

 public void validate(){ if(getFileUpload() !=null){ System.out.println("======File size validation before upload: size in bytes: "+getFileUpload().length()); if(getFileUpload().length()>202400){ //Give the size in bytes whatever you want to take addActionError("File is too large ! Select less than 200Kb file"); }else{ addActionMessage("File Uploaded successfully!"); } } } 

For full code, please visit http://knowledge-serve.blogspot.com/2011/10/upload-file-using-in-struts-2.html

0
source share

All Articles