超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。
消息报头分为通用报头、请求报头、响应报头、实体报头等。消息头由键值对组成,每行一对,关键字和值用英文冒号“:”分隔。
HTTPS (Hyper Text Transfer Protocol over SecureSocket Layer)是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。
使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器。
HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 HTTP 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
相同网络环境下,HTTPS 协议会使页面的加载时间延长近 50%,增加 10%到 20%的耗电。此外,HTTPS 协议还会影响缓存,增加数据开销和功耗 [2] 。
HTTPS 协议的安全是有范围的,在黑客攻击、拒绝服务攻击和服务器劫持等方面几乎起不到什么作用 [2] 。
最关键的是,SSL 证书的信用链体系并不安全。特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行 [2] 。
成本增加。部署 HTTPS 后,因为 HTTPS 协议的工作要增加额外的计算资源消耗,例如 SSL 协议加密算法和 SSL 交互次数将占用一定的计算资源和服务器成本。在大规模用户访问应用的场景下,服务器需要频繁地做加密和解密操作,几乎每一个字节都需要做加解密,这就产生了服务器成本。随着云计算技术的发展,数据中心部署的服务器使用成本在规模增加后逐步下降,相对于用户访问的安全提升,其投入成本已经下降到可接受程度 [4] 。
1.使用setConnectTimeout()方法设置连接超时,当网络不好时,Android系统会在超过设置时间后收回资源,中断操作。
2.通过getResponseCode()对响应码进行判断,如果返回的响应码为200,则表示连接成功
3.在对大文件操作时,要将文件写到SDCard上,不要直接写到手机内存上
4.操作大文件时,要一边从网络上读取,一边往SDCard上写入,减少手机内存的使用
5.对文件流操作完毕后要及时关闭
.Android4.0后所有网络通信的操作都不能在主线程进行,需要使用独立的线程完成
HttpURLConnection访问HTTP资源的步骤:
① 根据URL地址创建URL对象
② 使用URL对象的openConnection()方法获取HttpURLConnection对象
③ 设置连接的属性,包括GET/POST请求方式
④ 输入、输出数据
⑤ 关闭输入、输出流
⑤ 在AndroidManifest配置文件中设置访问INTERNET的权限
HttpClient其实是一个interface类型,HttpClient封装了对象需要执行的Http请求、身份验证、连接管理和其它特性。从文档上看,HttpClient有三个已知的实现类分别是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能,但是既然开发的是Android应用程序,还是使用Android专有的实现类,一定有其优势。
Socket中文意思为插座的意思,专业术语称之为套接字,它把TCP/IP封装成了调用接口供开发者调用,也就是说开发者可以通过调用Socket相关API来实现网络通讯。在Java中也存在Socket相关API,主要分为两个,分别是基于UDP传输协议的Socket和基于TCP传输协议的Socket。
0kHttp的每次网络请求是一个Request,提供Request必要的参数url、header等,基于Request构造出一个Call对象,再调用它的execute()方法,就能取得Web Server回复的数据
如果同步调用,需要在独立的线程中执行,使用异步调用,则采用回调的方式执行,在内部封装了一个请求队列。
OkHttp依赖另一个组件okio完成高性能的I/O操作
基本用法:
private void get(String url) {
final Request request = new Request.Builder().url(url)
.header("user-agent","Mozilla/5.0(Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML,like Gecko) Chrome/51.0.2704.7 Safari/573.36")
.addHeader("Accept","application/json")
.build();
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(@NotNull Call call, @NotNull final IOException e) {
Log.e(TAG,e.getMessage());
runOnUiThread(new Runnable() {
@Override public void run() {
textView1.setText("获取失败,"+e.getMessage());
}
});
}
@Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()){
String json = response.body().string();
final Ip ip = JSON.parseObject(json,Ip.class);
runOnUiThread(new Runnable() {
@Override public void run() {
if (ip.getCode() != 0){
textView1.setText("未获得数据");
}else {
IpData data = ip.getData();
textView1.setText(data.getiP()+","+data.getArea());
}
}
});
}else {
Log.e(TAG,response.body().string());
}
}
});
}
private void post(String url, Map<String, String> params) {
RequestBody body = setRequestBody(params);
Request request = new Request.Builder().url(url).post(body)
.header("user-agent","Mozilla/5.0(Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML,like Gecko) Chrome/51.0.2704.7 Safari/573.36")
.addHeader("Accept","application/json")
.build();
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e("okActivity",e.getMessage());
}
@Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()){
String json = response.body().string();
final Ip ip = JSON.parseObject(json,Ip.class);
runOnUiThread(new Runnable() {
@Override public void run() {
if (ip.getCode() != 0){
textView1.setText("未获得数据");
}else {
IpData data = ip.getData();
textView1.setText(data.getiP()+","+data.getArea());
}
}
});
} else {
Log.e(TAG,response.body().string());
}
}
});
}
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null
当需要创建JSON字符串时,new一个JSONObject或者JSONArray对象,使用它们的put系列方法向其中追加数据,根据实际情况组合装配出JSONObject或JSONArray对象。
完成对象的装配工作之后,调用JSONObject或JSONArray的toString()方法即可生成JSON字符串
首先区分一下JSON字符串是单个对象还是数组,然后以
这个字符串作为参数,new一个JSONObject或者是JSONArray对象,Android内置的JSON解析组件就会解析JSON字符串,自动完成JSONObject或者是JSONArray对象的装配工作。
得到JSONObject或者是JSONArray对象引用之后,调用它的get系列方法,就能提取出JSON字符串中特定属性的值。