简体   繁体   English

将文件上传到服务器,java.net.ProtocolException:读取响应后无法写入请求正文

[英]Upload File To Server, java.net.ProtocolException: cannot write request body after response has been read

I want to upload file to server from Android apps. 我想从Android应用程序将文件上传到服务器。 I try this but still cannot upload file to server. 我尝试这样做,但仍然无法将文件上传到服务器。 There's an error in my java. 我的java中有错误。

public class UploadFileActivity extends AppCompatActivity implements View.OnClickListener{

    private static final int PICK_FILE_REQUEST = 1;
    private static final String TAG = MainActivity.class.getSimpleName();
    private String selectedFilePath;
    private String SERVER_URL = "http://url.com/mobile/json/upload_file.php";
    ImageView ivAttachment;
    Button bUpload;
    TextView tvFileName;
    ProgressDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_upload_file);
        ivAttachment = (ImageView) findViewById(R.id.ivAttachment);
        bUpload = (Button) findViewById(R.id.b_upload);
        tvFileName = (TextView) findViewById(R.id.tv_file_name);
        ivAttachment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFileChooser();
            }
        });
        bUpload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(selectedFilePath != null){
                    dialog = ProgressDialog.show(UploadFileActivity.this,"","Uploading File...",true);

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            uploadFile(selectedFilePath);
                        }
                    }).start();
                }else{
                    Toast.makeText(UploadFileActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }


    @Override
    public void onClick(View v) {
    }

    private void showFileChooser() {
        Intent intent = new Intent();
        intent.setType("*/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == Activity.RESULT_OK){
            if(requestCode == PICK_FILE_REQUEST){
                if(data == null){
                    //no data present
                    return;
                }


                Uri selectedFileUri = data.getData();
                if(Build.VERSION.SDK_INT >= 19) {
                    selectedFilePath = FilePath.getPath(this, selectedFileUri);
                } else {
                    selectedFilePath = FilePath.getSmartFilePath(this, selectedFileUri);
                }

                Log.i(TAG,"Selected File Path:" + selectedFilePath);

                if(selectedFilePath != null && !selectedFilePath.equals("")){
                    tvFileName.setText(selectedFilePath);
                }else{
                    Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    public int uploadFile(final String selectedFilePath){

        int serverResponseCode = 0;

        HttpURLConnection connection;
        DataOutputStream dataOutputStream;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        final String boundary = "*****";


        int bytesRead,bytesAvailable,bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        File selectedFile = new File(selectedFilePath);

        String[] parts = selectedFilePath.split("/");
        String fileName = parts[parts.length-1];
        String[] separate = fileName.split(Pattern.quote("."));
        final String fileNameDoang = separate[0];
        final String fileType = separate[1];

        if (!selectedFile.isFile()){
            dialog.dismiss();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvFileName.setText("Source File Doesn't Exist: " + selectedFilePath);
                }
            });
            return 0;
        }else{
            try{
                FileInputStream fileInputStream = new FileInputStream(selectedFile);
                URL url = new URL(SERVER_URL);
                connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);//Allow Inputs
                connection.setDoOutput(true);//Allow Outputs
                connection.setUseCaches(false);//Don't use a cached Copy
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("ENCTYPE", "multipart/form-data");
                connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                connection.setRequestProperty("uploaded_file",selectedFilePath);
                int sizeFile = connection.getContentLength();   
                dataOutputStream = new DataOutputStream(connection.getOutputStream());

                dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
                dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                        + selectedFilePath + "\"" + lineEnd);

                dataOutputStream.writeBytes(lineEnd);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable,maxBufferSize);
                buffer = new byte[bufferSize];

                bytesRead = fileInputStream.read(buffer,0,bufferSize);

                while (bytesRead > 0){
                    //write the bytes read from inputstream
                    dataOutputStream.write(buffer,0,bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable,maxBufferSize);
                    bytesRead = fileInputStream.read(buffer,0,bufferSize);
                }

                dataOutputStream.writeBytes(lineEnd);
                dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                serverResponseCode = connection.getResponseCode();
                String serverResponseMessage = connection.getResponseMessage();

                Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);

                if(serverResponseCode == 200){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tvFileName.setText("File Upload completed.\n\n File Name : \n\n" + fileNameDoang + "File Type" + fileType);
                        }
                    });
                }

                fileInputStream.close();
                dataOutputStream.flush();
                dataOutputStream.close();


            } catch (FileNotFoundException e) {
                e.printStackTrace();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(UploadFileActivity.this,"File Not Found",Toast.LENGTH_SHORT).show();
                    }
                });
            } catch (MalformedURLException e) {
                e.printStackTrace();
                Toast.makeText(UploadFileActivity.this, "URL error!", Toast.LENGTH_SHORT).show();

            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(UploadFileActivity.this, "Cannot Read/Write File!", Toast.LENGTH_SHORT).show();
            }
            dialog.dismiss();
            return serverResponseCode;
        }
    }
}

Get filepath I put in another java. 获取我放入另一个Java的文件路径。 This is the warning and error: 这是警告和错误:

09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err: java.net.ProtocolException: cannot write request body after response has been read
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:223)
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:     at com.sintask.android.ui.UploadFileActivity.uploadFile(UploadFileActivity.java:195)
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:     at com.sintask.android.ui.UploadFileActivity$2$1.run(UploadFileActivity.java:66)
09-30 20:44:50.766 9855-10872/com.sintask.android W/System.err:     at java.lang.Thread.run(Thread.java:818)
09-30 20:44:50.766 9855-10872/com.sintask.android E/AndroidRuntime: FATAL EXCEPTION: Thread-5234
                                                                    Process: com.sintask.android, PID: 9855
                                                                    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                                                                        at android.os.Handler.<init>(Handler.java:200)

It's because you called getContentLength() before getting the output stream. 这是因为您在获取输出流之前调用了getContentLength() Doesn't make any sense. 没有任何意义。 You're uploading, not downloading. 您正在上传,而不是下载。 You don't need the content length, or if you do you don't need it until after you've uploaded the file. 您不需要内容长度,或者如果您不需要,则在上传文件后才需要。

NB available() is not a correct way to determine the length of a file, or of any input stream. 注意, available()不是确定文件或任何输入流长度的正确方法。 Use File.length() . 使用File.length()

暂无
暂无

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

相关问题 服务器发送请求firebase java.net.protocolexception无法在读取响应后写入请求正文 - Server Send Requests firebase java.net.protocolexception cannot write request body after response has been read java.net.ProtocolException:读取输入后无法写入输出 - java.net.ProtocolException: Cannot write output after reading input java.net.ProtocolException: 方法不支持请求正文:GET - java.net.ProtocolException: method does not support a request body: GET java.net.ProtocolException:在哪里读取输入? - java.net.ProtocolException: where is input being read? java.net.ProtocolException: 服务器重定向次数过多 (20) - java.net.ProtocolException: Server redirected too many times (20) java.net.ProtocolException: 服务器重定向次数过多 - java.net.ProtocolException: Server redirected too many times OkHttp“java.net.ProtocolException:意外状态行:nullHTTP / 1.1 200 OK”在使用相同连接的“204 NO-CONTENT”响应之后 - OkHttp “java.net.ProtocolException: Unexpected status line: nullHTTP/1.1 200 OK” after a “204 NO-CONTENT” response using same connection android中带有HttpsURLConnection的java.net.protocolException - java.net.protocolException with HttpsURLConnection in android java.net.Authenticator:java.net.ProtocolException:服务器重定向太多次(20) - java.net.Authenticator : java.net.ProtocolException: Server redirected too many times (20) java.net.ProtocolException:当我通过okhttp上传图像到服务器时,发生了意外的流结束 - java.net.ProtocolException: unexpected end of stream happened when i uploaded a image to server by okhttp
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM