简体   繁体   中英

Getting error when upload file used HttpUrlConnection

I have a android app and i wand to upload from this app, Large image (in this case 32MB) to Spring Server, but i got java.net.SocketException: sendto failed: EPIPE (Broken pipe) error.

i use this method :

public static void setPicture(User user, Picture picture, HavePicture havePicture, File file) {
    try {
        URL url = new URL(Request.BASE_URL + Request.BASE_PATH + Request.GAME_SYSTEM_PATH + Request.SET_PICTURE_PATH);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setUseCaches(false);
        connection.setDoOutput(true); // indicates POST method
        connection.setDoInput(true);
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        connection.setRequestProperty("User-Agent", "CodeJava Agent");
        connection.setRequestProperty("Test", "Bonjour");

        //load file with multi small pices not one lage pice good to use large filse
        connection.setChunkedStreamingMode(1024);

        OutputStream outputStream = connection.getOutputStream();
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, Request.CHARSET), true);

        addFormField(writer, Request.PARAM_USER, Json.toJson(user));
        addFormField(writer, Request.PARAM_PICTURE, Json.toJson(picture));
        addFormField(writer, Request.PARAM_HAVE_PICTURE, Json.toJson(havePicture));
        addFilePart(writer, outputStream, Request.PARAM_FILE, file);

        StringBuffer response = new StringBuffer();

        writer.append(LINE_FEED).flush();
        writer.append("--" + boundary + "--").append(LINE_FEED);
        writer.close();
        // checks server's status code first
        int status = connection.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            connection.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }

        String a =  response.toString();
        System.out.println(a);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

the params : user , picture , and havePicture are some objects that i whant to send they json with the big image, this method actully work with small image least then 1MB.

here the rest of the methods :

private static void addFormField(PrintWriter writer, String name, String value) {
    writer.append("--" + boundary).append(LINE_FEED);
    writer.append("Content-Disposition: form-data; name=\"" + name + "\"").append(LINE_FEED);
    writer.append("Content-Type: text/plain; charset=" + Request.CHARSET).append(LINE_FEED);
    writer.append(LINE_FEED);
    writer.append(value).append(LINE_FEED);
    writer.flush();
}

Use for the image file :

private static void addFilePart(PrintWriter writer,OutputStream outputStream, String fieldName, File uploadFile) throws IOException {
    String fileName = uploadFile.getName();
    writer.append("--" + boundary).append(LINE_FEED);
    writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED);
    writer.append("Content-Type: "+URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
    writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);

    FileInputStream inputStream = new FileInputStream(uploadFile);

    writer.append("Content-length: "+inputStream.available()).append(LINE_FEED);
    System.out.println("- - "+"Content-length: "+inputStream.available());
    writer.append(LINE_FEED);
    writer.flush();


    byte[] buffer = new byte[4096];
    int bytesRead = -1;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
    }
    outputStream.flush();
    inputStream.close();

    writer.append(LINE_FEED);
    writer.flush();
}

Here my completed error :

java.net.SocketException: sendto failed: EPIPE (Broken pipe) at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:586) at libcore.io.IoBridge.sendto(IoBridge.java:555) at java.net.PlainSocketImpl.write(PlainSocketImpl.java:520) at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:43) at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:272) at com.android.okio.Okio$1.write(Okio.java:70) at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116) at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44) at com.android.okhttp.internal.http.HttpConnection$ChunkedSink.write(HttpConnection.java:334) at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116) at com.android.okio.RealBufferedSink$1.write(RealBufferedSink.java:131) at com.mayan.ameritrade.android.tools.Server$override.addFilePart(Server.java:435) at com.mayan.ameritrade.android.tools.Server$override.access$dispatch(Server.java) at com.mayan.ameritrade.android.tools.Server.addFilePart(Server.java:0) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.tools.fd.runtime.AndroidInstantRuntime.invokeProtectedStaticMethod(AndroidInstantRuntime.java:170) at com.mayan.ameritrade.android.tools.Server$override.setPicture(Server.java:363) at com.mayan.ameritrade.android.tools.Server$override.access$dispatch(Server.java) at com.mayan.ameritrade.android.tools.Server.setPicture(Server.java:0) at com.mayan.ameritrade.android.MainActivity$2$1.run(MainActivity.java:99) at java.lang.Thread.run(Thread.java:818) Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe) at libcore.io.Posix.sendtoBytes(Native Method) at libcore.io.Posix.sendto(Posix.java:206) at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278) at libcore.io.IoBridge.sendto(IoBridge.java:553) ... 20 more

I dont now what to do, thank for any help !

You cannot use PrintWriter to upload an image... well you dont... but...

PrintWriter is for texts only.

You are mixing PrintWriter and the normal OutputStream. That will not do.

You should write to one type of stream only.

My problem solved ! thank to @Randyka Yudhistira and @greenapps for help, my problem was some unnecessary code in client, And Mainly my Spring server not able to upload large files

Solution

Add inserver side :

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSizePerFile">yourMaxSizeToUpload</property>
</bean>

or

@Bean
public CommonsMultipartResolver getCommonsMultipartResolver() {
    CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    resolver.setMaxUploadSize(yourMaxSizeToUpload);
    return resolver;
}

If this not work try to remove unnecessary code like :

writer.append("Content-length: "+inputStream.available()).append(LINE_FEED);

in my case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM