NutzCN Logo
精华 Nutz源码阅读之httpclient进阶
发布于 3170天前 作者 enilu 4250 次浏览 复制 上一个帖子 下一个帖子
标签: http 源码

上篇通过一个get请求大致弄明白了HttpClient的请求过程,和请求中使用到关键的几个类,这次来说说其他种类的请求,以及超时,上传文件,cookie的用法和实现。

Post请求

首先看创建请求的一段代码:

 return request.isGet() || request.isDelete() ? new GetSender(request)
                                                : new PostSender(request);

从上面可以看出这个HttpClient工具中,针对get和delete请求都统一使用GetSender来处理,针对其他请求使用PostSendr来处理。
之前提到过: Sender类方法的主要功能是根据传入的参数构造Request请求,并且打开连接(OpenConnection),底层是调用Url的openConnection;最终返回数据Response
那么基本上GetSender就是这些功能,PostSender也一样,只不过,PostSender针对参数为输入流的情况做了判断处理:

if (null != ins) {
                OutputStream ops = Streams.buff(conn.getOutputStream());
                Streams.write(ops, ins);
                Streams.safeClose(ins);
                Streams.safeFlush(ops);
                Streams.safeClose(ops);
            }

超时处理

  • 超时处理,在Sender类中体现,因为这个类负责openConnection嘛。
  • 超时处理有两种类型,连接超时(默认30秒)和读取数据超时(默认10分钟)
  • 实现中分别调用HttpUrlConnection的setConnectTimeout和setReadTimeout来设置超时时间。

上传文件

  • 针对文件上传类的请求,提供了FilePostSender类,该类集成自PostSender类。
  • 该类主要针对参数中的文件调用HttpURLConnection.getOutputStream()输出流,将文件输出到服务器端。
  • 伪代码如下:

     File f = getFileFromParams;
     final DataOutputStream outs = new DataOutputStream(conn.getOutputStream());
     outs.write(f); 
    

Cookie

  • Cookie的使用方法很简单,构造一个Cookie,然后Sender发送请求的时候将cookie作为参数发送即可:

    Cookie cookie = new Cookie();
    cookie.setDebug(true);
    Request req = Request.get("https://nutz.cn/user/login");
    Response resp = Sender.create(req).setInterceptor(cookie).send();
    
  • Cookie的实现主要有两块:

  • 一个是,在建立连接后将cookie发送到服务器端,

     afterConnect{
         String c = toString();//cokie内部实现使用map来存值,所以toString就是将这个键值对转换为字符串形式。
         conn.addReque=stProperty("Cookie", c);
     }
    
  • 一个是,在获取服务器响应的时候,将响应中的cookie信息保存下来。

    afterResponse{
          Map<String, List<String>> props = conn.getHeaderFields();
          for (Entry<String, List<String>> en : props.entrySet()) {            
              if (en.getKey() == null || !en.getKey().equalsIgnoreCase("Set-Cookie")) {
                  continue;
              }
              for (String e : en.getValue()) {
                  if (debug)
                      log.debugf("found Set-Cookie [%s]", e);
                  this.parse(e);//解析并保存cookie信息
              }
              break;
          }
    
    }
    
  • 上面代码中判断响应头信息是是否是cookie这里很有趣。按照我的理解,判断是否cookie的思路首先应该是:如果头信息中包含Set-Cookie的话,则解析这个cookie,但是作者确反过来判断了。
  • 我的想法是这样:

    if(en.getKey()!=null&&en.getKey().equalsIgnoreCase("Set-Cookie")) 
    //解析cookie
    
添加回复
请先登陆
回到顶部