formfile fileupload file-upload configuration struts2 interceptor interceptorstack

fileupload - Problemas de configuración de Struts 2 File Upload Interceptor



formfile struts2 (4)

Tengo dos problemas al intentar configurar el interceptor de carga de archivos Struts 2 en mi aplicación. Quiero cambiar el parámetro maximumSize (el valor predeterminado es 2 MB, necesito que sea de 5 MB) y el recurso de mensaje struts.messages.error.file.too.large (la configuración regional de la aplicación es pt_BR, por lo que el mensaje está en portugués, no inglés).

La configuración actual de la aplicación sigue:

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...

No hay nada especial en mi implementación de Acción y mi código JSP. Siguen el ejemplo encontrado http://struts.apache.org/2.1.6/docs/file-upload-interceptor.html . Cuando intento cargar un archivo con más de 5 MB, la aplicación muestra el mensaje "la solicitud fue rechazada porque su tamaño (6229458) excede el máximo configurado (2097152)": el mensaje de carga de archivo predeterminado con el valor máximo predeterminado.

Intento poner el recurso del mensaje struts.messages.error.file.too.large en un struts-messages.properties pero el mensaje no cambió después de eso. ¿Cuál es la forma correcta de configurar el interceptor de carga de archivos? Estoy usando Struts 2 2.1.7. Gracias por adelantado.


¡Finalmente resolvió todo el rompecabezas! struts.xml y MessageResource.properties se configuraron correctamente. El problema era struts.multipart.maxSize value . Este valor debe ser mayor que el límite de carga deseado (5242880 en mi aplicación), así que lo configuro como 10000000. Si el valor de struts.multipart.maxSize es igual o menor que fileUpload.maximumSize la biblioteca utilizada por Struts 2 para realizar la carga detiene el proceso de carga (y escribe el mensaje de error) antes de que el interceptor de carga de archivos tenga la oportunidad de hacer su trabajo.


La solución proporcionada por usted no es del todo correcta en el sentido de que si deseo límites de carga estrictos junto con i18n, esto no funcionará. También he creado un problema con strut2 para esto. Consulte el siguiente enlace https://issues.apache.org/jira/browse/WW-3177 . Se debe arreglar en struts2.1.9 y ya está asignado a un miembro del equipo de struts.

Mientras tanto, estoy usando un truco. Busqué el código fuente de struts2 y encontré el código para FileUploadInterceptor. Usando ese código, creé el mío. Aquí está el código a continuación. Puede encontrar detalles del problema en el enlace de arriba. Espero que esto ayude.

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''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.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); } } }


Primero use el método de validación en su archivo de acción ........

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!"); } } }

Para obtener el código completo, visite http://knowledge-serve.blogspot.com/2011/10/upload-file-using-in-struts-2.html


Pruebe esto en su struts.xml , donde xxxxxxxx es el límite:

<constant name="struts.multipart.maxSize" value="xxxxxxxxx" />