本篇介绍android中http通信技术,包括URLConnection与HttpClient的Get/Post方法,以及发送Json数据。
前戏操作:
1、在配置文件中添加访问网络的权限
<uses-permission android:name="android.permission.INTERNET"/>
2、android的网络请求必须通过异步请求的方式,否则会报错“android.os.NetworkOnMainThreadException”。因为系统认为这是一个耗时操作,放在主线程会导致界面卡顿。
URLConnection
我们使用URLConnection去请求豆瓣提供的访问api,获取北京热映电影列表:
https://api.douban.com/v2/movie/in_theaters?city=北京&start=0&count=10
Get方式请求:
@SuppressLint("StaticFieldLeak") AsyncTask<String, Integer, Void> asyncTask = new AsyncTask<String, Integer, Void>() {
@Override
protected Void doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
URLConnection connection = url.openConnection();//打开连接
//读取结果
InputStream is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
isr.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
asyncTask.execute("https://api.douban.com/v2/movie/in_theaters?city=%E5%8C%97%E4%BA%AC&start=0&total=1&count=10");
Post方式请求:
@SuppressLint("StaticFieldLeak") AsyncTask<String, Integer, Void> asyncTask2 = new AsyncTask<String, Integer, Void>() {
@Override
protected Void doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
//设置参数
OutputStream outputStream = connection.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(outputStream);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("city=%E5%8C%97%E4%BA%AC&start=30&count=10");
bw.flush();
//读取结果
InputStream is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
isr.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
asyncTask2.execute("https://api.douban.com/v2/movie/in_theaters");
HttpClient
HttpClient不是android原生的Http通信技术,由apache提供并集成到android中的,但是有些这样那样的原因,一直分分合合。如果想使用HttpClient,必须在app的build.gradle中添加引用:
android{
useLibrary 'org.apache.http.legacy'
}
HttpClient是个接口,需要实例化:
httpClient = new DefaultHttpClient();
使用的时候,发现DefaultHttpClient过时了,替代方法是 HttpClientBuilder 或CloseableHttpClient。如果使用这俩货,还得额外引用jar包。所以拉倒。
Get方式请求:
@SuppressLint("StaticFieldLeak") AsyncTask<String, Integer, Void> asyncTask3 = new AsyncTask<String, Integer, Void>() {
@Override
protected Void doInBackground(String... strings) {
try {
String url = strings[0];
HttpGet get = new HttpGet(url);
get.setHeader("User-Agent","");//必须设置,模拟浏览器的请求
HttpResponse response = httpClient.execute(get);
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
String request = "https://api.douban.com/v2/movie/in_theaters?city=%E5%8C%97%E4%BA%AC&start=20&total=1&count=11";
asyncTask3.execute(request);
Post方式请求:
@SuppressLint("StaticFieldLeak") AsyncTask<String, Integer, Void> asyncTask4 = new AsyncTask<String, Integer, Void>() {
@Override
protected Void doInBackground(String... strings) {
try {
String url = strings[0];
HttpPost post = new HttpPost(url);
// StringEntity entity = new StringEntity(strings[1]);
// post.setEntity(entity);//这样设置条件无效
List<BasicNameValuePair> list = new ArrayList<>();//使用键值对
list.add(new BasicNameValuePair("city", "%E5%8C%97%E4%BA%AC"));
list.add(new BasicNameValuePair("start", "28"));
list.add(new BasicNameValuePair("count", "9"));
post.setEntity(new UrlEncodedFormEntity(list));
post.setHeader("User-Agent", "");//不赋值也可以 ,但是必须有这个header
HttpResponse response = httpClient.execute(post);
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
asyncTask4.execute("https://api.douban.com/v2/movie/in_theaters", "city=%E5%8C%97%E4%BA%AC&start=28&count=10");
URLConnection提交Json数据到rest服务
我先用wcf搭建了一个rest风格的web服务,接收json数据:
http://192.168.0.102/wcfrest/Service1.svc/SaveStudent
提交json数据的格式为:{“Birthday”:“1987/10/12”,“Age”:25,“Name”:“八神”}
具体代码:注意该方法的调用必须放到异步中执行。
public static String doJsonPost(String urlPath, String Json) {
String result = "";
BufferedReader reader = null;
try {
URL url = new URL(urlPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求参数
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type","application/json; charset=UTF-8");// 设置文件类型:
// 设置接收类型否则返回415错误
conn.setRequestProperty("accept","application/json");
// 往服务器里面发送数据
if (Json != null && !TextUtils.isEmpty(Json)) {
byte[] writebytes = Json.getBytes();
// 设置文件长度
conn.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
OutputStream outwritestream = conn.getOutputStream();
outwritestream.write(Json.getBytes());
outwritestream.flush();//发送数据
outwritestream.close();
System.out.println("doJsonPost-ResponseCode:"+conn.getResponseCode());
}
if (conn.getResponseCode() == 200) {
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while((result = reader.readLine())!=null){
System.out.println(result);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(connection!=null){
connection.disconnect();
}
return result;
}