HttpClient学习(一)

来源:互联网 发布:lm555数据手册 编辑:程序博客网 时间:2024/05/16 14:50

序言、HttpUrlConnection和UrlConnection和DefaultHttpClient

1、HTTPUrlConnection通过setRequestMethod()的方法显示定义请求的方式;而UrlConnection使用setDoOutPut(true)显示定义为Post方法,否则默认是Get方式。

2、HttpUrlConnection使用可以通过setCache进行web缓存;而DefaultHttpClient则不能。

3、绝大多数的情况是:某些网页的访问,某些资源的访问需要用户的权限,而这些权限是需要涉及到Session和Cookie的处理,使用HttpUrlConnection类可以处理,但是较为繁琐,实现难度较大。此时,apache组织了一波开源,形成了HttpClient。

4、DefaultHttpClient继承AbstractHttpClient,AbstractHttpClient实现了HttpClient。

Apache的HttpClient框架学习

一、基础

1、报文头部的处理

1.2、报文头部信息的解析:

1.2.1、使用response.headIterator进行所有报文头部的解析;

1.2.2、对于单个的header首部的信息,使用HeaderElementIterator类进行解析。HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator("Set-Cookie"));

2、报文实体

HttpEntity类中封装了可以获取报文的一些元数据的方法,如:getContentType()等,而这些元数据大部分的情况下,都是放置在报文的header中的。

2.1、低级别资源的释放

当我们裂解到了需要的资源,并且已经获取到了需要的信息,那么经过此链接获取的剩下的信息就已经显得无足轻重了,并且http连接不会说自动关闭,这样就会很浪费资源(服务器,网络资源),我们可以使用HttpUriRequest#abort()进行连接的中断。

2.2、相应内容的读取

使用reponse.getEntity()获取内容实体,InputStream content = entity.getContent();进行资源的获取,得到一个InputStream的对象; OutputStream os = null;entity.writeTo(os);进行实体的写入。

实体的包装和缓存:使用entity = new BufferedHttpEntity(entity);将得到的实体内容进行包装缓存,以方便多次读取。

2.3、实体内容的封装

HttpClient提供了许多公用的数据容器,譬如:StringEntity,ByteArrayEntity等,这些封装类能够很好的帮助我们进行实体内容的封装。

使用ContentProduce和EntityTemplate类进行自定义使用内容的封装。

ContentProducer contentProducer = new ContentProducer() {            @Override            public void writeTo(OutputStream outputStream) throws IOException {                Writer writer = new OutputStreamWriter(outputStream, "UTF-8");                writer.write(...);//进行内容的书写            }        };EntityTemplate entityTemplate=new EntityTemplate(contentProducer);

使用这样的包装,我们基本上就能将我们需要的信息按照我们自己希望存储的形式包装起来(譬如:json,xml格式的数据),进而和客户端(希望获取这样形式数据的)进行数据通信。

2.4、HTML表单的提交

通常的表单提交,需要将参数进行URL编码进行提交,我们使用UrlEncodedFormEntity进行参数封装,该类会进行URL编码。

2.5、相应控制器的使用

使用ResponseHandler,不需要担心该连接是否成功还是出现了异常,该处理器直接会将连接的response返回,直接进行操作。
HttpGet httpGet = new HttpGet("www.baidu.com");
ResponseHandler<?> responseHandler=new ResponseHandler<Object>() {
@Override
public Object handleResponse(HttpResponse httpResponse) throws IOException {
return null;
}
};
try {
Object result = defaultHttpClient.execute(httpGet, responseHandler);
} catch (IOException e) {
e.printStackTrace();
}

3、异常的处理

3.1、http的安全运输机制

http协议只是面向请求/响应的,不涉及到事务操作层次,因为不会因为某次请求时报,不断的进行重新请求,这是不敢想象的:网络资源会因此很快的消耗。

3.2、幂等性的确定

本身并不能够提事务机制的http协议。在某些我们希望进行操作某些事务的操作上面,我们希望可以进行某些机制的建立。譬如:get请求失败后在某些时间段内进行有限次数的重新连接。但是这样的机制需要幂等性的支撑:重复n次的操作和1次成功的操作所获得的结果是一致的。

3.3、基于上述的机制的确定,需要进行的“请求重试处理”

需要进行HttpRequestRetryHandler接口的实现

3.4、Http的请求参数

HttpParams params = new BasicHttpParams();HttpProtocolParamBean paramsBean = new HttpProtocolParamBean(params);paramsBean.setVersion(HttpVersion.HTTP_1_1);

使用这样的方式,可以设置基础的Http的连接参数;

   httpProtocolParamBean.setContentCharset();   httpProtocolParamBean.setHttpElementCharset();   httpProtocolParamBean.setUseExpectContinue();   httpProtocolParamBean.setUserAgent();   httpProtocolParamBean.setVersion();

3.5、http参数的设置的影响

‘http.protocol.version’:http协议希望有一个版本,如果没有设置,就默认是:HTTP/1.1;

‘http.protocol.element-charset’:定义了http协议元素的编码的字符集,默认是US-ASCLL;
‘http.protocol.content-charset’:定义了为每个内容主体编码的默认字符集。这个参数期望得到一个java.lang.String类型的值。如果这个参数没有被设置,那么就使用ISO-8859-1;
‘http.useragent’:定义了头部信息User-Agent的内容。这个参数期望得到一个java.lang.String类型的值。如果这个参数没有被设置,那么HttpClient将会为它自动生成一个值。在android中,默认定义的agent是:Mozilla/5.0 (Linux; U; Android %s) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 %sSafari/533.1
‘http.protocol.expect-continue’:为包含方法的实体激活Expect: 100-Continue握手。Expect: 100-Continue握手的目的是允许客户端使用请求体发送一个请求信息来决定源服务器是否希望在客户端发送请求体之前得到这个请求(基于请求头部信息)。Expect: 100-Continue握手的使用可以对需要目标服务器认证的包含请求的实体(比如POST和PUT)导致明显的性能改善。Expect: 100-Continue握手应该谨慎使用,因为它和HTTP服务器,不支持HTTP/1.1协议的代理使用会引起问题。这个参数期望得到一个java.lang.Boolean类型的值。如果这个参数没有被设置,那么HttpClient将会试图使用握手;
‘http.protocol.strict-transfer-encoding’:定义了响应头部信息中是否含有一个非法的Transfer-Encoding,都要拒绝掉;
‘http.protocol.wait-for-continue’:定义了客户端应该等待100-Continue响应最大的毫秒级时间间隔。这个参数期望得到一个java.lang.Integer类型的值。如果这个参数没有被设置,那么HttpClient将会在恢复请求体传输之前为确认等待3秒。

3.6、以上的参数均要在http连接之前进行设置。

二、httpClient中连接的处理

1、影响http链接的参数

1.1、http.socket.timeout:套接字的连接超时时间。(0是无限大的超时时间)

1.2、http.tcp.nodelay:默认是TCP_NODELAY。如果设置成TCP_NAGLE算法,表示http希望通过分组发送来降低带宽,但是这样做会导致网络request/response时间变成(因为分组需要达到发送的要求才会被发送出去,每个分组需要等待发送的时间。)

1.3、http.socket.buf_size:内部套接字缓冲的大小,如果没有设置,默认是8192字节的套接字缓存。(1024*8)

1.4、’http.socket.linger’:使用指定的秒数拖延时间来设置SO_LINGER。最大的连接超时值是平台指定的。值0暗示了这个选项是关闭的。值-1暗示了使用了JRE默认的。这个设置仅仅影响套接字关闭操作。如果这个参数没有被设置,那么就假设值为-1(JRE默认)。

1.5、http.connection.timeout:直接连接建立的毫秒级时间,默认是0,表示永不超时,如果不进行设置,所有的连接将用不用超时。

1.6、http.connection.stalecheck:boolean类型,决定是否使用旧的连接,默认是true,表示在新的连接之前,进行旧的未处理的http连接检查,如果需要重连,那么先进行旧的连接的处理。

1.7、还有一些对连接时请求报文的数据进行限制的参数,这些参数可以不用设置,默认不会进行相关的限制。

2、持久性连接:如果每次请求重新建立http链路的连接,是相当耗时和耗费资源的

3、套接字工厂

3.1、普通的Http连接:使用PlainSocketFactory获取套接字工厂实现类;

3.2、加密的Https连接。

4、DefaultHttpclient构造函数中对connectionmanager和httpParams的处理

 public DefaultHttpClient() {        super((ClientConnectionManager)null, (HttpParams)null);        throw new RuntimeException("Stub!");    }

由此可见,apache的Default所构造的httpClient对http基础参数根本没有任何处理,超时时间,套接字工厂,重连机制等均需要自己在使用的过程中自己设置。

三、Http状态管理

原始的Http协议是面向无状态的,只是一些贯穿了“请求/响应”的会话。但是现在的一些会话中,我们希望能够保存一些用户的会话状态。

3.1、 Cookies

一个基础的Cookie包括了:(以BasicClientCookie2为例,这是最新的cookie标准)

1、构造函数:
public BasicClientCookie2(String name, String value) {
super((String)null, (String)null);
throw new RuntimeException(“Stub!”);
}

2、设置版本(version);
3、设置主机(Domain);
4、设置路径(path)
5、使用CookieStore将一些cookie对象进行存放。

3.2、如何从CookieStore中拿到CookieStore

BasicHttpClient是借口HttpClient的实现类,实例化的一个BasicHttpclient这个上下文中存放了http连接的相关信息。实际上BasicHttpContext就是一个ConcurrentHashMap。
这是一个独立用户(一个客户端)的处理过程:

HttpClient httpclient = new DefaultHttpClient();// 创建cookie store的本地实例CookieStore cookieStore = new BasicCookieStore();// 创建本地的HTTP内容HttpContext localContext = new BasicHttpContext();// 绑定定制的cookie store到本地内容中localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);HttpGet httpget = new HttpGet("http://www.google.com/");// 作为参数传递本地内容HttpResponse response = httpclient.execute(httpget, localContext)

这个localContext中会存储一些具备“特殊信息”的数据,这些数据在execute的过程中会发挥作用(特定的用户的cookie等~)。

CookieStore有自己的方法,通过

public interface CookieStore {    void addCookie(Cookie var1);    List getCookies();     boolean clearExpired(Date var1);    void clear();}

有以上几种几种方法对cookieStore中的cookie进行操作(增,删,获取)。

0 0