【问题标题】:parse server socket input stream to get json object解析服务器套接字输入流以获取 json 对象
【发布时间】:2016-07-02 05:59:09
【问题描述】:

我试图使用套接字从 api 获取响应

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  

得到的回应是:

HTTP/1.1 200 OKServer: nginx/1.8.1日期: Wed, 16 Mar 2016 10:58:33 GMTContent-Type:文本/html; charset=UTF-8 传输编码: chunkedConnection:keep-aliveSet-Cookie: ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22b98d2cae90806cadfc2c4e08235e85f6%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A15%3A%22202.12%66.91 3Bs%3A10%3A%22user_agent%22%3Bb%3A0%3Bs%3A13%3A%22last_activity%22%3Bi%3A1458125913%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B% 7D1df5f1fdd7228e520f7b0873b21273df; 过期=格林威治标准时间 2016 年 3 月 16 日星期三 12:58:33;最大年龄=7200;路径=/变化: Accept-Encoding389b{"update_date":"2015-04-02 05:31:26","status":"success","status_message":"new 数据","数据":[{"cat_id":"1","cat_name":"Art","update_date":"2015-04-02 05:30:44","subcat":[]},{"cat_id":"2","cat_name":"古董","update_date":"2015-04-02 05:30:54","subcat":[]},{"cat_id":"3","cat_name":"Automotive","update_date":"2015-03-19 21:11:14","subcat":[]},{"cat_id":"4","cat_name":"Baby","update_date":"2015-03-19 21:13:07","subcat":[]},{"cat_id":"5","cat_name":"Books","update_date":"2015-04-02 03:09:21","subcat":[]}}

现在如何仅从这个响应中获取 json??
除了从 { 到 } 获取字符串之外的任何标准方法......

在 (how to parse server socket input stream to get json object?) 中提出了类似的问题,但没有得到回答。

【问题讨论】:

    标签: android json sockets


    【解决方案1】:

    当您显然是在与 Web 服务器通信时,为什么要使用原始套接字而不是 HTTP 连接?

    让一些库为您解析 HTTP 响应并获取响应的 JSON 内容:

    Google Guava

    使用Resources.toString(URL, Charset):

    URL url = ...
    String json = Resources.toString(url, StandardCharsets.UTF_8);
    

    您将需要调整 URL,可能还需要调整字符集(如果您控制服务器,请使其为您提供 UTF-8,而不是让您的应用接受其他内容)。

    Volley

    String url = ...
    RequestQueue queue = Volley.newRequestQueue(this);
    StringRequest request = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
          @Override
          public void onResponse(String response) {
            // response is your JSON
          }
        }, new Response.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError error) {
            // stuff went wrong
          }
        });
    queue.add(stringRequest);
    

    使用普通的 Android SDK

    如果您真的想/必须避免使用库,请查看HttpURLConnection,这是推荐用于 Android 6.0 及更高版本的 HTTP 客户端:http://developer.android.com/reference/java/net/HttpURLConnection.html

    尽量避免这种情况,因为您更有可能从事构建应用的业务,而不是编写已经存在于其他地方的随机 IO 代码(并且可能具有更少的错误和更好的测试覆盖率)。

    【讨论】:

    • 感谢您的回复,但我正试图进入这个网络事物的核心......谁知道有一天我可能会建立比现在更好的库:)
    • 我为你学习的愿望鼓掌!如果您打算在 Play 商店上发布您的应用程序,我建议您使用其中一个库而不是自己滚动,因为您会犯错误,否则您的用户会遭受痛苦。学习方面,可以阅读 Guava、Volley、Apache HttpClient 和 HttpURLConnection 的代码(都是开源的),并尝试重新实现其中的一部分,以了解套接字、网络和 HTTP 的工作原理。
    【解决方案2】:
         String msg = "";
    
           BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            try {
                while ((line = rd.readLine()) != null) {
                    msg.append(line);                     // get the MSG as String
                }
            } catch (Exception e) {
                Toast.makeText(this, "Stream Exception", Toast.LENGTH_SHORT).show();
            }
    
    int index=line.indexOf('{');  // index from JSON response starts
    line=line.substring(index);
    JSONObject object=new JSONObject(line);
    
    // from here get your data.
    

    【讨论】:

    • 如果 JSON 响应是一个数组或只是一个基元,如果任何标头包含 {,如果响应没有以 Android 假定的任何默认字符集编码,则此方法不起作用。它也不会关闭套接字,从而泄露宝贵的原生资源。
    猜你喜欢
    • 2012-06-18
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    相关资源
    最近更新 更多