2011-07-11 8 views
2

(これは署名付きのアプレット用で、私はHTTPClientを使用してjarファイルを非常に小さく保つことに決めました)Java HttpURLConnectionで複数の部分からなるフォーム投稿のバッファリングを無効にするにはどうすればよいですか?

私はHttpURLConnectionを使用して、マルチパートフォーム投稿を使ってユーザーからサーバーにファイルを正常にアップロードしています。

問題は、HttpURLConnectionが送信前にデータをキャッシュしていることです。したがって、ファイルから読み込んでOutputstreamに書き込むとき、データを単にバッファリングしているだけなので、アップロード状況を示すプログレスバーは完全に間違っています。投稿コードが動作し、返信コードが200で正しくファイルがアップロードされることにご注意ください。

したがって、私はHttpURLConnectionがサーバーに送信しているデータを確実にキャッシュしないようにしますか?私は同じ問題を抱えている

public UploadResponse send(String formPostUrlStr,String fileFieldName,File targetFile, Map<String, String> valuesMap, UploadStatusListener uploadStatusListener) throws Exception{ 


    String sendStr=getBoundaryMessage(Boundary, valuesMap, fileFieldName, targetFile.getName(), valuesMap.get("content-type"));//"image/png") ; 

    System.out.println(" multi-part start \n "+ sendStr+ " multi-part end \n"); 

    String lenstr=Long.toString((long)(sendStr.length()*2)+ targetFile.length()); 
    System.out.println("Content-Length"+ lenstr); 
         //Content-Length 

    URL url= new URL(formPostUrlStr); 
    long startTime= System.currentTimeMillis(); 
    HttpURLConnection s3Connection = (HttpURLConnection) url.openConnection(); 

    System.out.println("opened url to "+ formPostUrlStr +", connection ok .."); 
    s3Connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" 
      + Boundary); 
    s3Connection.setRequestProperty("content-length", lenstr); 




    s3Connection.setDoOutput(true); 
    s3Connection.setDoInput(true); 
    s3Connection.setUseCaches(false); 
    s3Connection.setInstanceFollowRedirects(true); 
    s3Connection.setAllowUserInteraction(true); 
    s3Connection.setRequestProperty("User-Agent", "Mozilla/4.5"); 


    if (uploadStatusListener != null) { 
     uploadStatusListener.statusUpdate(targetFile.length(), 0); 
    } 


    String debugStr= s3Connection.toString(); 
    System.out.println("conmnection "+ debugStr); 


    DataOutputStream httpOut = new DataOutputStream(s3Connection.getOutputStream()); 

    System.out.println("opened DataOutputStream ok .."); 




    httpOut.write(sendStr.getBytes()); 


    //httpOut.flush(); 

    System.out.println("httpOut.flush 1 ok .."); 
    FileInputStream uploadFileReader = new FileInputStream(targetFile); 
    long totalBytes = uploadFileReader.available(); 
    if (uploadStatusListener != null) { 
     uploadStatusListener.statusUpdate(totalBytes, 0); 
    } 
    System.out.println(" uploading file with size "+ uploadFileReader.available()); 
    int bufSize = 102400; 
    long availableBytesToRead; 
    long totalSent = 0; 
    while ((availableBytesToRead = uploadFileReader.available()) > 0) { 
     byte[] bufferBytesRead; 
     bufferBytesRead = availableBytesToRead >= bufSize ? new byte[bufSize] 
       : new byte[(int)availableBytesToRead]; 
     int count = uploadFileReader.read(bufferBytesRead); 
     try{ 
      httpOut.write(bufferBytesRead); 
      totalSent += ((long) count); 
      System.out.println(" wrote bytes = "+count+ ", total sent = "+ totalSent +", pendingSize"+ (availableBytesToRead-count)); 
     } 
     catch(IOException ioe){ 
      System.out.println(" io exceotion e"+ ioe.getMessage()); 
      throw ioe; 
     } 

     //httpOut.flush(); 
     if (uploadStatusListener != null) { 
      uploadStatusListener.statusUpdate(totalBytes, totalSent); 
     } 

    } 
    // FILE DATA END 
    httpOut.write(("--" + Boundary + "--\r\n").getBytes()); 



    // form end  
    httpOut.write(("--" + Boundary + "--\r\n").getBytes()); 

    httpOut.flush(); 
    httpOut.close(); 

    long endTime= System.currentTimeMillis(); 

    System.out.println("Completed Writing Data to S3 Connection in "+ (endTime-startTime)+"ms.,now waiting for rsponse code "); 
    int code=s3Connection.getResponseCode(); 
    long endTime2= System.currentTimeMillis(); 
    System.out.println("Completed Sendind Data to S3 in "+ (endTime2-startTime)+ "ms., rsponse code time "+ (endTime2-endTime)+"ms. "); 


    UploadResponse uploadResponse = new UploadResponse(); 

    uploadResponse.setCode(code); 

    System.out.println(" response code : " + code); 

    StringBuilder response = new StringBuilder(); 
    byte[] respBuffer = new byte[4096]; 


    if (code > 300) { 
     if (code == 404) { 
      throw new Exception("Error 404"); 
     } 
     BufferedReader err = new BufferedReader(
       new InputStreamReader(s3Connection.getErrorStream())); 
     String ret; 
     StringBuffer buff = new StringBuffer(); 
     while ((ret = err.readLine()) != null) { 
      buff.append(ret); 
     } 
     uploadResponse.setMessage(buff.toString()); 
     System.out.println(" error :"+ buff.toString()); 
     err.close(); 


    } else { 
     BufferedReader inp = new BufferedReader(
       new InputStreamReader(s3Connection.getInputStream())); 
     StringBuffer buff = new StringBuffer(); 
     String ret; 
     while ((ret = inp.readLine()) != null) { 
      buff.append(ret); 
     } 
     inp.close(); 
     uploadResponse.setMessage(buff.toString()); 
     if(buff.toString().contains("fail")) 
      throw new Exception("Upload failed"); 
    }   

    System.out.println(response.toString()); 

    return uploadResponse;   

} 

}

答えて

1

は、ここに私のソースです。 rawソケットにHTTPリクエストを書く以外の方法はありませんでした。 あなたはよりよい回避策を見つけましたか?

EDIT:私はちょうど:url.openConnection()から取得したHttpURLConnectionオブジェクトでobj.setFixedLengthStreamingMode(12345)を使用するだけです。ここで12345はPOSTリクエストボディの長さです。