【发布时间】:2016-03-17 08:00:06
【问题描述】:
我想实现一些代码,这些代码完全符合我在 Mac 终端中执行 CURL 命令时所完成的工作,即将 .wav 文件上传到服务器。 我之前已经为一台服务器完成了这项工作,所以我的一般想法有效(以及我的代码), ....但现在我想在不同的服务器上完成相同的操作。 这次我遇到了麻烦,我得到的只是“400:Bad Request”
这是我想在 Android 上执行的 CURL 命令,我添加了一个“-v”,因此您可以看到我的命令的详细信息。
curl -F file=@audio_life.wav 11.2.333.44:14141/transcribe -v
在终端输出日志:
* 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
这是我的代码,我总是得到 400:Bad Request 响应,如您所见,我试图复制标头。我究竟做错了什么?我怎样才能知道错误可能是什么?
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()));
这是我从服务器返回的消息的打印输出:
{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]}
注意:我根据自己的知识编写了这个代码,在检查了 StartOverflow 上的相关帖子之后,整个代码都在 AsyncTask 的 doInBackground 方法中,所以让我们关注这里。希望能帮到我!!谢谢。
【问题讨论】:
-
你能发布你的网址吗?是否有必要在请求属性中添加主机
-
您缺少
Content-Length标头,可能服务器正在等待它 -
@Madhu 嗨,如果我在这里发布 URL 可能会遇到麻烦,我会在没有 Host 标头的情况下重试,我不确定是否有必要。
-
dos.write(buffer, 0, bufferSize);。那应该是dos.write(buffer, 0, bytesRead); -
dos.write(buffer, 0, bytesAvailable);也一样。
标签: android post file-upload httpurlconnection bad-request