File upload Struts 2文件上载拦截器配置问题

File upload Struts 2文件上载拦截器配置问题,file-upload,configuration,struts2,interceptor,interceptorstack,File Upload,Configuration,Struts2,Interceptor,Interceptorstack,在我的应用程序中配置Struts 2文件上传拦截器时,我遇到了两个问题。我想更改参数maximumSize(默认值为2MB,我需要它为5MB)和消息资源struts.messages.error.file.too.large(应用程序区域设置为pt_BR,因此消息是葡萄牙语,而不是英语) 应用程序当前配置如下所示: struts.properties struts.locale=pt_BR struts.custom.i18n.resources=MessageResources ... s

在我的应用程序中配置Struts 2文件上传拦截器时,我遇到了两个问题。我想更改参数
maximumSize
(默认值为2MB,我需要它为5MB)和消息资源
struts.messages.error.file.too.large
(应用程序区域设置为pt_BR,因此消息是葡萄牙语,而不是英语)

应用程序当前配置如下所示:

struts.properties

struts.locale=pt_BR 
struts.custom.i18n.resources=MessageResources
...
struts.messages.error.file.too.large=O tamanho do arquivo...
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>
我的操作实现和JSP代码没有什么特别之处。他们遵循我们发现的例子。当我尝试上载超过5 MB的文件时,应用程序会显示消息“请求被拒绝,因为其大小(6229458)超过了配置的最大值(2097152)”—默认文件上载消息,具有默认的maximumSize值


我尝试将消息资源
struts.messages.error.file.too.large
放在struts-messages.properties中,但此后消息没有更改。配置文件上载拦截器的正确方法是什么?我使用的是Struts2.1.7。提前感谢。

终于解决了整个难题
struts.xml
MessageResource.properties
已正确配置。问题是struts.multipart.maxSizevalue。该值必须大于所需的上传限制(在我的应用程序中为5242880),因此我将其设置为10000000。如果
struts.multipart.maxSize
值等于或小于
fileUpload.maximumSize
struts 2用于执行上载的库将停止上载过程(并写入错误消息)在文件上传拦截器有机会完成其工作之前。

您提供的解决方案并不完全正确,因为如果我想要严格的上传限制以及i18n,这将不起作用。我还为此创建了一个strut2问题。请看下面的链接。它将在struts2.1.9中修复,并已分配给struts团队成员

在两者之间,我用的是黑客。我浏览了struts2源代码,找到了FileUploadInterceptor的代码。使用这些代码,我创建了自己的。下面是代码。您可以在上面的链接中找到问题的详细信息。希望这有帮助

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);
        }
    }
}
导入java.io.File;
导入java.util.*;
导入javax.servlet.http.HttpServletRequest;
导入org.apache.struts2.ServletActionContext;
导入org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
导入com.opensymphony.xwork2.ActionContext;
导入com.opensymphony.xwork2.ActionInvocation;
导入com.opensymphony.xwork2.ActionProxy;
导入com.opensymphony.xwork2.ValidationAware;
导入com.opensymphony.xwork2.interceptor.AbstractInterceptor;
导入com.opensymphony.xwork2.util.LocalizedTextUtil;
导入com.opensymphony.xwork2.util.TextParseUtil;
导入com.opensymphony.xwork2.util.logging.Logger;
导入com.opensymphony.xwork2.util.logging.LoggerFactory;
公共类CustomFileUploaderInterceptor扩展了AbstractInterceptor{
私有静态最终长SerialVersionId=-4764627478894962478L;
受保护的静态最终记录器日志=LoggerFactory.getLogger(CustomFileUploaderInterceptor.class);
私有静态最终字符串DEFAULT_MESSAGE=“no.MESSAGE.found”;
受保护的布尔useActionMessageBundle;
保护长最大尺寸;
受保护集allowedTypesSet=Collections.emptySet();
受保护集AllowedExtensionSet=Collections.emptySet();
public void setUseActionMessageBundle(字符串值){
this.useActionMessageBundle=Boolean.valueOf(value);
}
/**
*设置允许的扩展名
*
*@param允许扩展名使用逗号分隔的扩展名列表
*/
公共void setAllowedExtensions(字符串allowedExtensions){
AllowedExtensionSet=TextParseUtil.commaDelimitedStringToSet(allowedExtensions);
}
/**
*设置允许的mimetype
*
*@param允许使用逗号分隔的类型列表
*/
公共void setAllowedTypes(字符串allowedTypes){
allowedTypesSet=TextParseUtil.commaDelimitedStringToSet(allowedTypes);
}
/**
*设置上载文件的最大大小
*
*@param maximumSize以字节为单位的最大大小
*/
公共无效设置最大大小(长最大大小){
this.maximumSize=maximumSize;
}
/*(非Javadoc)
*@see com.opensymphony.xwork2.interceptor.interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
*/
公共字符串截获(ActionInvocation调用)引发异常{
ActionContext ac=invocation.getInvocationContext();
Map params1=ac.getParameters();
Set keySet=params1.keySet();
用于(字符串s:键集){
LOG.debug(“键:+s+”,值:+params1.get(s.toString());
}
HttpServletRequest=(HttpServletRequest)ac.get(ServletActionContext.HTTP_请求);
if(!(MultiPartRequestWrapper的请求实例)){
if(LOG.isDebugEnabled()){
ActionProxy=invocation.getProxy();
调试(getTextMessage(“struts.messages.bypass.request”,新对象[]{proxy.getNamespace(),proxy.getActionName()},ac.getLocale());
}
返回invocation.invoke();
}
ValidationAware验证=null;
Object action=invocation.getAction();
if(ValidationWare的操作实例){
验证=(ValidationWare)操作;
}
MultiPartRequestWrapper multiWrapper=(MultiPartRequestWrapper)请求;
if(multiWrapper.hasErrors()){
字符串inputName=null;
if(multiWrapper.getFileParameterNames().hasMoreElements()){
inputName=(字符串)multiWrapper.getFileParameterNames().nextElement();
}
for(字符串错误:multiWrapper.getErrors()){
如果(验证=
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!");

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