2015-06-30 8 views
13

का कारण बनता है मैं जर्सी 2.0 के साथ फॉर्म सबमिशन सेवा विकसित कर रहा हूं। इस फॉर्म में कई टेक्स्ट फ़ील्ड और एक फ़ाइल फ़ील्ड शामिल है। मैं फ़ाइल, फ़ाइल नाम, फ़ाइल मीडिया प्रकार और फ़ाइल सामग्री प्रकार निकालें और उन्हें वस्तु की दुकान में बचाने की जरूरत है।जर्सी सेवा फ़ाइल अपलोड आउटऑफमेमरी एरर

@Path("upload") 
@Consumes({MediaType.MULTIPART_FORM_DATA}) 
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) 
public class UploadService { 
    @POST 
    public BlobDo uploadFile(FormDataMultiPart uploadedBody) { 
     String accountSid = uploadedBody.getField("account-sid").getValue(); 
     String apiToken = uploadedBody.getField("api-token").getValue(); 
     String checksum = uploadedBody.getField("checksum").getValue(); 

     FormDataBodyPart bodyPart = uploadedBody.getField("file"); 
     MySwiftObject obj = new MySwiftObject(bodyPart.getValueAs(InputStream.class)); 
     obj.setName(bodyPart.getContentDisposition().getFileName()); 
     obj.setContentType(bodyPart.getMediaType().toString()); 
     obj.setContentDisposition(bodyPart.getContentDisposition().toString()); 
    ... 
} 

pom.xml

<jersey.version>2.17</jersey.version> 

<dependency> 
    <groupId>org.glassfish.jersey.containers</groupId> 
    <artifactId>jersey-container-servlet-core</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-json-jackson</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.test-framework.providers</groupId> 
    <artifactId>jersey-test-framework-provider-inmemory</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-multipart</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.core</groupId> 
    <artifactId>jersey-server</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.ext</groupId> 
    <artifactId>jersey-bean-validation</artifactId> 
</dependency> 

फ़ॉर्म जमा अनुरोध

POST /nbs/v2/upload HTTP/1.1 
Host: 127.0.0.1:8080 
Cache-Control: no-cache 
Postman-Token: a4c1d4e9-5f71-2321-3870-e9cac0524f8d 
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryA2Z9pPMA7y3da8BG 

------WebKitFormBoundaryA2Z9pPMA7y3da8BG 
Content-Disposition: form-data; name="account-sid" 

Q45Ppm5ukvdqjTQ6eW0O5ztTXipwnjKQx1p6cf+fbCQ= 
------WebKitFormBoundaryA2Z9pPMA7y3da8BG 
Content-Disposition: form-data; name="api-token" 

6397cd691909fdc14cef67dbc1dc2dc3 
------WebKitFormBoundaryA2Z9pPMA7y3da8BG 
Content-Disposition: form-data; name="file"; filename="screen_4_100155.jpg" 
Content-Type: image/jpeg 

......Exif..MM.*.............................b...........j 
------WebKitFormBoundaryA2Z9pPMA7y3da8BG 
Content-Disposition: form-data; name="checksum" 

6a3381b1d16bded4a3dfc325a8bb800e 
------WebKitFormBoundaryA2Z9pPMA7y3da8BG 

JVM ढेर आकार

-Xmx=1024mb 

समस्या

अपलोड करने ~ समान MD5 रकम के साथ 50MB फ़ाइल दो अस्थायी फ़ाइलों को नाम FileBackedOutputStream7949386530699987086.tmp और MIME8234229766850016150.tmp

साथ निर्देशिका /tmp/tomcat7-tomcat7-tmp में बनाए जाते हैं जब से पहले अपलोड पूरा सर्वर अपवाद फेंकता

 
javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: Java heap space 
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:421) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222) 

है और फ़ाइल को हटा देता है नाम MIME8234229766850016150.tmp के साथ लेकिन दूसरे को छोड़ देता है। और FileBackedOutputStream....tmp फ़ाइलों को अवांछित हार्ड ड्राइव पर पूरी जगह भरें।


क्या मैं 7GB को

  1. बढ़ाएँ ढेर अंतरिक्ष किया था, लेकिन ~ 200MB फ़ाइलों को अपलोड नहीं किया जा सकता।

  2. पुराने अस्थायी फ़ाइलों को हटाने के लिए सर्वर पर नौकरी चलाएं। नाम jersey-multipart-config.properties और सामग्री

    jersey.config.multipart.bufferThreshold = -1

फ़ाइल MIME[random numbers].tmp साथ

  • बनाया गया फ़ाइल नहीं रह बनाई गई है, लेकिन अभी भी FileBackedOutputStream[random number].tmp हार्ड ड्राइव पर लटका हुआ है, जब तक कि बिल्ला को पुन: प्रारंभ किया गया है।


    प्रश्न

    1. कैसे जर्सी मेरी हार्ड डिस्क पर अस्थायी फ़ाइलों को छोड़े बिना बड़ी फ़ाइलों (शायद 1GB) संभाल कर सकते हैं? सबसे अच्छा मामला हार्ड ड्राइव का उपयोग नहीं करना होगा और स्मृति के माध्यम से छोटे हिस्सों को स्थानांतरित करना होगा।

    2. इनपुट स्ट्रीम को फ़ाइलों के साथ समर्थित होने पर मुझे ढेर ओवरफ्लो क्यों मिलता है?


    सामग्री मैंने पढ़ा

    • The I अब तक पाया स्पष्टीकरण बंद कर देता है। read
    • इस लड़के को समान समस्या है लेकिन ग्राहक पक्ष पर है। read
    • समाधान हो सकता है, लेकिन उत्तर को समझ में नहीं आया। read
    • मेरी समस्या के बहुत करीब है लेकिन इसे काम नहीं कर सकता है। read
    • बफर थ्रेसहोल्ड विचार यहां से लिया गया था। read
  • उत्तर

    3

    ऐसा लगता है कि # 1 समस्या <servlet> टैग

    <multipart-config> 
         <location>/tmp</location> 
         <max-file-size>1000000000</max-file-size> 
         <max-request-size>1500000000</max-request-size> 
         <file-size-threshold>0</file-size-threshold> 
    </multipart-config> 
    

    के तहत मेरे web.xml में निम्नलिखित लाइनों को जोड़कर हल और jersey-multipart-config.properties फ़ाइल हटा दिया गया था।

    अब मैं 200 एमबी से अधिक फ़ाइलों को अपलोड कर सकता हूं। कोई और अस्थायी फ़ाइलें नहीं बनाई गई हैं।

    लेकिन मैं अभी भी समस्या # 2 की व्याख्या नहीं कर सकता।

    संबंधित मुद्दे