12 March 2016

上篇通过一个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,然后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
    




blog comments powered by Disqus
Fork me on GitHub