HttpURLConnection 网络请求最佳实践

13 篇文章 0 订阅

概述

在Android开发中网络请求是最常用的操作之一, Android SDK中对HTTP(超文本传输协议)也提供了很好的支持,这里包括两种接口:

  • 标准Java接口(java.NET) —-HttpURLConnection,可以实现简单的基于URL请求、响应功能;
  • Apache接口(org.appache.http)—-HttpClient,使用起来更方面更强大。

但在android API23SDKGoogleHttpClient移除了。Google建议使用httpURLconnection进行网络访问操作。

常见请求

HttpURLconnection是基于http协议的,支持getpostputdelete等各种请求方式,最常用的就是getpost,下面针对这两种请求方式进行讲解。

  • get 请求
    get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给服务端
  • post 请求
    postget的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内

构建请求

可以采用如下方式构建请求,当然,这只是构建请求。并没有发起实质的请求呢。

URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro/index.jsp");   
  
URLConnection rulConnection = url.openConnection();  
        // 此处的urlConnection对象实际上是根据URL的   
          // 请求协议(此处是http)生成的URLConnection类   
          // 的子类HttpURLConnection,故此处最好将其转化   
          // 为HttpURLConnection类型的对象,以便用到   
          // HttpURLConnection更多的API.如下:   
   
HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;

参数设置

// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在   
 // http正文内,因此需要设为true, 默认情况下是false;   
 httpUrlConnection.setDoOutput(true);   
  
 // 设置是否从httpUrlConnection读入,默认情况下是true;   
 httpUrlConnection.setDoInput(true);   
  
 // Post 请求不能使用缓存   
 httpUrlConnection.setUseCaches(false);   
  
 // 设定传送的内容类型是可序列化的java对象   
 // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)   
 httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");   
  
 // 设定请求的方法为"POST",默认是GET   
 httpUrlConnection.setRequestMethod("POST");   
  
 // 设置好所有的参数后就可以连接了   
httpUrlConnection.connect();

设置好所有的参数后可以调用 httpUrlConnection.connect 方法进()行连接 ,也可以直接调用 getOutputStream()进行连接,这个方法中会自动调用 connect()方法进行连接。

 OutputStream outStrm = httpUrlConnection.getOutputStream();

进行连接。
**注意:**但实际上到这里,只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
###发起请求
上面我们说了,不管是 getOutputStream() ,还是 connect()方法,最后都没有真正的发起请求。getInputStream()才是实际发送请求的地方。但是这个方法有个问题,如果该服务不管用或服务拒绝,它就会抛出 FileNotFoundException的异常,这非常的不友好,且也不好定位错误。

1 // 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。   
  2  ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm);   
 3   
 4  // 向对象输出流写出数据,这些数据将存到内存缓冲区中   
  5  objOutputStrm.writeObject(new String("我是测试数据"));   
 6   
 7  // 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)   
  8  objOutputStm.flush();   
 9   
 10  // 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,   
 11  // 在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器   
 12  objOutputStm.close();   
 13   
 14  // 调用HttpURLConnection连接对象的getInputStream()函数,   
 15  // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。   
 16  InputStream inStrm = httpConn.getInputStream(); // <===注意,实际发送请求的代码段就在这里   
 17   
18  // 上边的httpConn.getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义,   
19  // 既使对象输出流没有调用close()方法,下边的操作也不会向对象输出流写入任何数据.   
20  // 因此,要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据、   

所以我们需要在 httpConn.getInputStream() 方法前面加一段代码,判断下网络连接是否通畅,是否有问题。当然我这个只是示例,仅仅简单的做了判断。你可以根据你的需求添加详细的业务逻辑。

            int responseCode = urlConnection.getResponseCode();
            if (responseCode != 200) {
                Logger.e("网络连接失败 responseCode:"+responseCode);
                return null;
            }
            httpConn.getInputStream()

###一次完整请求的最佳实践

    private static String doPost(String data) {
        try {
            HttpURLConnection urlConnection = (HttpURLConnection) (new URL("http://api.faceid.com/faceid/v1/sdk/authm")).openConnection();
            urlConnection.setConnectTimeout(5000);
            urlConnection.setReadTimeout(5000);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Content-type", "text/plain");
             urlConnection.setDoOutput(true); 
            BufferedOutputStream bos = new BufferedOutputStream(urlConnection.getOutputStream());
            bos.write(data.getBytes());
            bos.close();
            int responseCode = urlConnection.getResponseCode();
            if (responseCode != 200) {
                Logger.e("网络连接失败 responseCode:"+responseCode);
                return null;
            }
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();

            String tmp;
            while ((tmp = bufferedReader.readLine()) != null) {
                stringBuilder.append(tmp);
            }

            bufferedReader.close();
            urlConnection.disconnect();
            return stringBuilder.toString();
        } catch (IOException var6) {
            var6.printStackTrace();
            return null;
        }
    }

总结

  • 首先确实如 HttpURLConnection用法详解 文章中所说,各参数的设置顺序、时机挺重要的。
  • 记得在实际发起网络请求之前,判断网络状况。不然只会给你抛出一个异常,实在不是一个友好的请求方式。
  • http请求实际上由两部分组成,
    • 一个是http头,所有关于此次http请求的配置都在http头里面定义,也就是 connect() 方法调用之前的一些配置。 connect()函数会根据HttpURLConnection对象的配置值生成http头部
    • 一个是正文content,也就是请求体

###参考文档
这篇 HttpURLConnection用法详解 非常详细的介绍了应该怎样使用HttpURLConnection 发起一次网络请求 。还对后台如何开发http 请求做了比较深入的介绍。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值