App研发录第二章

读书笔记–App研发录

Http和HttpUrlConnection的用法

标签(空格分隔): Android HttpUrlConnection 异步


网络请求过程

HTTP是一种应用层协议,他通过TCP实现了可靠的数据传输,能够保证数据的完整性,准确性,TCP的优点使得HTTP的数据传输吞吐量和效率得到保证。
移动开发多为C/S架构,客户端向服务端发送特定请求,服务器返回结构,客户端解析结果,再进行操作。
* 过程:

客户端执行网络请求,从URL中解析出服务器的主机名
主机名转换为IP地址
从URL中解析出端口号
建立客户端和服务器的TCP链接
客户端向服务器发送一条HTTP请求
服务器向客户端回执一条HTTP响应报文
客户端从输入流获取报文
客户端解析数据,关闭连接
客户端处理数据,并将结果显示在UI上


Request网络请求格式

  对于网络请求,我们一般只需要定义GET和POST即可,GET为向服务器请求数据,POST为修改数据。但是HTTP支持的请求方式有很多,被人们常用的请求有7种。GET和DELETE的URL最大长度为1KB。
  1,GET请求
  
  http://www.xxx.com/aaa.api?k1=va&k3=v2
  
  第一个参数之前有一个”?“,其后以”&“链接的键值对,是我们传输的参数。
  
  2, POST请求
  
  POST请求通常用来处理HTML的From表单,经常需要提交大量数据,所以我们的键值对要定义成集合或者复杂的自定义实体。这时可以将需要传输的值转换为JSON字符串进行提交,在底层MobileApi中完成JSON的实体化。
  
  3,PUT请求
  
  有些系统允许允许用户创建Web页面,PUT方法可以向服务器写入资源,如果已经存在请求主体的URL,用新的资源代替它。
  
  4,DELETE请求
  
  DELETE同样需要将参数放在URL中,不过HTTP规范允许服务器不通知客户端的情况下撤销请求,所以,无法保证指定的资源一定会被删除。
  
  5,HEAD请求
  
  HEAD和GET相似,但返回的数据不是数据的主体部分。使用HEAD请求可以在不获得资源的情况下获得资源的情况。通过查看响应中的状态码,可以判断对象是否存在。
  
  6,TRACE请求
  
  TRACE请求用于诊断,验证请求是否穿过了请求/响应链。客户端发起的请求可能要穿过代理,防火墙等,TRACE请求发送一个回环诊断,最后的服务器会返回原始的报文,让客户端判断请求是否能够正常到达服务器。
  
  7,OPTIONS请求
  
  询问服务器支持的方法,或者特殊资源支持的方法。
  

HTTP报文格式

  格式是一个复杂的东西,有兴趣可以自己查一些资料。

Response格式

  一般使用JSON作为MobileApi返回的结果
  规范格式1
  java
  {
   "isError" : true,
   "errorType" : 1,
   "errorMessage" : 网络异常,
   "result" : ""
  }
  

  格式2
  java
  {
   "isError" : false,
   "errorType" : 0,
   "errorMessage" : "",
   "result" : [
   {"id" : 1, "name" : "Brook"}
   {"id" : 2, "name" : "Pirate"}
   ]
  
  }
 

 
 根据前面所说的实体化编程的规范,我们应该为Response建立一个对应的实体便于使用和保存。很简单,不必细说。如果result返回的是集合,则需要解析为相应的实体集合。
 异常的类型的写法,因为网络原因标记为负数,正常标记为0,其他规定为正整数
 

底层获取过程

  在原书的Demo中,2.12节,AsyncTask的使用和缺点,其中HttpClient相关类已经不在支持,使用需要额外导入包useLibrary 'org.apache.http.legacy',sdk-23之后只支持HttpUrlConnection, 因为他的API简单,较小,而且存在压缩与缓存机制,很适合Android。
  在此使用HttpURLConnection代替HttpCilent,下面的代码可能有些不规范(缺少某些判断和异常处理,掌握基本用法即可。

  public class WeatherAsync extends AsyncTask <String, Integer, Response> {
    @Override
    protected Response doInBackground(String[] params) {
        return getResponseFromURL(params[0]);
    }

    private Response getResponseFromURL(String url) {
            return getResponseFromString(
                    convertStreamToString(
                            getInputStreamFromURL(url)));
    }

    private InputStream getInputStreamFromURL(String url) {
        InputStream is = null;
        try {
            URL newUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) newUrl.openConnection();
            // 读取超时10秒
            connection.setReadTimeout(10000);
            // 连接超时15秒
            connection.setConnectTimeout(15000);
            // 设置请求方式
            connection.setRequestMethod("POST");

            // 接受输入流
            connection.setDoInput(true);
            // 开启输出流, 需要传入参数,说明未开启
            connection.setDoOutput(true);
            // 添加请求Header
            connection.setRequestProperty("Connection", "Keep-Alive");

            // GET参数已经写在URL中,所以调用连接
            connection.connect();
            // 获取输入流
            is = connection.getInputStream();

        } catch (ProtocolException e1) {
            e1.printStackTrace();
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return is;
    }

    private Response getResponseFromString(String result) {
        Gson gson = new Gson();
        Response response = gson.fromJson(result, Response.class);
        return response;
    }

    private String convertStreamToString(InputStream is) {
        String line;
        try {
            InputStreamReader inStreamReader = new InputStreamReader(is, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inStreamReader);

            while ((line = bufferedReader.readLine()) != null) {
                return line;

            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;

    }
}

关于网络访问底层框架的设计,建议看一看Android开发进阶-从小工到专家的4.3章-网络框架的设计与实现,了解一下原理即可。
本着不重复造轮子(造出来也跑不快)的原则,就可以使用OkHttp,Volley等框架。

参考 http://blog.csdn.net/caomiao2006/article/details/52648990[Http详解][1]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值