2021SC@SDUSC Zxing开源代码(十一)URL请求处理


前言

在上次的博客中,我们分析了如果扫描图书的ISBN码后,所进行的处理操作。但是对于其中连接网络,打开网页URL的部分并没有展开分析。这部分功能主要是通过一个叫作 HttpHelper 的类来实现的,因此本次代码分析将以其为重点展开。


一、HttpURLConnection

在Android开发中网络请求是最常用的操作之一, Android SDK中对HTTP也提供了很好的支持,其中就包括标准Java接口(java.NET) —-HttpURLConnection,可以实现简单的基于URL请求、响应功能

HttpURLConnection的使用步骤:
在这里插入图片描述

对于HttpURLConnection的理解:

  • 任何网络连接都需要经过Socket才能连接,HttpURLConnection使用中并没有设置Socket,所以说HttpURLConnection并不是底层的连接,而是在底层连接上的一个请求
  • 虽然底层的网络连接可以被多个HttpURLConnection实例共享,但每一个HttpURLConnection实例只能发送一个请求。请求结束之后,应该调用HttpURLConnection实例的 InputStream 或 OutputStream的close() 方法以释放请求的网络资源。不过对于持久化连接,需要用 disconnect() 方法关闭底层连接的socket。
  • HttpURLConnection 只是一个抽象类,只能通过 url.openConection() 方法创建具体的实例。严格来说,openConection() 方法返回的是 URLConnection 的子类。根据 url 对象的不同,如可能不是 http:// 开头的,那么 openConection() 返回的可能就不是 HttpURLConnection

二、代码分析

在全局代码中,一共有多处使用到了 HttpHelper,这些调用类都涉及根据URL打开网页的操作,而其中调用了 HttpHelper 的方法 downloadViaHttp(String uri, ContentType type),来获取网页请求结果
在这里插入图片描述

downloadViaHttp

在 HttpHelper 中,downloadViaHttp 进行了方法重载,外部类调用的方法都是

  public static CharSequence downloadViaHttp(String uri, ContentType type) throws IOException {
    return downloadViaHttp(uri, type, Integer.MAX_VALUE);
  }

其中参数分别为:

参数含义
uri检索的URL地址
typeContentType类是HTTP支持的内容类型,有:HTML/JSON/XML/TEXT

重载的方法多了一个参数 int maxChars 来表示读取到的最大字符数,在该方法中,其根据 ContentType ,来将不同类型解析为了字符串格式,以便提交

  public static CharSequence downloadViaHttp(String uri, ContentType type, int maxChars) throws IOException {
    String contentTypes;
    switch (type) {
      case HTML:
        contentTypes = "application/xhtml+xml,text/html,text/*,*/*";
        break;
      case JSON:
        contentTypes = "application/json,text/*,*/*";
        break;
      case XML:
        contentTypes = "application/xml,text/*,*/*";
        break;
      default: // Includes TEXT
        contentTypes = "text/*,*/*";
    }
    return downloadViaHttp(uri, contentTypes, maxChars);
  }

而最后调用的 downloadViaHttp 方法,则真正的进行了网络请求

private static CharSequence downloadViaHttp(String uri, String contentTypes, int maxChars) throws IOException

其首先创建了URL对象,而后获取 HttpURLConnection 对象实例,这里的 safelyOpenConnection 继承了 HttpURLConnection,其主要是一些异常处理操作,来排除建立的对象非 HttpURLConnection 实例的情况(如果 url 不是 http:// 开头的,那么 openConection() 返回的可能就不是 HttpURLConnection)

      URL url = new URL(uri);
      HttpURLConnection connection = safelyOpenConnection(url);

创建对象后,需要设置 http 请求头;同时设置所有的 http 连接自动处理重定向

      connection.setInstanceFollowRedirects(true); 
      connection.setRequestProperty("Accept", contentTypes);
      connection.setRequestProperty("Accept-Charset", "utf-8,*");
      connection.setRequestProperty("User-Agent", "ZXing (Android)");

而后获取状态码

int responseCode = safelyConnect(connection);

根据状态码不同进行不同的操作:
在这里插入图片描述
对于 HttpURLConnection.HTTP_MOVED_TEMP 的情况:

          case HttpURLConnection.HTTP_MOVED_TEMP:
          // 在返回的Response的Location字段可以得到重定向地址的URL
            String location = connection.getHeaderField("Location");
            if (location != null) {
              uri = location;
              // 重定向计数
              redirects++;
              continue;
            }
            throw new IOException("No Location");

这里需要注意重定向的页面不能过多,在方法一开始也进行了限制

private static CharSequence downloadViaHttp(String uri, String contentTypes, int maxChars) throws IOException {
    int redirects = 0;
    while (redirects < 5) {
    ......
    }
    throw new IOException("Too many redirects");
}

对于 HttpURLConnection.HTTP_OK 的情况:
其调用了 consume 方法,来获得服务器返回的输入流,并将其作为结果返回

  private static CharSequence consume(URLConnection connection, int maxChars) throws IOException {
    // 获取服务器返回数据的编码格式
    String encoding = getEncoding(connection);
    StringBuilder out = new StringBuilder();
    // 读取返回的输入流
    try (Reader in = new InputStreamReader(connection.getInputStream(), encoding)) {
      char[] buffer = new char[1024];
      int charsRead;
      while (out.length() < maxChars && (charsRead = in.read(buffer)) > 0) {
        out.append(buffer, 0, charsRead);
      }
    }
    return out;
  }

总结

通过本次代码分析,了解了Zxing项目在处理URL请求时的操作,同时熟悉了Android开发中网络请求的流程。到这里,整个 Zxing 项目有关结果处理的重点部分就基本分析完了。接下来将会把重点放在在 Zxing 安卓端使用编码功能所进行的处理操作

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值