Java 在android中从HttpURLConnection获取InputStream时获取未知长度HttpInputStream
HttpURLConnection.getInputStream()提供未知长度的httpInputStream,并且由于此文档解析引发SAX解析器异常 下面是代码Java 在android中从HttpURLConnection获取InputStream时获取未知长度HttpInputStream,java,android,web-services,inputstream,saxparser,Java,Android,Web Services,Inputstream,Saxparser,HttpURLConnection.getInputStream()提供未知长度的httpInputStream,并且由于此文档解析引发SAX解析器异常 下面是代码 try{ URL url = new URL(uri); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connectio
try{
URL url = new URL(uri);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
InputStream xml = connection.getInputStream();
System.out.println(connection.getResponseCode());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(connection.getInputStream());
doc.getDocumentElement().normalize();
}catch(Exception e){
e.printStackTrace();
}
任何人都知道UnknownLengthHttpInputStream的原因。我只在android中遇到这个错误,而这段代码在Java项目中工作得非常好
以下是LogCat的例外情况:
08-08 11:07:40.490: W/System.err(1493): org.xml.sax.SAXParseException: Unexpected end of document
08-08 11:07:40.504: W/System.err(1493): at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:129)
08-08 11:07:40.510: W/System.err(1493): at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
08-08 11:07:40.510: W/System.err(1493): at com.example.testws.MainActivity.onCreate(MainActivity.java:59)
08-08 11:07:40.520: W/System.err(1493): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-08 11:07:40.520: W/System.err(1493): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-08 11:07:40.520: W/System.err(1493): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-08 11:07:40.520: W/System.err(1493): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-08 11:07:40.530: W/System.err(1493): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
提前感谢。您需要在服务中正确关闭输出流以避免此异常。 如果您使用的是第三方库,请确保已设置响应标头
Content-Type
Content-Length
如果您使用的是java服务,则可以从方法中获取内容长度
File.length()
您是否尝试过使用apache库来实现此目的?我建议如下:
try {
HttpClient client = new DefaultHttpClient();
String getURL = "http://www.google.com";
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
//do something with the response
Log.i("GET RESPONSE",EntityUtils.toString(resEntityGet));
}
} catch (Exception e) {
e.printStackTrace();
}
然后获取HttpEntity
本身的流。
Smth类似:
InputStream st = entity.getContent();
这里有更多示例:要处理响应,请使用此方法,它将处理所有问题
public static ResponseHandler<String> getResponseHandlerInstance(final Handler handler) {
final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
public String handleResponse(final HttpResponse response) {
Message message = handler.obtainMessage();
Bundle bundle = new Bundle();
StatusLine status = response.getStatusLine();
Log.d(CLASSTAG, " " + HTTPRequestHelper.CLASSTAG + " statusCode - " + status.getStatusCode());
Log.d(CLASSTAG, " " + HTTPRequestHelper.CLASSTAG + " statusReasonPhrase - " + status.getReasonPhrase());
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
try {
result = HTTPRequestHelper.inputStreamToString(entity.getContent());
bundle.putString("RESPONSE", result);
message.setData(bundle);
handler.sendMessage(message);
} catch (IOException e) {
Log.e(CLASSTAG, " " + HTTPRequestHelper.CLASSTAG, e);
bundle.putString("RESPONSE", "Error - " + e.getMessage());
message.setData(bundle);
handler.sendMessage(message);
}
} else {
Log.w(CLASSTAG, " " + HTTPRequestHelper.CLASSTAG + " empty response entity, HTTP error occurred");
bundle.putString("RESPONSE", "Error - " + response.getStatusLine().getReasonPhrase());
message.setData(bundle);
handler.sendMessage(message);
}
return result;
}
};
return responseHandler;
}
private static String inputStreamToString(final InputStream stream) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
publicstaticresponsehandler getresponsehandler实例(最终处理程序){
最终响应handler ResponseHandler=新响应handler(){
公共字符串句柄响应(最终HttpResponse响应){
Message Message=handler.obtainMessage();
Bundle=新Bundle();
StatusLine status=response.getStatusLine();
Log.d(CLASSTAG,“+HTTPRequestHelper.CLASSTAG+”状态码-“+status.getStatusCode());
Log.d(CLASSTAG,“+HTTPRequestHelper.CLASSTAG+”statusReasonPhrase-“+status.getReasonPhrase());
HttpEntity=response.getEntity();
字符串结果=null;
如果(实体!=null){
试一试{
结果=HTTPRequestHelper.inputStreamToString(entity.getContent());
bundle.putString(“响应”,结果);
message.setData(bundle);
handler.sendMessage(message);
}捕获(IOE异常){
Log.e(CLASSTAG,“+HTTPRequestHelper.CLASSTAG,e);
bundle.putString(“响应”,“错误-”+e.getMessage());
message.setData(bundle);
handler.sendMessage(message);
}
}否则{
Log.w(CLASSTAG,“+HTTPRequestHelper.CLASSTAG+”空响应实体,发生HTTP错误);
bundle.putString(“RESPONSE”,“Error-”+RESPONSE.getStatusLine().getReasonPhrase());
message.setData(bundle);
handler.sendMessage(message);
}
返回结果;
}
};
返回应答器;
}
私有静态字符串inputStreamToString(最终InputStream流)引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(流));
StringBuilder sb=新的StringBuilder();
字符串行=null;
而((line=br.readLine())!=null){
sb.追加(第+行“\n”);
}
br.close();
使某人返回字符串();
}
当SAX解析器无法获取InputStream
数据的长度时,问题就出现了。要解决此问题,请将从xml
(InputStream
)读取的内容保存到字符串变量中,并从DocumentBuilder
的parse
方法的变量中生成InputStream
。要执行此操作,请按如下方式修改代码:
try {
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
InputStream xml = connection.getInputStream();
DataInputStream dis = new DataInputStream(xml);
StringBuilder sb = new StringBuilder();
int asci = dis.read();
while (asci > 0) {
sb.append((char) asci);
asci = dis.read();
}
String inputXML = sb.toString();
String predefinedXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <EmotionDB></EmotionDB>";
InputStream inputStream = new ByteArrayInputStream(inputXML.getBytes());//use predefinedXML.getBytes() instead of inputXML.getBytes() for sample test
System.out.println(connection.getResponseCode());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(inputStream);
doc.getDocumentElement().normalize();
} catch (Exception e) {
e.printStackTrace();
}
试试看{
URL=新的URL(uri);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod(“GET”);
setRequestProperty(“接受”、“应用程序/xml”);
InputStream xml=connection.getInputStream();
DataInputStream dis=新的DataInputStream(xml);
StringBuilder sb=新的StringBuilder();
int asci=dis.read();
而(asci>0){
sb.追加((char)asci);
asci=dis.read();
}
字符串inputXML=sb.toString();
字符串预定义XML=“”;
InputStream InputStream=new ByteArrayInputStream(inputXML.getBytes());//对于示例测试,请使用预定义的XML.getBytes()而不是inputXML.getBytes()
System.out.println(connection.getResponseCode());
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
文档doc=db.parse(inputStream);
doc.getDocumentElement().normalize();
}捕获(例外e){
e、 printStackTrace();
}
此处,inputStream
将具有正确的内容长度,因为它是由具有固定字节数的ByteArrayInputStream
构建的。一旦这样尝试
if(connection.getResponseCode() ==HttpURLConnection.HTTP_OK){
InputStream xml = connection.getInputStream();
..........
}else{
//problem in URI/connection .....
}
它可能是Http 1.0(旧服务器或配置错误)服务器,或者没有配置保持活动。在这种情况下,从服务器关闭连接时,流的长度是已知的。尝试指定http1.1并在请求头中保持活动状态(通过谷歌搜索会有所帮助)。只有在服务器响应中指定了content-length属性,您才能提前知道流的长度
解决方法:
将http流完全读入
字节缓冲流
(直到read()
返回-1
)。然后将ByteBufferInputStream抛出到您的库中(长度现在已知)从logcat附加异常?@Jens我从logcat附加了异常。.您得到了未知长度HttpInputStream
流,因为您的服务器没有提供内容长度或使用分块传输编码。当服务器不提供这两种服务时,它必须通过关闭连接来发出HTTP正文结束的信号——在本例中,它似乎是这样做的。你有没有可能嗅探网络服务器