android 用okhttp访问服务器的数据为什么总连接不上
OkHttp是一个相对成熟的解决方案,据说Android44的源码中可以看到HttpURLConnection已经替换成OkHttp实现了。所以我们更有理由相信OkHttp的强大。
OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。
使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和javanetHttpURLConnection一样的API。如果你用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。
public String androidPost() { String rs = null; String path = "url/Android_JDBC_SH/AndroidLoginAction"; HttpPost hp = new HttpPost(path); //获取客户端,用来向服务器发出请求 DefaultHttpClient hc = new DefaultHttpClient(); try { //Default Constructor taking a name and a value BasicNameValuePair nm = new BasicNameValuePair("name", name); BasicNameValuePair pa = new BasicNameValuePair("password", password); List list = new ArrayList(); listadd(nm); listadd(pa); //构建向服务器发送的实体 HttpEntity entity = new UrlEncodedFormEntity(list); hpsetEntity(entity); //提交请求,获取服务器的响应 HttpResponse response = hcexecute(hp); if (responsegetStatusLine()getStatusCode() == 200) { //获取响应实体 entity = responsegetEntity(); rs = EntityUtilstoString(entity); } } catch (ClientProtocolException e) { eprintStackTrace(); } catch (IOException e) { eprintStackTrace(); } return rs; }
Response类:
public boolean isSuccessful()
// Returns true if the code is in [200300), which means the request was successfully received, understood, and accepted
responsebody()返回ResponseBody类可以方便的获取string
public final String string() throws IOException
// Returns the response as a string decoded with the charset of the Content-Type header
// If that header is either absent or lacks a charset, this will attempt to decode the response body as UTF-8
Throws:IOException当然也能获取到流的形式:
public final InputStream byteStream()
HTTP POST POST提交Json数据
public static final MediaType JSON = MediaTypeparse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String jsonstr) throws IOException {
RequestBody body = RequestBodycreate(JSON, jsonstr);
Request request = new RequestBuilder()
url(url)
post(body)
build();
Response response = clientnewCall(request)execute();
if (responseisSuccessful()) {
return responsebody()string();
} else {
return ""; //根据自己的需要做异常数据处理
}
}
使用Request的post()来提交请求体RequestBody
POST提交键值对很多时候我们会需要通过POST方式把键值对数据传送到服务器。
OkHttp提供了很方便的方式来做这件事情。
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody formBody = new FormEncodingBuilder()
add("platform", "android")
add("name", "robert")
add("info", "abcdefg")
build();
Request request = new RequestBuilder()
url(url)
post(body)
build();
Response response = clientnewCall(request)execute();
if (responseisSuccessful()) {
return responsebody()string();
} else {
return ""; //根据自己的需要做异常数据处理
}
}
HttpDns是通过网络请求的方式,获取即将发送的业务请求所需要的ip地址。
在使用HttpDns时,android发送网络请求时会请求本地dns或本地运营商 的dns服务获取目标ip,但是一旦你使用的这个默认的dns不靠谱,不受信任,则请求稳定性将会降低,甚至可能被劫持。
因此,如果能够使用自己信任的dns服务器做dns域名解析,将大大降低这种风险。
OkHttp3一大亮点在其强大的Interceptor机制。因此HttpDns在整个request发射过程中就有了两个结合点:
使用Interceptor做ip直连,则会存在以下优点:
若使用OkHttp自带的dns(),优点在于:
综上来看,使用OkHttp原生Dns接口更加科学。除非不要求Cookie,不使用Https,使用Interceptor做简单的场景才比较合适。
OkHttp内使用 RouteDatabase 进行每次使用ip的监控和反馈:
为了能够复用 shouldPostpone() 获取okhttp自身对ip可用性的判断结果,使得自定义manager对ip的可用性的判断与okhttp一致,从而更新Manager自身的ip名单,可以通过
InternalinstancerouteDatabase(getConnectionPool()); 得到RouteDatabase对象。
Internalinstance 在OkHttpClient实例化之后就被赋值,事实上,Internalinstance就是OkHttpClient。因此可以使用NetworkInterceptor获取RouteDatabase。即:
Manager内维护两个名单Map,
interceptorsaddAll(clientinterceptors()) 是将addInterceptor时的所有Interceptor加入列表,然后再加入OkHttpCore核心处理Interceptor。
如果本次请求是一个需要走网络的请求,还会继续添加addNetInterceptor时所有的Interceptor加入列表。最后才加入CallServerInterceptor用来处理真正的网络请求。
这个顺序能够保证在递归调用过程中,自定义拦截器只会影响到OkHttpCore处理流程之前或者之后,而Core内的核心流程不会受到影响。
这里可以在客户端单独提供一个API进行描述,客户端可以直接引入,无需再定义。服务端也同样引入,直接实现即可。
OpenFeign底层也是通过http请求实现。
该接口其实就是为了描述http请求所需要的全部条件。如:服务名称(地址)、请求方式、请求方法、请求参数、返回类型等
在远程调用请求、响应数据较大的情况下可以配置使用GZIP压缩。(默认2048字符以上)
可以针对某些Feign接口指定日志跟踪。
修改配置关闭httpclient,开启okhttp
引入okhttp jar
OpenFeign可以看做是一个模板。比如下方示例。定义了请求方式,包括。服务名称(host)、请求路径、GET/POST、参数、结果,这些已经可以满足我们进行http请求调用。OpenFeign客户端便是通过这些,生成代理对象,从而在调用时向服务端发起请求。
代理对象中主要通过对注解进行解析,从Eureka中获取服务列表,再利用LoadBlance进行负载均衡,最后向服务端请求数据结果。
OpenFeign方便了跨服务之间的调用。如果没有OpenFeign我们要知道具体的地址才可以发起http请求获得返回结果。
底层使用Http通讯方式。RestTemplate是对Http协议的一种封装。
不引入服务端jar包自己写接口也完全可以。
只要定义好FeignClient模板,交给Feingn去扫描加载,都可以请求到服务端。服务端直接提供jar包的方式是一种接口的收敛,方便客户端调用,有变动仅需要修改服务端版本即可。比如,服务端A提供了接口IA,同时被服务B/C/D使用,如果不引入jar包由客户端B/C/D自行定义,容易出错,且服务A修改需要增加参数时,B/C/D必需要修改。
思考,如果服务A 10版本接口 IA 只有一个参数 id,B服务引入了该版本服务接口。 然后服务A 升级版本,11 ,接口IA 增加参数 name,此时,服务 B 继续使用10版本接口IA,请求时是否会出现问题?取决于什么?为什么?
0条评论