7

Mam dwa problemy podczas próby skonfigurowania przechwytywacza plików Struts 2 w mojej aplikacji. Chcę zmienić parametr maximumSize (domyślna wartość to 2 MB, potrzebuję 5 MB) i zasób komunikatu struts.messages.error.file.too.large (lokalizacja aplikacji to pt_BR, więc wiadomość jest w języku portugalskim, a nie angielskim).Struts Przesyłanie plików 2 Problemy z konfiguracją przechwytywacza

Aplikacja aktualnej konfiguracji następuje:

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

Nie ma nic szczególnego w mojej implementacji Akcji i moim kodzie JSP. Podążają za przykładem znalezionym pod numerem http://struts.apache.org/2.1.6/docs/file-upload-interceptor.html. Kiedy próbuję przesłać plik z więcej niż 5 MB, aplikacja wyświetla komunikat "żądanie zostało odrzucone, ponieważ jego rozmiar (6229458) przekracza skonfigurowane maksimum (2097152)" - domyślny komunikat Przesyłanie pliku z domyślną wartością maksymalnego rozmiaru.

Próbuję umieścić zasób wiadomości struts.messages.error.file.too.large w pliku struts-messages.properties, ale po tym wiadomość nie uległa zmianie. Jaki jest właściwy sposób konfigurowania przechwytywacza plików? Używam Struts 2 2.1.7. Z góry dziękuję.

+0

Po prostu znalazłem sposób na zmianę limitu rozmiaru wysyłania. :) Zmieniłem 'struts.multipart.maxSize' właściwość w pliku 'struts.properties' do pożądanej wartości. Ale problem z zlokalizowanym komunikatem o błędzie nadal pozostaje ... –

Odpowiedz

9

W końcu rozwiązałem całą zagadkę! struts.xml i MessageResource.properties zostały poprawnie skonfigurowane. Problem był następujący: struts.multipart.maxSize wartość. Ta wartość musi być większa niż pożądany limit przesyłania (5242880 w mojej aplikacji), więc ustawię go na 10000000. Jeśli wartość struts.multipart.maxSize jest równa lub mniejsza niż fileUpload.maximumSize biblioteka używana przez Struts 2 do przesłania zatrzymuje proces przesyłania (i wypisze komunikat o błędzie), zanim przechwytywanie plików będzie miało szansę wykonać to zadanie.

6

Dostarczone przez ciebie rozwiązanie nie jest całkowicie poprawne w tym sensie, że jeśli chcę ścisłe limity wysyłania wraz z i18n, to nie zadziała. Stworzyłem także problem z rozszerzeniem strut2. Proszę spojrzeć na następujący link https://issues.apache.org/jira/browse/WW-3177. Zostanie on naprawiony w struts2.1.9 i jest już przypisany do członka zespołu rozpórek.

Pomiędzy, używam hack. Przeglądałem kod źródłowy struts2 i znalazłem kod dla FileUploadInterceptor. Używając tego kodu, stworzyłem swój własny. Oto poniższy kod. Możesz znaleźć szczegóły problemu pod linkiem powyżej. Mam nadzieję że to pomoże.

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

Pierwsza metoda użycie validate w pliku działań ........

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

    } 
    } 
} 

Dla pełnego kodu, proszę odwiedzić http://knowledge-serve.blogspot.com/2011/10/upload-file-using-in-struts-2.html

3

Spróbuj tego w swojej struts.xml, gdzie xxxxxxxx jest granicą:

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