1 使用HttpURLConnection方式把数据提交到服务器
基于什么协议?答:http协议
GET方式:组拼URL地址,把数据组拼到URL上,有大小限制:1KB(浏览器规定) 4KB(http协议规定)
POST方式:POST方式提交比较安全 提交的数据没有大小限制
GET方式提交数据代码如下:
new Thread(){
public void run() {
try {
//[2]获取用户名和密码
String name = et_username.getText().toString().trim();
String pwd = et_password.getText().toString().trim();
//[2.1]定义GET方式要提交的路径
String path = "http:192.168.1.102:8080/login/LoginServlet?username="+name+"&password"+pwd+"";
//[2.2]
//(1)创建URL对象
URL url = new URL(path);
//(2)获取httpurlconnection对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//(3)设置参数 发送get请求
conn.setRequestMethod("GET");
//(4)设置请求超时时间
conn.setReadTimeout(5000);
//(6)获取服务器返回的状态码
int code = conn.getResponseCode();
if(code == 200){
//(6)获取服务器返回的数据 以流的形式返回
InputStream in = conn.getInputStream();
//(6.1)把inputstream转换成string
String content = StreamTools.readStream(in);
//(7)把服务器展示到Toast上 不能在子线程展示Toast
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
【1】路径不同
【2】请求方式
【3】通过请求体的方式把数据写给服务器(以流的形式写给服务器)
POST方式提交数据代码如下:
new Thread(){
public void run() {
try {
//[2]获取用户名和密码
String name = et_username.getText().toString().trim();
String pwd = et_password.getText().toString().trim();
//[2.1]定义GET方式要提交的路径
String data = "username="+name+"&password"+pwd+"";
//一 ☆☆☆☆☆☆☆☆区别1 路径不同
String path = "http:192.168.1.102:8080/login/LoginServlet?";
//[2.2]
//(1)创建URL对象
URL url = new URL(path);
//(2)获取httpurlconnection对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//(3)设置参数 发送get请求
//二 ☆☆☆☆☆☆☆☆区别2 请求方式不同
conn.setRequestMethod("POST");
//(4)设置请求超时时间
conn.setReadTimeout(5000);
//三 ☆☆☆☆☆☆☆☆区别3 要多设置2个请求头信息
//设置头信息
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//参数通过抓包工具获取
conn.setRequestProperty("Content-Length", data.length()+"");
//四☆☆☆☆☆☆☆☆区别4 把我们组拼好的数据提交给服务器 以流的形式提交
conn.setDoOutput(true);//设置一个标记 允许输出
conn.getOutputStream().write(data.getBytes());
//(5)获取服务器返回的状态码
int code = conn.getResponseCode();
if(code == 200){
//(6)获取服务器返回的数据 以流的形式返回
InputStream in = conn.getInputStream();
//(6.1)把inputstream转换成string
String content = StreamTools.readStream(in);
//(7)把服务器展示到Toast上 不能在子线程展示Toast
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
【1】开源项目
【2】谷歌一般以base default simple进行命名
【3】对http请求的封装
GET方式:
new Thread(){
public void run() {
try {
//[2]获取用户名和密码
String name = et_username.getText().toString().trim();
String pwd = et_password.getText().toString().trim();
//[2.1]定义GET方式要提交的路径 小细节:如果提交中文要对name和pwd进行一个URLencode编码
String path = "http:192.168.1.102:8080/login/LoginServlet?username="+URLEncoder.encode(name, "utf-8")+"&password"+URLEncoder.encode(pwd, "utf-8")+"";
//[3]获取httpclient实例
DefaultHttpClient client = new DefaultHttpClient();
//[3.1]准备GET请求 定义一个httpget实现
HttpGet get = new HttpGet(path);
//[3.2]执行一个GET请求
HttpResponse response = client.execute(get);
//[4]获取服务器返回的状态码
int code = response.getStatusLine().getStatusCode();
if(code ==200){
//[5]获取服务器返回的数据 以流的形式返回
InputStream inputStream = response.getEntity().getContent();
//[6]把流转换成字符串
String content = StreamTools.readStream(inputStream);
//[7]展示结果
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
POST方式:
new Thread(){
public void run() {
try {
//[2]获取用户名和密码
String name = et_username.getText().toString().trim();
String pwd = et_password.getText().toString().trim();
String path = "http:192.168.1.102:8080/login/LoginServlet?";
//[3]以httpclient方式进行POST提交
DefaultHttpClient client = new DefaultHttpClient();
//[3.1]准备POST请求
HttpPost post = new HttpPost(path);
//[3.1.0]准备parameters
List lists = new ArrayList();
//[3.1.1]准备NameValuePair 实际上就是我们要提交的用户名和密码 key是服务器key:username
BasicNameValuePair nameValuePair = new BasicNameValuePair("username", name);
BasicNameValuePair pwdValuePair = new BasicNameValuePair("password", pwd);
//[3.1.2]把nameValuePair和pwdValuePair加入到集合中
lists.add(nameValuePair);
lists.add(pwdValuePair);
//[3.1.3]准备entity
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(lists);
//[3.2]准备POST方式提交的正文信息,以实体的形式准备(键值对形式)
post.setEntity(entity);
//[3.3]执行一个POST请求
HttpResponse response = client.execute(post);
//[4]获取服务器返回的状态码
int code = response.getStatusLine().getStatusCode();
if(code == 200){
//[5]获取服务器返回的数据,以流的形式返回
InputStream inputStream = response.getEntity().getContent();
//[6]把流转化为字符串
String content = StreamTools.readStream(inputStream);
//[7]展示出来
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
AsyncHttpClient
GET方式:
POST方式:
总结:
【1】HttpURLConnection:安卓下连网的基类,当需要向服务器发送数据的时候,用这个
【2】HttpClient:了解,不怎么使用
【3】开源项目(AsyncHttpClient):就只是往服务器中提交一些数据,用户名密码,参数,然后服务器返回一些数据,就可以直接用开源项目
4 javase多线程下载
设置请求服务器文件的位置
conn.setRequestProperty("Range","byte="+startIndex+"-"+endIndex);
提问:为什么多线程下载能够提高速度
多线程下载的步骤分析:
【1】获取服务器文件的大小
【2】在客户端创建一个大小和服务器一模一样的文件(这一步不是必须得),目的是提前申请好空间
【2.1】每个线程下载的开始位置和结束位置
【3】开多个线程去下载文件
【4】知道每个线程什么时候下载完毕
每个线程下载的开始位置和结束位置的计算公式:
5 开源项目实现多线程下载。(XUtils)
public void click(View v) {
//[1]获取下载路径
String path = et_path.getText().toString().trim();
//[2]创建HttpUtils对象
HttpUtils http = new HttpUtils();
//[3]实现断点逻辑
//target:下载文件的路径 autoResume:是否支持断点续传
http.download(path, "/mnt/sdcard/haha.exe", true, new RequestCallBack(){
//下载成功
@Override
public void onSuccess(ResponseInfo responseInfo) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "下载成功", Toast.LENGTH_LONG).show();
}
@Override
public void onLoading(long total, long current, boolean isUploading) {
//total:代表总进度 current:代表当前进度
pb.setMax((int) total);
pb.setProgress((int) current);
}
//下载失败
@Override
public void onFailure(HttpException error, String msg) {
}
});
}