XML响应不标准

时间:2014-10-28 21:28:13

标签: android xml line response

我的WiFi三星空调没有以标准XML格式响应。 有没有办法可以忽略第一个回应?

如果我打开SSL连接,它会响应两行:

DRC-1.00 
<?xml version="1.0" encoding="utf-8" ?><Update Type="InvalidateAccount"/>

我必须回答:

<?xml version="1.0" encoding="utf-8" ?><Request Type="GetToken" />

Android中的堆栈跟踪是:

W/System.err﹕ java.net.ProtocolException: Unexpected status line: DRC-1.00

我的代码:

    URL url;
    URLConnection conn = null;

    try {
        //Create connection
        url = new URL(targetURL);

        // for not trusted ssl connections (https)
        FakeX509TrustManager.allowAllSSL();
        Log.v(TAG, "Set \"javax.net.debug\" to \"all\"");
        System.setProperty("javax.net.debug", "all");

        conn = url.openConnection();
        conn.setReadTimeout(5000 /* milliseconds */);
        conn.setConnectTimeout(5000 /* milliseconds */);
        conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);

        //Send request
        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));
        writer.flush();
        writer.close();
        os.close();

        Log.i(TAG, "Response " + conn.toString());

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        XMLReader xmlReader = parser.getXMLReader();
        xmlReader.parse(new InputSource(conn.getInputStream())); // Error here

        Log.v(TAG, xmlReader.toString());



    } catch (IOException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    }
}

2 个答案:

答案 0 :(得分:1)

问题不在于XML。问题是三星服务器没有说真正的HTTP。

(旧)HTTP RFC定义了响应的样子:

6.1 Status-Line

The first line of a Response message is the Status-Line, consisting
of the protocol version followed by a numeric status code and its
associated textual phrase, with each element separated by SP
characters. No CR or LF is allowed except in the final CRLF sequence.

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

"DRC-1.00"显然不是像"HTTP/1.1 200 OK"这样的状态行,导致一些严格的HTTP符合解析器失败。

您有两种方法可以解决此问题:

  • 直接使用Socket。这种受限用例的基本HTTP客户端实现起来并不复杂。你基本上只是写作&#34; GET path / from / url&#34;进入socket,然后阅读回复。 Simple java http client no server response包含一个很小的例子。要支持Https,AFAIK所需要做的就是使用SSLSocket代替。
  • 使用可配置为使用自定义协议的http库。 How to parse a none standard HTTP response?看起来很有希望。

答案 1 :(得分:1)

结束于:

try {
    // Taken from: http://blog.alcor.se/index.php/2013/08/09/using-java-to-connect-with-sslsocket-trusting-all-certificates/
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[]
                                               chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[]
                                               chain, String authType) throws CertificateException {
        }

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
    };

    // Install the all-trusting trust manager
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());

    SSLSocketFactory sslsocketfactory = sc.getSocketFactory();
    sslsocket = (SSLSocket) sslsocketfactory.createSocket(targetIp, port);
    sslsocket.setKeepAlive(true);
    // Sets this socket's read timeout in milliseconds.
    // sslsocket.setSoTimeout(timeoutSocket);

    Log.d(TAG, "Sending: " + xmlAction + xmlValue + XmlConstants.NEW_LINE);
    String line;
    ArrayList<String> receivedLines = new ArrayList<String>();

    DataOutputStream outToServerSSL = new DataOutputStream(sslsocket.getOutputStream());
    BufferedReader inFromServerSSL = new BufferedReader(new InputStreamReader(sslsocket.getInputStream()));
    outToServerSSL.writeBytes(xmlAction + xmlValue + XmlConstants.NEW_LINE + XmlConstants.NEW_LINE);

    while ((line = inFromServerSSL.readLine()) != null) {
        receivedLines.add(line);
        Log.d(TAG, "Received: " + line);
    }

    Log.d(TAG, "Closing tha sizzle");
    inFromServerSSL.close();
    outToServerSSL.close();

    return ParseXmlForStatusCode(receivedLines);

} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (UnknownHostException e) {
    e.printStackTrace();
} catch (KeyManagementException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (sslsocket != null) {
        try {
            sslsocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}