2016-08-17 8 views
6

मैं स्प्रिंग बूट स्टॉर्मपाथ 1.0.2 के साथ स्प्रिंग बूट संस्करण = '1.4.0.आरसी 1' का उपयोग कर रहा हूं।स्प्रिंग बूट मल्टीपार्टफाइल हमेशा शून्य

मैं मल्टीपार्ट फ़ाइल अपलोड का उपयोग करने की कोशिश कर रहा हूं लेकिन मल्टीपार्टफाइल हमेशा नियंत्रक में शून्य है।

जब मैं @RequestPart का उपयोग करें ("फाइल") जानकारी: "status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present"

जब मैं @RequestPart (नाम = "फाइल", = आवश्यक false) का उपयोग, हिस्सा हमेशा रिक्त है।

हालांकि, अगर मैं नियंत्रक को एक HttpServletRequest तर्क जोड़ता हूं, तो मैं सीधे अनुरोध से फ़ाइल भाग प्राप्त कर सकता हूं, इसलिए मुझे पता है कि यह वास्तव में मौजूद है।

इस नियंत्रक है और checkNotNull(part) नीचे कोड में हमेशा सफल होता है और checkNotNull(imageFile) हमेशा विफल रहता है:

@PostMapping("{username}/profilePhoto") 
public ResponseEntity<?> saveProfilePhoto(@PathVariable("username") String username, 
              @RequestPart(name = "file", required = false) MultipartFile imageFile, 
              HttpServletRequest request) { 
    try { 
     Part part = request.getPart("file"); 
     checkNotNull(part); 
     checkNotNull(imageFile); 
    } catch (IOException | ServletException ex) { 
     throw InternalServerErrorException.create(); 
    } 

    // Transfer the multipart file to a temp file 
    File tmpFile; 
    try { 
     tmpFile = File.createTempFile(TMP_FILE_PREFIX, null); 
     imageFile.transferTo(tmpFile); 
    } catch (IOException ex) { 
     log.error("Failed to create temp file", ex); 
     throw InternalServerErrorException.create(); 
    } 

    // Execute the use case 
    updateUserProfilePhoto.execute(username, tmpFile); 

    // Delete the temp file 
    FileUtils.deleteQuietly(tmpFile); 

    return ResponseEntity.status(HttpStatus.CREATED).build(); 
} 

मेरे एकीकरण परीक्षण का उपयोग करता है पुराना वापस:

@Multipart 
@POST("users/{username}/profilePhoto") 
Call<Void> uploadProfilePhoto(@Path("username") String username, 
           @Part("file") RequestBody profilePhoto); 

... 

@Test 
public void saveProfilePhoto_shouldSavePhoto() throws IOException { 
    // Given 
    String usernamme = usernames[0]; 
    Resource testImageResource = context.getResource("classpath:images/test_image.jpg"); 
    File imageFile = testImageResource.getFile(); 
    RequestBody body = RequestBody.create(okhttp3.MediaType.parse("image/*"), imageFile); 

    // When 
    Response<Void> response = getTestApi().uploadProfilePhoto(usernamme, body).execute(); 

    // Then 
    assertThat(response.code()).isEqualTo(201); 
} 

मैं तो मेरे ही कस्टम ऑटो विन्यास का उपयोग कर रहा कॉन्फ़िगर क्लास स्टॉर्मपाथ को कॉन्फ़िगर करता है:

@Configuration 
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.apply(stormpath()); 
    } 
} 

अद्यतन: यह आउटगोइंग अनुरोध है। मुझे यकीन नहीं है कि मल्टीपार्ट रिज़ॉल्वर में लॉगिंग को कैसे सक्षम किया जाए।

2016-08-18 14:44:14.714 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : --> POST http://localhost:8080/users/user1/profilePhoto http/1.1 
2016-08-18 14:44:14.714 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : Content-Type: multipart/form-data; boundary=fe23ef21-3413-404c-a260-791c6921b2c6 
2016-08-18 14:44:14.715 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : Content-Length: 181212 
2016-08-18 14:44:14.715 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : Accept: application/json 
2016-08-18 14:44:14.715 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : Authorization: Bearer [token] 
2016-08-18 14:44:14.715 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : 
2016-08-18 14:44:14.735 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : --fe23ef21-3413-404c-a260-791c6921b2c6 
Content-Disposition: form-data; name="file" 
Content-Transfer-Encoding: binary 
Content-Type: image/* 
Content-Length: 180999 

file data 

--fe23ef21-3413-404c-a260-791c6921b2c6-- 

2016-08-18 14:44:14.762 DEBUG 13088 --- [   main] c.t.server.web.testutil.TestConfig$1  : --> END POST (181212-byte body) 

क्या हो रहा है पर कोई विचार?

+0

क्या आप अनुरोध कर सकते हैं कि अनुरोध पेलोड कैसा दिखता है? हो सकता है कि आप 'मल्टीपार्ट रीसोल्वर' को डीबग लेवल लॉगिंग भी जोड़ सकें जिसका उपयोग आप यह देखने के लिए कर रहे हैं कि यह अनुरोध के मल्टीपार्ट घटक का अर्थ है या नहीं? –

+0

@ शॉन-क्लर्क यह आउटगोइंग अनुरोध है। मुझे यकीन नहीं है कि मल्टीपार्ट रिज़ॉल्वर में लॉगिंग को कैसे सक्षम किया जाए। अनुरोध हेडर: स्वीकार करें: आवेदन/json प्राधिकरण: बियरर [प्रमाणीकरण टोकन] अनुरोध शरीर: --56436527-d311-4d26-8e67-27fdf6f0edb8 सामग्री-विन्यास: फार्म डेटा; नाम = "फाइल" सामग्री-स्थानांतरण-एन्कोडिंग: द्विआधारी सामग्री प्रकार: image/* सामग्री-लंबाई: 180,999 [... द्विआधारी ...] --56436527-d311-4d26-8e67- 27fdf6f0edb8-- – JabariP

+0

जैसा कि आप वसंत बूट 1.4 का उपयोग कर रहे हैं, आप मेरे समाधान का उपयोग कर सकते हैं और यह – rajadilipkolli

उत्तर

1

मुझे पता चला कि समस्या यह है कि मैं रेट्रोफिट के साथ अपना अनुरोध बना रहा था।

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

जानकारी के अनुसार यहां मिली: https://futurestud.io/blog/retrofit-2-how-to-upload-files-to-server, मेरे एपीआई इंटरफेस होना चाहिए:

@Multipart 
@POST("users/{username}/profilePhoto") 
Call<Void> uploadProfilePhoto(@Path("username") String username, 
           @Part MultipartBody.Part profilePhoto); 

और फिर जब अपने परीक्षण में कॉल करने से:

// Given 
String usernamme = usernames[0]; 
Resource testImageResource = context.getResource("classpath:images/test_image.jpg"); 
File imageFile = testImageResource.getFile(); 
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile); 
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile); 

// When 
Response<Void> response = testApi.uploadProfilePhoto(usernamme, filePart).execute(); 
+0

खुशी है कि आप इसे जा रहे हैं। मैं वही सोच रहा था लेकिन आपका नमूना अनुरोध दिखाता है कि नाम "फ़ाइल" के रूप में है। –

2

आपको Spring Multipart Resolver को डिफ़ॉल्ट रूप से सक्षम करना है स्प्रिंग मल्टीपार्ट क्षमता को सक्षम नहीं करता है।

डिफ़ॉल्ट रूप से, स्प्रिंग, कोई बहुखण्डीय हैंडलिंग करता है क्योंकि कुछ डेवलपर्स multiparts खुद को हैंडल करना चाहते हैं। आप वेब अनुप्रयोग के संदर्भ में मल्टीपार्ट रिज़ॉल्वर जोड़कर स्प्रिंग मल्टीपार्ट हैंडलिंग सक्षम करते हैं।

आपके विन्यास वर्ग के लिए

आप निम्नलिखित सेम जोड़ना चाहते हैं:

@Bean 
public MultipartResolver multipartResolver() { 
    return new CommonsMultipartResolver(); 
} 

* अद्यतन * मेरे पिछले जवाब के रूप में टिप्पणी के आधार पर सही नहीं था। यहां एक अद्यतन उदाहरण है कि मैं सफलतापूर्वक चलाने में सक्षम था।

@SpringBootApplication 
public class StackoverflowWebmvcSandboxApplication { 
    public static void main(String[] args) { 
     SpringApplication.run(StackoverflowWebmvcSandboxApplication.class, args); 
    } 

    @Controller 
    public class UploadPhoto { 
     @PostMapping("{username}/profilePhoto") 
     public ResponseEntity<String> saveProfilePhoto(@PathVariable("username") String username, 
       @RequestPart(name = "file", required = false) MultipartFile imageFile, HttpServletRequest request) { 
      String body = "MultipartFile"; 
      if (imageFile == null) { 
       body = "Null MultipartFile"; 
      } 

      return ResponseEntity.status(HttpStatus.CREATED).body(body); 
     } 
    } 
} 

यह किसी विशेष सामान के साथ एक बहुत ही बुनियादी परीक्षण है। मैं तो एक डाकिया अनुरोध बनाया है और यहाँ नमूना कर्ल कॉल है:

curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 17e5e6ac-3762-7d45-bc99-8cfcb6dc8cb5" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "[email protected]" "http://localhost:8080/test/profilePhoto" 

प्रतिक्रिया MultipartFile अर्थ था कि यह रिक्त नहीं था और कहा कि लाइन पर एक डिबग कर पता चला है कि चर छवि के साथ बसा हुआ था कि मैं अपलोड कर रहा था

+0

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

+0

आह अच्छा ... इसके लिए स्वत: कॉन्फ़िगरेशन की जांच नहीं की गई है, लेकिन तब से इसे 'मल्टीपार्टऑटो कॉन्फ़िगरेशन' के अंतर्गत मिला है। यह 'StandardServletMultipartResolver' का उपयोग करने के लिए डिफ़ॉल्ट रूप से दिखता है। आपने कहा था कि आपको अभी भी 'CommonsMultipartResolver' के साथ त्रुटि मिल रही है, ऐसा लगता है कि अनुरोध में आने के तरीके के साथ यह एक और समस्या है। –

0

आप Spring Multipart Resolver के रूप में सक्षम करने के लिए डिफ़ॉल्ट रूप से वसंत मल्टीपार्ट क्षमता को सक्षम नहीं करता है।

डिफ़ॉल्ट रूप से, स्प्रिंग, कोई बहुखण्डीय हैंडलिंग करता है क्योंकि कुछ डेवलपर्स multiparts खुद को हैंडल करना चाहते हैं। आप वेब अनुप्रयोग के संदर्भ में मल्टीपार्ट रिज़ॉल्वर जोड़कर स्प्रिंग मल्टीपार्ट हैंडलिंग सक्षम करते हैं।

आपके विन्यास वर्ग के लिए

आप निम्नलिखित सेम जोड़ना चाहते हैं:

@Bean 
public MultipartResolver multipartResolver() { 
    return new StandardServletMultipartResolver(); 
} 

के बाद से वसंत बूट 1.4 + सर्वलेट का उपयोग करता है 3.0+ हम क्लासिक CommonsMultipartResolver

+0

समस्या का समाधान नहीं करता – AutoMEta

+0

वसंत बूट का कौन सा संस्करण आप उपयोग कर रहे हैं? – rajadilipkolli

+0

https: // github।com/rajadilipkolli/spring-mvc-showcase/blob/master/src/main/java/org/springframework/samples/mvc/config/webMvcConfig.java # L99-L112 नमूना कोड जो काम कर रहा है – rajadilipkolli

0

के बजाय StandardServletMultipartResolver पर लाभ उठा सकते हैं देखें इस यूआरएल में मेरे उत्तर में: Spring Boot multipart upload getting null file object

मूल रूप से आपको डिफ़ॉल्ट स्प्रिंग कॉन्फ़िगरेशन से बचना होगा मल्टीपार्ट के लिए आयन और अपने अनुरोध हेडर में सामग्री-प्रकार या सीमा सेट करने से बचें।