can’t create native thread
问题描述
OkHttpClient 每次使用都new创建,造成OOM,提示can’t create native thread…
问题分析
没有将OkHttpClient单例化.
每个client对象都有自己的线程池和连接池,如果为每个请求都创建一个client对象,自然会出现内存溢出。所以官方建议OkHttpClient应该单例化,重用连接和线程能降低延迟和减少内存消耗。
问题解决
使用官方推荐的方式,按需创建实例。
- new OkHttpClient()
该方式将创建一个使用默认设置的client单例对象。 - new OkHttpClient.Builder()
该方式允许自定义配置自己的单例client对象。配置connectionTimeout, readTimeout, writeTimeout等参数。okHttpClient = new OkHttpClient.Builder() .connectTimeout(50L, TimeUnit.SECONDS) .readTimeout(60L, TimeUnit.SECONDS) .build();
- okHttpclient.newBuilder()
该方式通过已经存在的client对象,创建特殊需要的client对象。如 我们通过上个方法创建了自定义配置的单例client对象,但是针对某些场景需要调整某些参数,那么就需要使用该方法创建定制的client。新client对象与旧client对象共享连接池,线程池和其他配置。OkHttpClient myClient = okHttpClient.newBuilder() .readTimeout(80L, TimeUnit.SECONDS).build();
get不支持请求体
问题描述
使用Retrofit发送get请求,自定义的service传递了实体bean对象,出现cras
@HTTP(method = "GET",path = "extend-web/intelligence-recipe/queryByModel",hasBody = true)
Call<CookResponse> postCookBook(@Body CookBookRequestBean cookBook);
问题分析
Retrofit自带的Okhttp内部报的错,主要原因是在HttpMethod#permitsRequestBody,判断get方法是否包含请求体,如果包含,就抛出异常;所以get请求发不出去。
Retrofit自带的okhttp不支持带body的get,想跳过那句请求体检查,可以通过修改源码方式解除判断;
Http协议只支持get请求path形式访问,不支持get请求带请求体的,所以即使你修改Okhttp源码,解除了get方法判断是否包含请求体,,也无法从应用层-…—网络层-链路层一层一层的将参数传递到server,更别说进入Tomcat,让Spring框架解析你的参数了;
一句话总结:Http协议规定get请求只能path形式进行查询;Retrofit+Okhttp遵循了Http协议规范,所以抛出异常,强制开发者使用Post协议发请求体。
问题解决
- get不传递请求体
- 修改body源码,在okhttp组装的时候用post格式组装,发出请