前面几讲的网络通信都是讲解的获取网络数据,这节开始我们来讲讲,发送数据。
其中发送数据分为GET和POST请求。
GET和POST的区别:
- GET使用URL或Cookie传参。而POST将数据放在BODY中。
- GET的URL会有长度(8Kb)上的限制,则POST的数据则可以非常大。
- POST比GET安全,因为数据在地址栏上不可见。
对于初学者,就这么认为就ok了,别看网上那些老学究,深究到底,大谈特谈,到最后不能自拔。等你干这一行久了,接触的多了,他们到里有哪些区别,不言自明。
5.1. 发送GET请求
发送get请求有好多方式,我们这里讲解Android自带的HttpURLConnection,以及HttpClient,还有开源的AsyncHttpClient发送get请求。
5.1.1. HttpURLConnection发送GET请求
- 拼接路径和参数,通过URL进行封装,打开一个HttpURLConnection,发送请求
- 如果参数是中文会出现乱码
- URL中包含的中文参数需要使用URLEncoder进行编码
- 服务器端如果是TOMCAT,其默认使用ISO8859-1编码,接收时需要处理编码问题
5.1.2. HttpClient发送GET请求
- 创建HttpClient对象
- 创建HttpGet对象,指定请求地址(带参数)
- 使用HttpClient的execute()方法执行HttpGet请求,得到HttpResponse对象
- 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码
- 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据
public String getByHttpClient(String username, String password) throws Exception {
username = URLEncoder.encode(username, "UTF-8");
password = URLEncoder.encode(password, "UTF-8");
String data = "username=" + username + "&password=" + password;
HttpClient httpClient = new DefaultHttpClient(); // 创建客户端
HttpGet httpGet = new HttpGet(path + "?" + data); // 创建GET请求
HttpResponse httpResponse = httpClient.execute(httpGet); // 发送请求
int code = httpResponse.getStatusLine().getStatusCode(); // 获取状态行, 获取响应码
if (code == 200) {
InputStream in = httpResponse.getEntity().getContent(); // 获取响应实体数据, 获取连接输入流
byte[] arr = Utils.load(in); // 读取出流中的数据
return new String(arr);
}
throw new NetworkErrorException("Code: " + code);
}
5.1.3. AsyncHttpClient发送GET请求
- AsyncHttpClient.get(), 使用RequestParams传递数据
public void login(View v) throws Exception {
String username = usernameET.getText().toString().trim();
String password = passwordET.getText().toString().trim();
String path = pathET.getText().toString().trim();
RequestParams params = new RequestParams();
params.put("username", username); // URLEncoder.encode()
params.put("password", password);
params.put("upload", new File(path)); // File类型会作为上传文件字段
client.get("http://192.168.1.251:8080/WebServer/LoginServlet", params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Toast.makeText(getApplicationContext(), "登录失败 " + statusCode, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
});
}
5.2. 发送POST请求
发送post请求有好多方式,我们这里讲解Android自带的HttpURLConnection,以及HttpClient,还有开源的AsyncHttpClient发送post请求。
5.2.1. HttpURLConnection发送POST请求
- 通过URL打开一个HttpURLConnection
- 头信息中除了超时时间和请求方式之外还必须设置Content-Type和Content-Length
- 从HttpURLConnection获得输出流输出参数数据
- 服务端可以使用request对象的setCharacterEncoding方法设置编码
5.2.2. HttpClient发送POST请求
- 创建HttpClient对象
- 创建HttpPost对象,指定请求地址
- 创建List< NameValuePair>,用来装载参数
- 调用HttpPost对象的setEntity()方法,装入一个UrlEncodedFormEntity对象,携带之前封装好的参数
- 使用HttpClient的execute()方法执行HttpPost请求,得到HttpResponse对象
- 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码
- 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据
public String postByHttpClient(String username, String password) throws Exception {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> params = new ArrayList<NameValuePair>(); // 创建用来装载名值对的集合
params.add(new BasicNameValuePair("username", username)); // 创建名值对
params.add(new BasicNameValuePair("password", password));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); // 给POST请求设置数据实体以及编码方式
HttpResponse httpResponse = httpClient.execute(httpPost);
int code = httpResponse.getStatusLine().getStatusCode();
if (code == 200) {
InputStream in = httpResponse.getEntity().getContent();
byte[] data = Utils.load(in);
return new String(data);
}
throw new NetworkErrorException("Code: " + code);
}
5.2.3. AsyncHttpClient发送POST请求
- AsyncHttpClient.post(), 使用RequestParams传递数据
public void login(View v) throws Exception {
String username = usernameET.getText().toString().trim();
String password = passwordET.getText().toString().trim();
String path = pathET.getText().toString().trim();
RequestParams params = new RequestParams();
params.put("username", username); // URLEncoder.encode()
params.put("password", password);
params.put("upload", new File(path)); // File类型会作为上传文件字段
client.post("http://192.168.1.251:8080/WebServer/LoginServlet", params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Toast.makeText(getApplicationContext(), "登录失败 " + statusCode, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
});
}
示例源码->百度网盘