简体   繁体   English

上传文件时使用HttpUrlConnection时出错

[英]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. 我有一个Android应用程序和我的魔杖从这个应用程序上传,大图像(在这种情况下32MB)到Spring Server,但我得到java.net.SocketException:sendto失败:EPIPE(断管)错误。

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. params: userpicturehavePicture是我想用大图像发送json的一些对象,这种方法适用于小于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) java.net.SocketException:sendto failed:在java.net.PlainSocketImpl上的libcore.io.IoBridge.sendto(IoBridge.java:555)的libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:586)上的EPIPE(Broken pipe) .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 com.android.okhttp上com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)的com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)$ 1.write(Okio.java:70) .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)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 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)在com.mayan.amenidrade.android.tools.Server $ override.setPicture(Server.java:363)com.mayan的com.android.tools.fd.runtime.AndroidInstantRuntime.invokeProtectedStaticMethod(AndroidInstantRuntime.java:170) .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 java.lang.Thread.run上的$ 2 $ 1.run(MainActivity.java:99)(Thread.java:818)引起:android.system.ErrnoException:sendto failed:libcore.io.Posix中的EPIPE(Broken pipe)。发送到libcore.io.Posix.sendto(Posix.java:206)的libto.io.BlockGuardOs.sendto(BlockGuardOs.java:278)的libto.io.IoBridge.sendto(IoBridge.java:553)的sendtoBytes(Native Method) ......还有20个

I dont now what to do, thank for any help ! 我现在不做该做什么,谢谢你的帮助!

You cannot use PrintWriter to upload an image... well you dont... but... 你无法使用PrintWriter上传图片......你不...但......

PrintWriter is for texts only. PrintWriter仅用于文本。

You are mixing PrintWriter and the normal OutputStream. 您正在混合PrintWriter和普通的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 感谢@Randyka Yudhistira和@greenapps的帮助,我的问题是客户端的一些不必要的代码,主要是我的Spring服务器无法上传大文件

Solution

Add inserver side : 添加inserver端:

<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. 在我的情况下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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