7

Ich habe zwei Probleme, wenn ich versuche, den Struts 2 File Upload Interceptor in meiner Anwendung zu konfigurieren. Ich möchte den Parameter maximumSize ändern (der Standardwert ist 2 MB, ich brauche es 5 MB) und die Nachrichtenressource struts.messages.error.file.too.large (das Gebietsschema der App ist pt_BR, also ist die Nachricht in Portugiesisch, nicht Englisch).Struts 2 File Upload Interceptor Konfigurationsprobleme

Die App aktuelle Konfiguration folgt:

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

Es gibt nichts besonderes an meiner Action-Implementierung und meinem JSP-Code. Sie folgen dem Beispiel gefunden http://struts.apache.org/2.1.6/docs/file-upload-interceptor.html. Wenn ich versuche, eine Datei mit mehr als 5 MB hochzuladen, zeigt die App die Meldung "Die Anfrage wurde abgelehnt, da ihre Größe (6229458) das konfigurierte Maximum (2097152) überschreitet" - die Standardnachricht zum Hochladen von Dateien mit dem Standardwert maximumSize.

Ich versuche, die Nachrichtenressource struts.messages.error.file.too.large in eine struts-messages.properties zu setzen, aber die Nachricht hat sich danach nicht geändert. Was ist der richtige Weg, um den File Upload Interceptor zu konfigurieren? Ich benutze Struts 2 2.1.7. Danke im Voraus.

+0

Es wurde gerade eine Möglichkeit gefunden, das Upload-Größenlimit zu ändern. :) Ich habe die 'struts.multipart geändert.Eigenschaft "maxSize" in der Datei "struts.properties" auf den gewünschten Wert. Aber das Problem mit der lokalisierten Fehlermeldung bleibt immer noch ... –

Antwort

9

Endlich das Rätsel gelöst! struts.xml und MessageResource.properties wurden korrekt konfiguriert. Das Problem war struts.multipart.maxSize Wert. Dieser Wert muss größer sein als das gewünschte Upload-Limit (5242880 in meiner App), also setze ich es als 10000000. Wenn struts.multipart.maxSize Wert gleich oder kleiner ist als fileUpload.maximumSize stoppt die von Struts 2 verwendete Upload-Datei den Upload-Prozess (und schreibt die Fehlermeldung, bevor der Datei-Upload-Interceptor eine Chance hat, seine Aufgabe zu erledigen.

6

Die von Ihnen zur Verfügung gestellte Lösung ist nicht ganz korrekt in dem Sinne, dass wenn ich strenge Upload-Grenzen zusammen mit i18n will, wird dies nicht funktionieren. Ich habe auch ein Problem mit Strut2 dafür erstellt. Bitte beachten Sie den folgenden Link https://issues.apache.org/jira/browse/WW-3177. Es wird in struts2.1.9 behoben und ist bereits einem struts-Teammitglied zugewiesen.

Dazwischen benutze ich einen Hack. Ich habe den Quellcode von struts2 durchsucht und den Code für FileUploadInterceptor gefunden. Mit diesem Code habe ich meinen eigenen erstellt. Hier ist der Code unten. Sie können Details des Problems über den obigen Link finden. Hoffe das hilft.

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); 
     } 
    } 
} 
0

Erste Einsatz Validate-Methode in Ihrer Aktion Datei ........

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

    } 
    } 
} 

Für vollständigen Code, besuchen Sie bitte http://knowledge-serve.blogspot.com/2011/10/upload-file-using-in-struts-2.html

3

dieses struts.xml in Ihrem Versuchen, wobei xxxxxxxx das Limit ist:

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