/***********
****************************************************/
使用 HTTP 协议访问网络
在 Android 上发送 HTTP 请求的方式一般有两种, HttpURLConnection 和 HttpClient.
HttpURLConnection
首先需要获取到 HttpURLConnection 的实例,一般只需 new 出一个 URL 对象,并传入目标的网络地址,然后调用一下 openConnection()方法即可。
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
注意:如果URL传入的地址中含有中文,要对含有的中文进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文);
得到了 HttpURLConnection 的实例之后,我们可以设置一下 HTTP 请求所使用的方法。常用的方法主要有两个, GET 和 POST。
GET 表示希望从服务器那里获取数据
POST 则表示希望提交数据给服务器
connection.setRequestMethod("GET");
注意:其实GET方式也可以向服务器提交数据,如何通过GET方式提交数据,见最后GET方式提交数据
接下来就可以进行一些自由的定制了,比如设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等。这部分内容根据自己的实际情况进行编写
connection.setConnectTimeout(8000); //设置连接超时
connection.setReadTimeout(8000); //读取超时的毫秒数
获取连接状态码,如果状态码为200则表示连接成功
int status_code = connection.getResponseCode();
if(code == 200){
.........................................................................................
}
之后再调用 getInputStream()方法就可以获取到服务器返回的输入流了
InputStream in = connection.getInputStream();//获取到服务器返回的输入流了
剩下的任务就是对输入流进行读取,然后进行相关处理
public class StreamTool {
/**
* 把一个inputstream里面的内容转化成一个byte[]
*/
public static byte[] getBytes(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = is.read(buffer))!=-1){
bos.write(buffer, 0, len);
}
is.close();
bos.flush();
byte[] result = bos.toByteArray();
return result;
}
}
byte[] result = StreamTool.getBytes(in);
//如果读取的是图片数据
Bitmap bitmap = BitmapFactory.decodeByteArray(result,0,result.length);//也可以直接用Bitmap bitmap = BitmapFactory.decodeStream(in);
......
//如果读取的是网页数据,此处要注意网页的编码问题
String temp = new String(result);
if (temp.contains("gbk")) {
String temp = new String(result, "gb2312");
.......................
} else {
.......................
}
最后需要调用 disconnect()方法将这个 HTTP 连接关闭掉
connection.disconnect();
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
String response = (String) msg.obj;
// 在这里进行UI操作,将结果显示到界面上
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("http://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
// 下面对获取到的输入流进行读取
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
Message message = new Message();
message.what = SHOW_RESPONSE;
// 将服务器返回的结果存放到Message中
message.obj = response.toString();
handler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
提交数据给服务器
将 HTTP 请求的方法改成 POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&符号隔开,比如说我们想要向服务器提交用户名和密码,就可以这样写:
connection.setRequestMethod("POST");//设置为POST方式
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");//向服务器提交数据
int code = conn.getResponseCode();//获取服务器返回的状态码,以此来判断数据是否提交成功
if(code==200){
//数据提交成功,获取服务器返回的数据
InputStream in = conn.getInputStream();
byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(is)是自定义的流处理方法,见第一段实例代码
........................................................................
}
注意:如果传入的地址中含有中文,要对中文进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文参数);
同时如果要提交的数据中含有中文,要对提交的中文数据进行URL编码,否则传输数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(“张三”);
out.writeBytes("username=
param1+
"
&password=123456");//对于英文或者数字,进不进行URL编码应该没有什么影响
!!!!!!!HttpClient!!!!!!已经被废弃掉了
HttpClient
HttpClient 是一个接口,因此无法创建它的实例,通常情况下都会创建一个 DefaultHttpClient 的实例
HttpClient httpClient = new DefaultHttpClient();
接下来如果想要发起一条 GET 请求,就可以创建一个 HttpGet 对象,并传入目标的网络地址,然后调用 HttpClient 的 execute()方法即可:
HttpGet httpGet = new HttpGet("http://www.baidu.com");
HttpResponse httpResponse = httpClient.execute(httpGet);
注意:如果传入的地址参数中含有中文,要对中文参数进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文参数);
执行 execute()方法之后会返回一个 HttpResponse 对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 请求和响应都成功了
}
接下来在这个 if 判断的内部取出服务返回的具体内容,可以调用 getEntity()方法获取到一个 HttpEntity 实例,然后再用 EntityUtils.toString()这个静态方法将 HttpEntity 转换成字符串即可(也可以调用entity的getContent()实例方法,得到输入流),如下所示:
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity);
或者
HttpEntity entity = httpResponse.getEntity();
InputStream in = entity.getContent();
byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
注意如果服务器返回的数据是带有中文的,直接调用 EntityUtils.toString()方法进行转换会有乱码的情况出现,这个时候只需要在转换的时候将字符集指定成 utf-8 就可以了,如下所示:
String response = EntityUtils.toString(entity, "utf-8");
实例:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
String response = (String) msg.obj;
// 在这里进行UI操作,将结果显示到界面上
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://www.baidu.com");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 请求和响应都成功了
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity,"utf-8");
Message message = new Message();
message.what = SHOW_RESPONSE;
// 将服务器返回的结果存放到Message中
message.obj = response.toString();
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
提交数据给服务器
创建一个 DefaultHttpClient 的实例
HttpClient httpClient = new DefaultHttpClient();
创建一个 HttpPost 对象,并传入目标的网络地址,如下所示:
HttpPost httpPost = new HttpPost("http://www.baidu.com");
注意:如果传入的地址参数中含有中文,要对中文参数进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(中文参数);
然后通过一个 NameValuePair 集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity 中,然后调用 HttpPost 的 setEntity()方法将构建好的 UrlEncodedFormEntity传入,如下所示:
List params = new ArrayList();
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);
注意:
如果要
提交的数据中含有中文,要对提交的中文数据进行URL编码
,否则传输数据会出现中文乱码问题,解决方式如下:
String param1 = URLEncoder.encode(“张三”);
params.add(new BasicNameValuePair("username", param1));
接下来的操作就和 HttpGet 一样了,调用 HttpClient 的 execute()方法,并将 HttpPost 对象传入即可:
HttpResponse httpResponse = httpClient.execute(httpPost);
执行 execute()方法之后会返回一个 HttpResponse 对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 请求和响应都成功,接下来可以获取服务器的返回数据
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity);
或者
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");//这样可以防止乱码问题
或者
HttpEntity entity = httpResponse.getEntity();
InputStream in = entity.getContent();
byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
.........................................................................
}
/***********
****************************************************/
GET方式提交数据
HttpURLConnection的GET方式:
String path = "提交数据的服务器的地址";
String param1 = URLEncoder.encode(name); //对要传递的数据进行URL编码,防止出现乱码问题
String param2 = URLEncoder.encode(password); //对要传递的数据进行URL编码,防止出现乱码问题
URL url = new URL(path + "?name=" + param1 + "&password=" + param2);//如果path中含有中文参数的话,也要对path进行URL编码
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
// 只有调用getInputStream()方法的时候,数据才会被提交到服务器。
// 获取服务器返回的流信息
InputStream is = conn.getInputStream();
byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
.........................................................................
HttpClient的GET方式:
//1. 获取到一个浏览器的实例
HttpClient client = new DefaultHttpClient();
//2. 准备请求的地址
String param1 = URLEncoder.encode(name); //对要传递的数据进行URL编码,防止出现乱码问题
String param2 = URLEncoder.encode(password); //对要传递的数据进行URL编码,防止出现乱码问题
HttpGet httpGet = new HttpGet(path + "?name=" + param1 + "&password=" + param2); //如果path中含有中文参数的话,也要对path进行URL编码
//3. 敲回车 发请求
HttpResponse ressponse = client.execute(httpGet);
int code = ressponse.getStatusLine().getStatusCode();
if(code == 200){
InputStream is =ressponse.getEntity().getContent();
byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
.....................................................................
}
else{
.....................................................................
}
POST方式跟GET方式提交数据到服务器的区别:
get 一次提交的数据数据量比较小 4K 内部其实通过组拼url的方式
post 可以提交比较大的数据 form表单的形式 流的方式写到服务器
补充:
为了防止服务器端接收到的中文字符是乱码,在服务器端接收到的数据要注意编码问题。
String name = request.getParameter("name");
if(name!=null){
name = new String( name.getBytes("iso8859-1"),"utf-8");
}
服务器端对接收的字节流,按照
"iso8859-1"
进行编码生成字符串
,
所以对接收到的字符串,要按
"iso8859-1"
反编码成字节数组,再按UTF-8重新进行编码,生成中文字符。