URLConnection always returns 400 : Bad Request whe

2019-03-04 14:07发布

问题:

I want to implement some code that does exactly what I accomplish when I execute a CURL command in my Mac's terminal, which is to upload a .wav file to a Server. I already accomplished this for one server before, so my general thinking works (and my code too), ....but now I want to accomplish the same but on a different server. This time I am having trouble and all I get are "400:Bad Request"

This is he CURL command I want to do on Android, I have added a "-v" so you can see the verbose of my command.

curl -F file=@audio_life.wav 11.2.333.44:14141/transcribe -v

Output log in Terminal:

*   Trying 11.2.333.44...
* Connected to 11.2.333.44 (11.2.333.44) port 14141 (#0)
> POST /transcribe HTTP/1.1
> Host: 11.2.333.44:14141
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 304898
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------62142b52672c69e0
> 
* Done waiting for 100-continue
< HTTP/1.1 201 Created
< Content-Type: application/json
< Content-Length: 915

This is my code, I always get 400:Bad Request responses, as you can see I have tried to replicate the headers. What am I doing wrong? how can I close in on what the error may be?

String wavpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/ArtificialSolutions/"+StorageUtils.AUDIO_FILE_NAME+".wav"; 
                File wavfile = new File(wavpath);
                FileInputStream fileInputStream = new FileInputStream(wavpath);
                connectURL = new URL(ASR_URL_VOCITEC);
                String filevalue = StorageUtils.AUDIO_FILE_NAME+".wav";
                HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection();
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.setUseCaches(false);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Host","11.2.333.44:14141");
                conn.setRequestProperty("User-Agent", "android");
                conn.setRequestProperty("Accept","*/*");
                conn.setRequestProperty("Transfer-Encoding", "chunked");
                conn.setRequestProperty("Expect", "100-continue");
                conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=------------------------f016e997e308ec07");//+boundary);
                DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\"File\""+ lineEnd);
                //dos.writeBytes("Content-Disposition: form-data; File=\""+wavpath+"\""+ lineEnd);
                dos.writeBytes(lineEnd);

                dos.writeBytes(wavpath);
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                int bytesAvailable = fileInputStream.available();     
                int maxBufferSize = 1024;
                int bufferSize = Math.min(bytesAvailable, maxBufferSize);
                byte[ ] buffer = new byte[bufferSize];
                int bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0){
                        dos.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        Log.e("joshtag","BytesAvailable: "+bytesAvailable);
                        bufferSize = Math.min(bytesAvailable,maxBufferSize);
                        if(bytesAvailable>maxBufferSize){
                            bytesRead = fileInputStream.read(buffer, 0,bufferSize);
                        }
                        else{
                            bytesRead = fileInputStream.read(buffer, 0,bytesAvailable);
                            dos.write(buffer, 0, bytesAvailable);
                            break;
                        }
                }
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                fileInputStream.close();//63532 , 64556

                dos.flush();

                Log.e(Tag,"File Sent, Response: "+String.valueOf(conn.getResponseCode()));
                Log.e(Tag,"File Sent, ResponseMSG: "+String.valueOf(conn.getResponseMessage()));

This is a printout of the message I get back from the server:

{null=[HTTP/1.1 400 Bad Request], Content-Length=[42], Content-Type=[text/plain], X-Android-Received-Millis=[1449836192887], X-Android-Response-Source=[NETWORK 400], X-Android-Sent-Millis=[1449836192719]}

NOTE: I coded this based on the best of my knowledge and after examining related posts here on StartOverflow, the whole code is inside the doInBackground method of an AsyncTask so lets focus here. I hope can help me!! Thanks.

回答1:

After much fiddling with the code, I found a way to upload a wav file with URLConnection, and using multipartentity. Here is the code, enjoy:

public int uploadWav(String sourceFileUri) {  
    String wavpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/myAppFolder/"+StorageUtils.AUDIO_FILE_NAME+".wav";
    String filename=wavpath;
    HttpURLConnection conn = null;
    DataOutputStream dos = null;  
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "------------------------afb19f4aeefb356c";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024; 
    File sourceFile = new File(fileName); 
    Log.e("joshtag", "Uploading: sourcefileURI, "+fileName);

    if (!sourceFile.isFile()) {                                
         Log.e("uploadFile", "Source File not exist :"+wavpath);//FullPath);                        
         return 0;  //RETURN #1
         }
    else{
        try{        
             Log.v("joshtag","UPLOADING .WAV FILE");
             FileInputStream fileInputStream = new FileInputStream(sourceFile);   
             URL url = new URL(SERVER_URL);
             Log.v("joshtag","UL URL: "+url.toString());

             // Open a HTTP  connection to  the URL
             conn = (HttpURLConnection) url.openConnection(); 
             conn.setDoInput(true); // Allow Inputs
             conn.setDoOutput(true); // Allow Outputs
             conn.setUseCaches(false); // Don't use a Cached Copy            s       
             conn.setRequestMethod("POST");                     
            // conn.setRequestProperty("Connection", "Keep-Alive");
             conn.setRequestProperty("ENCTYPE", "multipart/form-data");
             conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);     
             conn.setRequestProperty("file", sourceFile.getName()); 
             //so on and so forth...
             //conn.setRequestProperty("param", "value");  
             conn.setRequestProperty("connection", "close");
             dos = new DataOutputStream(conn.getOutputStream());          
             dos.writeBytes(twoHyphens + boundary + lineEnd); 
             dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + sourceFile.getName() + "\"" + lineEnd);                    
             dos.writeBytes(lineEnd);      

             // create a buffer of  maximum size
             bytesAvailable = fileInputStream.available();           
             bufferSize = Math.min(bytesAvailable, maxBufferSize);
             buffer = new byte[bufferSize];         
             // read file and write it into form...
             bytesRead = fileInputStream.read(buffer, 0, bufferSize);   

             while (bytesRead > 0) {                        
                    dos.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    Log.i("joshtag","->");
                    }
             Log.i("joshtag","->->");
             // send multipart form data necesssary after file data...
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
             conn.connect();
             Log.i("joshtag","->->->");
             // Responses from the server (code and message)
             serverResponseCode = conn.getResponseCode();
             Log.i("joshtag","->->->->");
             String serverResponseMessage = conn.getResponseMessage().toString();     

             Log.i("joshtag","->->->->->");
             Log.i("joshtag", "HTTP Response is : "  + serverResponseMessage + ": " + serverResponseCode);   

             // ------------------ read the SERVER RESPONSE
             DataInputStream inStream;
             String str="";
             String response="";
             try {
                 Log.i("joshtag","->->->->->->");
                 inStream = new DataInputStream(conn.getInputStream());

                 while ((str = inStream.readLine()) != null) {
                     Log.e("joshtag", "SOF Server Response" + str);
                     response=str;
                    }
                 inStream.close();
                }
             catch (IOException ioex) {
                Log.e("joshtag", "SOF error: " + ioex.getMessage(), ioex);
                }
             conn.disconnect();
             conn=null;                       
             //close the streams //
             fileInputStream.close();
             dos.flush();
             dos.close();    

             if(serverResponseCode == 201){       
                 loge("*** SERVER RESPONSE: 201"+response);
                }//END IF Response code 201  
            // conn.disconnect();
            }//END TRY - FILE READ      
        catch (MalformedURLException ex) {
            ex.printStackTrace();   
            Log.e("joshtag", "UL error: " + ex.getMessage(), ex);  
            } //CATCH - URL Exception

         catch (Exception e) {           
            e.printStackTrace();             
            Log.e("Upload file to server Exception", "Exception : "+ e.getMessage(), e);
            } 

        return serverResponseCode; //after try       
        }//END ELSE, if file exists.
    }