URI
统一资源标识符
组成:scheme://host/path
1. 访问资源的命名机制
2. 存放资源的主机名称
3. 资源自身的名称,由路径表示
绝对URI: http://www.baidu.com
相对URI:books/ios.pdf
Uri类
- schema
- 主机名
- 路径
android Uri类
- schema:Contentprovider的schema由系统规定content://
- 主机名(Authority):用于标志ContentProvider,外部调用者可以根据这个标志找到对应的contentprovider
- 路径(Path):用于表示需要操作的数据,路径的构建根据业务决定:
相对uri
不包含命名规范信息。路径通常指同一台机器上的资源。可能含有相对标识符,或片段标识符
URL
统一资源定位
组成 协议://主机[:端口号][/path]
1. 协议
2. 主机:[端口号]
3. 资源具体地址
HTTP 基础
Http URL 、请求、响应、消息
HTTP URL
格式:http://host[:port][path]
host:合法的internet主机域名或IP地址
port:端口,为空默认80,非80端口访问需要显示指定
path:没有给出,当url作为uri使用需要加”/”,一般浏览器自动完成
HTTP 请求
组成
1. 请求行符号开头,后面跟URI、协议版本CRLF结尾,空格分隔。出结尾CRLF不允许单独出现CR或LF
格式:Method Request-URI HTTP-Version CRLF
例如:GET /index.html HTTP/1.1 (CRLF)
HTTP请求方法
GET方法
GET Request-URI HTTP/1.1
向服务器发送请求,获取资源
POST方法
向服务器发送请求获取资源,请求后附加数据
POST Request-URI HTTP/1.1(CRLF)
…
(CRLF)
…
HTML中get和post无大小写之分,HTTP协议中必须大写
HEAD方法
和GET方法相同,但之请求消息报头,不请求完整内容。响应消息和GET方法获取的是相同的
通常用于测试连接有效性
HTTP响应
组成
1. 状态行
2. 消息报头
3. 正文
状态行格式:HTTP-Version Status-Code Reason-Phrase(CRLF)
HTTP-Version:协议版本
状态码:三位数 第一个定义响应类别
状态描述:状态码描述
状态码分类
1xx:指示信息–请求接收,继续处理
2xx:成功–请求成功
3xx:重定向–要完成请求必须进一步操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务端错误–服务器未能实现合法请求
HTTP消息
HTTP消息由客户端到服务器的请求和服务器到客户端响应组成。
请求和响应消息组成:
- 开始行(请求消息-请求行,响应消息-状态行)
- 消息报头(可选)
- 空行(CRLF)
- 消息正文(可选)
Android Http 请求实现
HTTPURLConnection
POST
public static String requestPostURLConnection(String urlStr, Map<String, String> header, Map<String, String> params) {
HttpURLConnection connection = null;
InputStreamReader in = null;
URL url= null;
try {
//设置请求消息头
url = new URL(urlStr);
Log.d("http", "request:" + urlStr);
connection = (HttpURLConnection) url.openConnection();
//post请求,参数要放在http正文,需要设置为true
//默认情况false
connection.setDoOutput(true);
connection.setDoInput(true);
//post请求不能缓存
connection.setUseCaches(false);
//请求方法为POST默认为GET
connection.setRequestMethod("POST");
//默认编码
connection.setRequestProperty("Charset", "UTF-8");
connection.setConnectTimeout(10 * 1000);//连接超时 毫秒
connection.setReadTimeout(10 * 1000);//读取超时 毫秒
if (header != null && !header.isEmpty()) {
for (String key : header.keySet()) {
connection.addRequestProperty(key, header.get(key));
}
}
//开始连接
connection.connect();
//提交post参数
if (params != null && !params.isEmpty()) {
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
Iterator<String> it = params.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String nameValuePair = key + "=" + params.get(key);
dos.write(nameValuePair.getBytes());
}
dos.flush();
dos.close();
}
//读取响应消息
in = new InputStreamReader(connection.getInputStream());
BufferedReader reader = new BufferedReader(in);
StringBuffer result = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
Log.d("http", "result:" + result.toString());
return result.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "";
}
GET
public static String requestGetURLConnection(String urlStr, Map<String,String> header,Map<String, String> params) {
HttpURLConnection connection = null;
InputStreamReader in = null;
URL url = null;
try {
if (params != null) {
Iterator<String>it = params.keySet().iterator();
StringBuilder sb = null;
while (it.hasNext()) {
if (sb == null) {
sb = new StringBuilder();
sb.append("?");
}else {
sb.append("&");
}
String key = it.next();
sb.append(key).append("=").append(params.get(key));
}
urlStr += sb.toString();
}
url = new URL(urlStr);
Log.d("http", "request url:"+urlStr);
//设置请求消息头
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10 * 1000);
connection.setReadTimeout(10 * 1000);
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("Accept-Language", Locale.getDefault().toString());
connection.setRequestProperty("Charset", "UTF-8");
if (header != null && !header.isEmpty()) {
for (String key : header.keySet()) {
connection.setRequestProperty(key, header.get(key));
}
}
//参数设置完毕,开始连接
connection.connect();
//获取响应
in = new InputStreamReader(connection.getInputStream());
BufferedReader reader = new BufferedReader(in);
StringBuilder buffer = new StringBuilder();
String line ;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
Log.d("http", "result:" + buffer.toString());
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "";
}
HttpClient
post
static DefaultHttpClient client;
public static synchronized DefaultHttpClient getClient() {
if (client == null) {
HttpParams _connParam = new BasicHttpParams();
//设置连接管理器参数
//每台主机最多连接数
ConnManagerParams.setMaxConnectionsPerRoute(_connParam, new ConnPerRouteBean(5));
//连接池最大连接数
ConnManagerParams.setMaxTotalConnections(_connParam, 10);
//从连接池获取连接超时
ConnManagerParams.setTimeout(_connParam, 1000);
//设置协议参数
//设置http协议版本
HttpProtocolParams.setVersion(_connParam, HttpVersion.HTTP_1_1);
//设置编码格式
HttpProtocolParams.setContentCharset(_connParam, HTTP.UTF_8);
//设置浏览器
//HttpProtocolParams.setUserAgent(_connParam, "");
//连接服务器参数
HttpConnectionParams.setConnectionTimeout(_connParam, 10 * 1000);
HttpConnectionParams.setSoTimeout(_connParam, 10 * 1000);
HttpConnectionParams.setSocketBufferSize(_connParam, 1024 * 5);
//设置重定向
HttpClientParams.setRedirecting(_connParam, true);
//注册协议模式
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
//配置管理多线程安全
ClientConnectionManager manager = new ThreadSafeClientConnManager(_connParam, schemeRegistry);
client = new DefaultHttpClient(manager, _connParam);
}
return client;
}
public static String requestPostHttpClient(String url, Map<String, String> header, Map<String, String> params) {
HttpClient client = getClient();
HttpResponse resp = null;
try {
HttpPost request = new HttpPost(url);
Log.d("http", url + (params == null ? "" : ":" + params.toString()));
//设置消息头
if (header != null && !header.isEmpty()) {
for (String key : header.keySet()) {
request.setHeader(key, header.get(key));
}
}
//设置参数
if (params != null && !params.isEmpty()) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : params.keySet()) {
paramList.add(new BasicNameValuePair(key, params.get(key)));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "UTF-8");
request.setEntity(entity);
}
resp = client.execute(request);
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = resp.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
return result;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (resp != null) {
try {
resp.getEntity().consumeContent();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "";
}
参考资料
博客:
http://www.cnblogs.com/mengdd/archive/2013/05/26/3099776.html
http://www.open-open.com/lib/view/open1351324240738.html
HTTP状态码查询:
http://httpstatus.es/