2012-12-03 44 views
7

महत्वपूर्ण: यह सवाल किसी भी वसंत संस्करण से अधिक 3.0.4 मुद्दा इस सूत्र में चर्चा के रूप में के लिए पूरी तरह से बेकार है कि संस्करण में fixed किया गया था है बहुत पहले और वसंत के बाद के संस्करणों में अब पुन: उत्पन्न नहीं किया गया है।अपलोड कर रहा है कई वसंत MVC 3.0.2 का उपयोग कर HiddenHttpMethodFilter के बाद फ़ाइलों सक्षम किया गया है


मैं वसंत संस्करण 3.0.2 का उपयोग कर रहा हूं। मैं इस तरह के रूप में एक फ़ाइल ब्राउज़र की multiple="multiple" विशेषता का उपयोग कर एकाधिक फ़ाइलों को अपलोड करने के लिए,

<input type="file" id="myFile" name="myFile" multiple="multiple"/> 

जरूरत है (और नहीं this answer द्वारा कहा गया एक जैसे कई फ़ाइल ब्राउज़रों कुछ का उपयोग कर, यह वास्तव में काम करता है मैंने कोशिश की)।

हालांकि इंटरनेट एक्सप्लोरर का कोई संस्करण इस दृष्टिकोण का समर्थन नहीं करता है जब तक कोई उचित jQuery प्लगइन/विजेट का उपयोग नहीं किया जाता है, मुझे अभी इसकी परवाह नहीं है (क्योंकि अधिकांश अन्य ब्राउज़र इसका समर्थन करते हैं)।

यह commons fileupload के साथ ठीक लेकिन RequestMethod.POST और RequestMethod.GET तरीकों का उपयोग कर के अलावा काम करता है, मैं भी RequestMethod.PUT और अपने स्वयं के उपयुक्त स्थानों में RequestMethod.DELETE तरह का समर्थन किया और स्प्रिंग ने सुझाव दिया अन्य अनुरोध तरीकों का उपयोग करना चाहते हैं। ऐसा करने के लिए, मैंने HiddenHttpMethodFilter के साथ वसंत को कॉन्फ़िगर किया है जो this question इंगित करता है ठीक है।

लेकिन यह फ़ाइल ब्राउज़र में एकाधिक फ़ाइलों को चुना गया है, भले ही यह केवल पर केवल एक फ़ाइल अपलोड कर सके। स्प्रिंग कंट्रोलर क्लास में, निम्नानुसार एक विधि मैप की जाती है।

@RequestMapping(method={RequestMethod.POST}, value={"admin_side/Temp"}) 
public String onSubmit(@RequestParam("myFile") List<MultipartFile> files, @ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) throws IOException, FileUploadException { 
    for (MultipartFile file : files) { 
     System.out.println(file.getOriginalFilename()); 
    } 
} 
भी अनुरोध पैरामीटर @RequestParam("myFile") List<MultipartFile> files किस प्रकार MultipartFile के List है (यह हमेशा एक समय में केवल एक फ़ाइल हो सकता है) के साथ


मैं एक रणनीति है जो एक से अधिक फ़ाइलों on this blog के साथ काम करने की संभावना है मिल सकता है। मैं इसे ध्यान से चला गया है।

अनुभाग के नीचे समाधान समाधान 2 - रॉ अनुरोध कहते हैं,

उपयोग तथापि ग्राहक इस तरह के 'फ़ाइलों []' या के रूप में एक ही रूप इनपुट नाम के उपयोग पर जोर तो 'फाइल' और उसके बाद उस नाम को एकाधिक फ़ाइलों के साथ पॉप्युलेट कर रहा है, तो निम्नानुसार एक छोटा हैक आवश्यक है। जैसा कि ऊपर बताया गया है वसंत 2.5 अपवाद फेंकता है अगर यह एक ही रूप में टाइप फ़ाइल के समान फॉर्म इनपुट नाम का पता लगाता है। CommonsFileUploadSupport - वर्ग जो कि अपवाद फेंकता अंतिम नहीं है और method जो फेंकता है कि अपवाद तो विरासत के चमत्कार का उपयोग कर और एक उपवर्गीकरण बस ठीक/के रूप में इस प्रकार तर्क एक छोटा सा संशोधित कर सकते हैं सुरक्षित है। परिवर्तन मैंने सचमुच एक शब्द एक विधि आमंत्रण का प्रतिनिधित्व किया है जो हमें एक ही फॉर्म इनपुट नाम के अंतर्गत आने वाली कई फाइलें प्राप्त करने में सक्षम बनाता है।

यह इस तरह के रूप वर्ग CommonsMultipartResolver बढ़ा कर विधि ओवरराइड करने के लिए

protected MultipartParsingResult parseFileItems(List fileItems, String encoding){} 
सार वर्ग CommonsFileUploadSupport की

प्रयास करता है,

package multipartResolver; 

import java.io.UnsupportedEncodingException; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Map; 
import javax.servlet.ServletContext; 
import org.apache.commons.fileupload.FileItem; 
import org.springframework.util.StringUtils; 
import org.springframework.web.multipart.MultipartException; 
import org.springframework.web.multipart.MultipartFile; 
import org.springframework.web.multipart.commons.CommonsMultipartFile; 
import org.springframework.web.multipart.commons.CommonsMultipartResolver; 

public final class MultiCommonsMultipartResolver extends CommonsMultipartResolver { 

    public MultiCommonsMultipartResolver() {} 

    public MultiCommonsMultipartResolver(ServletContext servletContext) { 
     super(servletContext); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    protected MultipartParsingResult parseFileItems(List fileItems, String encoding) { 
     Map<String, MultipartFile> multipartFiles = new HashMap<String, MultipartFile>(); 
     Map multipartParameters = new HashMap(); 

     // Extract multipart files and multipart parameters. 
     for (Iterator it = fileItems.iterator(); it.hasNext();) { 
      FileItem fileItem = (FileItem) it.next(); 

      if (fileItem.isFormField()) { 
       String value = null; 

       if (encoding != null) { 
        try { 
         value = fileItem.getString(encoding); 
        } catch (UnsupportedEncodingException ex) { 
         if (logger.isWarnEnabled()) { 
          logger.warn("Could not decode multipart item '" + fileItem.getFieldName() 
            + "' with encoding '" + encoding + "': using platform default"); 
         } 

         value = fileItem.getString(); 
        } 
       } else { 
        value = fileItem.getString(); 
       } 

       String[] curParam = (String[]) multipartParameters.get(fileItem.getFieldName()); 

       if (curParam == null) { 
        // simple form field 
        multipartParameters.put(fileItem.getFieldName(), new String[]{value}); 
       } else { 
        // array of simple form fields 
        String[] newParam = StringUtils.addStringToArray(curParam, value); 
        multipartParameters.put(fileItem.getFieldName(), newParam); 
       } 
      } else { 
       // multipart file field 
       CommonsMultipartFile file = new CommonsMultipartFile(fileItem); 
       if (multipartFiles.put(fileItem.getName(), file) != null) { 
        throw new MultipartException("Multiple files for field name [" + file.getName() 
          + "] found - not supported by MultipartResolver"); 
       } 

       if (logger.isDebugEnabled()) { 
        logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize() 
          + " bytes with original filename [" + file.getOriginalFilename() + "], stored " 
          + file.getStorageDescription()); 
       } 
      } 
     } 

     return new MultipartParsingResult(multipartFiles, multipartParameters); 
    } 
} 

क्या होता है कि विधि parseFileItems() में अंतिम पंक्ति (वापसी विवरण) यानी

return new MultipartParsingResult(multipartFiles, multipartParameters); 

एक संकलन समय त्रुटि होती है क्योंकि पहले पैरामीटर multipartFilesMap का एक प्रकार HashMapद्वारा लेकिन वास्तविकता में लागू किया है, यह प्रकारMultiValueMap<String, MultipartFile>

की एक पैरामीटर की आवश्यकता है यह सार अंदर एक स्थिर वर्ग के एक निर्माता है वर्ग CommonsFileUploadSupport,

public abstract class CommonsFileUploadSupport { 
    protected static class MultipartParsingResult { 
     public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {} 
    } 
} 

कारण हो सकता है - इस समाधान स्प्रिंग संस्करण 2.5 के बारे में है और मैं वसंत संस्करण 3.0.2 जो इस संस्करण के लिए अनुपयुक्त हो सकती उपयोग कर रहा हूँ।


मैं तथापि,

MultiValueMap<String, MultipartFile>mul=new LinkedMultiValueMap<String, MultipartFile>(); 

for(Entry<String, MultipartFile>entry:multipartFiles.entrySet()) { 
    mul.add(entry.getKey(), entry.getValue()); 
} 

return new MultipartParsingResult(mul, multipartParameters); 

लेकिन कोई सफलता इस तरह के कोड की निम्न खंड में दिखाया गया है एक के रूप में विभिन्न तरीकों से MultiValueMap साथ Map को बदलने के लिए कोशिश की। मुझे यकीन नहीं है कि को MultiValueMap के साथ कैसे बदला जाए और यहां तक ​​कि ऐसा करने से भी काम हो सकता है। यह करने के बाद, ब्राउज़र HTTP प्रतिक्रिया,

HTTP स्थिति से पता चलता 400 -

प्रकार स्थिति रिपोर्ट

संदेश

वर्णन अनुरोध ग्राहक द्वारा भेजे गए वाक्य रचना था गलत ()।

अपाचे बिलाव/6.0.26


मैं संभव के रूप में सवाल मैं कर सकता के रूप में छोटा करने के लिए कोशिश की है और मैं शामिल नहीं किया है अनावश्यक कोड।

स्प्रिंग को HiddenHttpMethodFilter के साथ कॉन्फ़िगर किए जाने के बाद एकाधिक फ़ाइलों को अपलोड करना संभव कैसे बनाया जा सकता है?

वह ब्लॉग इंगित करता है कि यह एक लंबी स्थायी, उच्च प्राथमिकता वाली बग है।

यदि संस्करण 3.0.2 (3 या उच्चतम) के संबंध में कोई समाधान नहीं है तो मुझे हमेशा के लिए वसंत समर्थन अक्षम करना होगा और commons-fileupolad का उपयोग जारी रखना होगा जैसा कि उस ब्लॉग पर तीसरे समाधान द्वारा PUT, DELETE और अन्य अनुरोध को छोड़कर सुझाया गया है हमेशा के लिए तरीकों।


वर्ग MultiCommonsMultipartResolver अंदर parseFileItems() विधि में कोड करने के लिए बहुत कम परिवर्तन यह एकाधिक फ़ाइलों को अपलोड कर सकता है, लेकिन मैं (फिर से वसंत संस्करण 3.0.2 (3 या अधिक) के साथ अपने प्रयास में सफल नहीं हो सकता है)।

+0

[जिरा मुद्दा] (https://jira.springsource.org/browse/SPR-2784?page=com.atlassian.jira.plugin.system.issuetabpanels%25253Aall-tabpanel) ब्लॉग पोस्ट में उल्लिखित है संस्करण 3.0.4 के बाद से, क्या आप उन्नयन करने का प्रयास कर सकते हैं? –

+0

@ आरसी - उस लिंक के लिए धन्यवाद। मेरे पास एक बड़ा एप्लीकेशन है जो आधे रास्ते से अधिक पूरा हो गया है। ढांचे को बदलने के लिए कई स्थानों पर कोड को बदलने की आवश्यकता हो सकती है, इसलिए मैं केवल भविष्य की परियोजनाओं के लिए एक उच्च संस्करण के बारे में सोच सकता हूं (मुझे इसे शुरू करने से पहले इसे जाना चाहिए था)। धन्यवाद। – Tiny

+2

3.0.2 से 3.0.4 एक मामूली अपग्रेड है (मुख्य रूप से बगफिक्स यदि मैं संस्करण संख्या को देखता हूं), तो यह दर्द रहित होना चाहिए। आपको इसे आजमाएं और इसके लिए जाएं यदि यह –

उत्तर