studio example ejemplo java android web-services inputstream saxparser

ejemplo - httpurlconnection java example



Obteniendo UnknownLengthHttpInputStream mientras obtengo InputStream de HttpURLConnection en Android (6)

HttpURLConnection.getInputStream () proporciona UnknownLengthHttpInputStream y, debido a este análisis de documentos, se produce una excepción del analizador SAX.

El siguiente es el código

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(); }

Cualquiera sabe el motivo de UnknownLengthHttpInputStream. Recibo este error solo en Android y este código funciona perfectamente en Java Project.

Lo siguiente es la excepción de 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)

Gracias por adelantado.


¿Has intentado usar las librerías de apache para esto? Sugeriría lo siguiente:

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(); }

y luego obtener la secuencia de la HttpEntity . Algo así como

InputStream st = entity.getContent();

Más ejemplos aquí: http://www.softwarepassion.com/android-series-get-post-and-multipart-post-requests/


Aquí el problema surge cuando el analizador SAX no pudo obtener la longitud de los datos de InputStream . Para solucionar este problema, guarde los contenidos leídos del xml ( InputStream ) en una variable de cadena y haga un InputStream de la variable para el método de parse de DocumentBuilder . Para ello modifica tu código de la siguiente manera:

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(); }

Aquí el inputStream tendrá una longitud de contenido correcta, ya que se construye a partir de un ByteArrayInputStream con un número fijo de bytes.


Deberá cerrar la secuencia de salida correctamente dentro del servicio para evitar esta excepción. Si está utilizando una biblioteca de terceros, asegúrese de haber configurado el encabezado de respuesta

Content-Type Content-Length

Si está utilizando un servicio java, puede obtener la longitud del contenido del método

File.length()


Es probable que se trate de un servidor Http 1.0 (servidor antiguo o configuración errónea) o que no se mantenga vivo configurado. En este caso, la longitud del flujo se conoce en el momento en que se cierra la conexión desde el servidor. Intente especificar http1.1 y keep-alive en el encabezado de su solicitud (algunas búsquedas en Google lo ayudarán). Solo si el atributo de longitud del contenido se especifica en la respuesta del servidor, sabrá de antemano la longitud del flujo.

Solución alternativa: lea la secuencia http en un ByteBufferStream completamente (hasta que read() devuelva -1 ). Luego, lance el ByteBufferInputStream a su biblioteca (la longitud se conoce ahora)


Para manejar la respuesta utiliza este método, ¡se encargará de todo!

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(); }


Una vez probarlo así

if(connection.getResponseCode() ==HttpURLConnection.HTTP_OK){ InputStream xml = connection.getInputStream(); .......... }else{ //problem in URI/connection ..... }