okhttp3基础使用全解析(配合servlet)

依赖

compile 'com.squareup.okhttp3:okhttp:3.10.0'

OkHttpClient
核心类, 内部封装请求响应业务逻辑,由于体积庞大所以只生成一个对象。
RequestBody
post请求所用到的类,用于打包上传的数据,为了简化操作又分为两个子类。
FormBody
RequestBody的子类之一,只能用于打包键值对,默认编码方式为URL的utf-8。
MultipartBody
RequestBody另一个子类,同时打包多个类型数据。
MediaType
解析上传,接收文件类型,最后将信息封装在请求头中。
Headers
封装头文件所有信息,本质是一个String数组。
Response
无论是get或者Post请求最后都会从服务器得到一个响应,而Respones就是包装了这个响应的内容。

创建一个OkHttpClient

使用默认配置参数

OkHttpClient client=new OkHttpClient();

自定义参数

OkHttpClient client=new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)       //设置连接超时
        .readTimeout(10, TimeUnit.SECONDS)          //设置读超时
        .writeTimeout(10,TimeUnit.SECONDS)          //设置写超时
        .retryOnConnectionFailure(true)             //是否自动重连
        .build();                                   //构建OkHttpClient对象

参数10指的是10秒,为默认值。

Headers详解

在HttpURLConnection中,头文件信息都是通过connection.addRequestProperty()方法添加的,整体代码耦合度较高,而okhttp完美解决这个问题,将头文件封装成一个对象最后统一处理,而这个对象就是Headers,headers的创建有两种方式;

方式一:建造者模式

Headers headers = new Headers.Builder().add("Height","5").add("Width","5").build();

这种方式方便在于直接通过add()方法以键值对形式保存头文件信息。

方式二:静态方法创建

Map<String, String> maps = new HashMap<>();
Headers headers = Headers.of(maps);

当我们拥有一个map集合时会通过这个方法创建。

两种方法的本质是相同的,看下Headers源码,

public final class Headers {
   
private final String[] namesAndValues;


 Headers(Builder builder) {
   this.namesAndValues = builder.namesAndValues.toArray(new                                     String[builder.namesAndValues.size()]);
	 }

   private Headers(String[] namesAndValues) {
    this.namesAndValues = namesAndValues;
  }	



  public static Headers of(Map<String, String> headers) {
   String[] namesAndValues = new String[headers.size() * 2];
		....
	 return new Headers(namesAndValues)
}



  public Headers build() {
      return new Headers(this);
    }

	
 }

最终都会将键值对转换成一个String数组

产生一个Request随即产生一个Headers对象,并且最终的Headers自带默认的几个头文件信息
笔者发起一个没有自定义Headers参数的get请求,这是servlet部分代码

Enumeration<String> enumeration = request.getHeaderNames();
	
		while(enumeration.hasMoreElements()){
			
			String key=enumeration.nextElement();
			
			System.out.print(key+":");
			
			Enumeration<String> values=request.getHeaders(key);
		
			while(values.hasMoreElements()){
			
				System.out.print(values.nextElement()+";");
			}	
		
			System.out.println();
		}

打印结果

host:***.***.***.***:8080;
connection:Keep-Alive;
accept-encoding:gzip;
user-agent:okhttp/3.10.0;

确实是这样,这些是信息是在 OkHttpClient里生成的,看下源码:

static {
    Internal.instance = new Internal() {
      @Override public void addLenient(Headers.Builder builder, String line) {
        builder.addLenient(line);
      }

      @Override public void addLenient(Headers.Builder builder, String name, String value) {
        builder.addLenient(name, value);
      }
}

OkHttpClient静态域提供这些方法,我们可以看到有个参数为Headers.Builder,所以猜想在最后数据包装时将产生新的一个Headers

而post请求由于需要提交上传数据类型,所以构建RequestBody时需要我们为其提供一个。

**注意:**okhttp的Headers的键值不能含有中文字符,否则报错。

Request##

request内部封装了请求头,请求行,实体内容

public final class Request {
  final HttpUrl url;
  final String method;
  final Headers headers;
  final @Nullable RequestBody body;
  final Object tag;

  private volatile CacheControl cacheControl; // Lazily initialized.

  Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tag = builder.tag != null ? builder.tag : this;
  }
}

可以看到Request不能直接从外部创建

Request的创建

Request request = new Request.Builder().url("http://192.168.23.1:8080/Get/aa?帅=5&Height=5").post(request).build();

这是一个post请求,它的创建方式与Headers大径相同都是使用建造者模式先构建一个Build对象用于接收各种参数,最后通过build()方法创建一个含有这些参数的Request对象。

发起一个get请求
因为是get请求所以不需要RequestBody。

同步线程阻塞

 OkHttpClient okHttpClient=new OkHtt
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值