Dr.*_*all 8 java httpclient apache-commons-httpclient apache-httpclient-4.x
有一个api我需要执行没有长度的八位字节流.它只是一个实时数据流.我遇到的问题是,当我提出请求时,它似乎试图在将信息读入输入流之前等待内容的结束,但是它没有看到内容的结束和具有NoHttpResponse异常的超时.以下是我的代码的简化版本:
private static HttpPost getPostRequest() {
// Build uri
URI uri = new URIBuilder()
.setScheme("https")
.setHost(entity.getStreamUrl())
.setPath("/")
.build();
// Create http http
HttpPost httpPost = new HttpPost(uri);
String nvpsStr = "";
Object myArray[] = nvps.toArray();
for(int i = 0; i < myArray.length; i ++) {
nvpsStr += myArray[i].toString();
if(i < myArray.length - 1) {
nvpsStr += "&";
}
}
// Build http payload
String request = nvpsStr + scv + streamRequest + "\n\n";
// Attach http data
httpPost.setEntity(new StringEntity(URLEncoder.encode(request,"UTF-8")));
return httpPost;
}
// Where client is simply
// private static final CloseableHttpClient client = HttpClients.createDefault();
private static runPostRequest (HttpPost request) {
CloseableHttpResponse response = client.execute(request);
try {
HttpEntity ent = response.getEntity();
InputStream is = ent.getContent();
DataInputStream dis = new DataInputStream(is);
// Only stream the first 200 bytes
for(int i = 0; i < 200; i++) {
System.out.println(( (char)dis.readByte()));
}
} finally {
response.close();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2
所以,如果你不熟悉线程/ runnables/Handlers并且不熟悉android AsyncTask,我会直接去HttpUrlConnection(用apacheHttpClient删除整个练习因为,基本上googl说HttpUrlConn会支持stream'd响应,它确实有效!)
它可能不像转储标题那样容易检测所有细节.但是,使用正常的流式响应对象,我认为它应该正常工作....请参阅编辑3以获取UrlConn代码示例
EndEdit2
从问题是什么'流'协议被使用(渐进式dwnld | http流)或者如何实际管理客户端上的流式响应不清楚.
建议从连接转储标头,以确切了解客户端和服务器同意的内容?
假设您关闭了UI线程(在asyncTask中或在Handler的回调部分中),因此您可能需要重构一点.
假设http流与apache客户端4.3.5+一起使用
如果响应的头部没有长度,那么你在Http 1.1上做了一个'chunked'响应,你必须读取一个缓冲区直到你得到一个'last-chunk'或者决定关闭流或者Connection :
服务器刚开始发送(流),客户端应该根据生成实体内容的详细apache说明,通过使用缓冲区来处理它从http响应中获得的'input-stream' .
如果30秒的套接字超时会抢占活动流,我不记得了吗?请记住,在apache中,构建器中存在用于套接字超时和READ超时的单独设置.不希望套接字关闭,并且不希望在服务器提供响应时等待可读流的可用字节超时.
无论如何,客户端处理程序只需要通过检查读入缓冲区的内容来了解流的结束方式......
如果适当的协议是"继续"和"分块",那么客户端上的响应处理程序应该在流处理程序循环中UNTIL它从http规范中看到LAST-CHUNK .
response.getEntity().getContent()
Run Code Online (Sandbox Code Playgroud)
应该为您提供处理响应流所需的参考,直到'last-chunk'...
我想你应该在这里阅读如何使用一个缓冲的实体,在这个实体中需要多个读取才能在响应中的'last-chunk'结束.HttpUrlConn可能更容易的另一个原因......
做一个处理缓冲读取的循环,直到由匹配'last-chunk'的字节表示的END.
然后根据消费实体和可重用连接的详细apache说明CLO流或CONN.
在apache HttpClient中编辑流响应的代码
在'处理程序的回调或asyncTask中
request.execute();
...
processStreamingEntity(response.getEntity());
response.close();
//implement your own wrapper as mentioned in apache docs
private void processStreamingEntity(HttpEntity entity) throws IOException {
InputStreamHttpEntityHC4 bufHttpEntity = new InputStreamHttpEntityHC4(entity);
while not bufHttpEntity.LAST_CHUNK {
handleResponse(bufHttpEntity.readLine())
}
Run Code Online (Sandbox Code Playgroud)
编辑3
httpUrlConnection版本,如果你去那样.(使用MessageHandler,但你可以使用这些字节,因为这是来自流式语音示例,文本中的单词将被发送回UI)
private void openHttpsConnection(String urlStr, Handler mhandler) throws IOException {
HttpsURLConnection httpConn = null;
String line = null;
try {
URL url = new URL(urlStr);
URLConnection urlConn = url.openConnection();
if (!(urlConn instanceof HttpsURLConnection)) {
throw new IOException ("URL is not an Https URL");
}
httpConn = (HttpsURLConnection)urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.setReadTimeout(50 * 1000);
BufferedReader is =
new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
while ((line = is.readLine( )) != null) {
Message msg = Message.obtain();
msg.what=1;
msg.obj=line;
mhandler.sendMessage(msg);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch( SocketTimeoutException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Message msg = Message.obtain();
msg.what=2;
BufferedInputStream in = new BufferedInputStream(httpConn.getErrorStream());
line =new String(readStream(in));
msg.obj=line;
mhandler.sendMessage(msg);
}
finally {httpConn.disconnect();}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22614 次 |
最近记录: |