_052_Android_Android網路程式設計總結
1.httpURLConnection協議使用
1)建立一個URL物件
2)利用HttpURLConnection物件從網路中獲取網頁資料,設定請求方法
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");// 設定請求方法為post
3)設定連線超時
conn.setConnectTimeout(6*1000);
4)對響應碼進行判斷
if (conn.getResponseCode() != 200) //從Internet獲取網頁,傳送請求,將網頁以流的形式讀回來
throw new RuntimeException("請求url失敗");
5)處理輸入輸出流
InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK"); //檔案流輸入出文件用outStream.write
7)conn.disconnect();
public class NetUtils { public static String post(String url, String content) { HttpURLConnection conn = null; try { // 建立一個URL物件 URL mURL = new URL(url); // 呼叫URL的openConnection()方法,獲取HttpURLConnection物件 conn = (HttpURLConnection) mURL.openConnection(); conn.setRequestMethod("POST");// 設定請求方法為post conn.setReadTimeout(5000);// 設定讀取超時為5秒 conn.setConnectTimeout(10000);// 設定連線網路超時為10秒 conn.setDoOutput(true);// 設定此方法,允許向伺服器輸出內容 // post請求的引數 String data = content; // 獲得一個輸出流,向伺服器寫資料,預設情況下,系統不允許向伺服器輸出內容 OutputStream out = conn.getOutputStream();// 獲得一個輸出流,向伺服器寫資料 out.write(data.getBytes()); out.flush(); out.close(); int responseCode = conn.getResponseCode();// 呼叫此方法就不必再使用conn.connect()方法 if (responseCode == 200) { InputStream is = conn.getInputStream(); String response = getStringFromInputStream(is); return response; } else { throw new NetworkErrorException("response status is "+responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if (conn != null) { conn.disconnect();// 關閉連線 } } return null; } public static String get(String url) { HttpURLConnection conn = null; try { // 利用string url構建URL物件 URL mURL = new URL(url); conn = (HttpURLConnection) mURL.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); conn.setConnectTimeout(10000); int responseCode = conn.getResponseCode(); if (responseCode == 200) { InputStream is = conn.getInputStream(); String response = getStringFromInputStream(is); return response; } else { throw new NetworkErrorException("response status is "+responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if (conn != null) { conn.disconnect(); } } return null; } private static String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); // 模板程式碼 必須熟練 byte[] buffer = new byte[1024]; int len = -1; while ((len = is.read(buffer)) != -1) { os.write(buffer, 0, len); } is.close(); String state = os.toString();// 把流中的資料轉換成字串,採用的編碼是utf-8(模擬器預設編碼) os.close(); return state; } }
2.httpClient的使用
1. 建立HttpClient物件。
2. 建立請求方法的例項,並指定請求URL。如果需要傳送GET請求,建立HttpGet物件;如果需要傳送POST請求,建立HttpPost物件。
3. 如果需要傳送請求引數,可呼叫HttpGet、HttpPost共同的setParams(HetpParams params)方法來新增請求引數;對於HttpPost物件而言,也可呼叫setEntity(HttpEntity entity)方法來設定請求引數。
4. 呼叫HttpClient物件的execute(HttpUriRequest request)傳送請求,該方法返回一個HttpResponse。
5. 呼叫HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取伺服器的響應頭;呼叫HttpResponse的getEntity()方法可獲取HttpEntity物件,該物件包裝了伺服器的響應內容。程式可通過該物件獲取伺服器的響應內容。
6. 釋放連線。無論執行方法是否成功,都必須釋放連線
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
public class HttpClientTest {
@Test
public void jUnitTest() {
get();
}
/**
* HttpClient連線SSL
*/
public void ssl() {
CloseableHttpClient httpclient = null;
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File("d:\\tomcat.keystore"));
try {
// 載入keyStore d:\\tomcat.keystore
trustStore.load(instream, "123456".toCharArray());
} catch (CertificateException e) {
e.printStackTrace();
} finally {
try {
instream.close();
} catch (Exception ignore) {
}
}
// 相信自己的CA和所有自簽名的證書
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
// 只允許使用TLSv1協議
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
// 建立http請求(get方式)
HttpGet httpget = new HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action");
System.out.println("executing request" + httpget.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
System.out.println(EntityUtils.toString(entity));
EntityUtils.consume(entity);
}
} finally {
response.close();
}
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} finally {
if (httpclient != null) {
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* post方式提交表單(模擬使用者登入請求)
*/
public void postForm() {
// 建立預設的httpClient例項.
CloseableHttpClient httpclient = HttpClients.createDefault();
// 建立httppost
HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");
// 建立引數佇列
List<namevaluepair> formparams = new ArrayList<namevaluepair>();
formparams.add(new BasicNameValuePair("username", "admin"));
formparams.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity uefEntity;
try {
uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
httppost.setEntity(uefEntity);
System.out.println("executing request " + httppost.getURI());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println("--------------------------------------");
System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));
System.out.println("--------------------------------------");
}
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關閉連線,釋放資源
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 傳送 post請求訪問本地應用並根據傳遞引數不同返回不同結果
*/
public void post() {
// 建立預設的httpClient例項.
CloseableHttpClient httpclient = HttpClients.createDefault();
// 建立httppost
HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");
// 建立引數佇列
List<namevaluepair> formparams = new ArrayList<namevaluepair>();
formparams.add(new BasicNameValuePair("type", "house"));
UrlEncodedFormEntity uefEntity;
try {
uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
httppost.setEntity(uefEntity);
System.out.println("executing request " + httppost.getURI());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println("--------------------------------------");
System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));
System.out.println("--------------------------------------");
}
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關閉連線,釋放資源
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 傳送 get請求
*/
public void get() {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
// 建立httpget.
HttpGet httpget = new HttpGet("http://www.baidu.com/");
System.out.println("executing request " + httpget.getURI());
// 執行get請求.
CloseableHttpResponse response = httpclient.execute(httpget);
try {
// 獲取響應實體
HttpEntity entity = response.getEntity();
System.out.println("--------------------------------------");
// 列印響應狀態
System.out.println(response.getStatusLine());
if (entity != null) {
// 列印響應內容長度
System.out.println("Response content length: " + entity.getContentLength());
// 列印響應內容
System.out.println("Response content: " + EntityUtils.toString(entity));
}
System.out.println("------------------------------------");
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 關閉連線,釋放資源
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 上傳檔案
*/
public void upload() {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceFile.action");
FileBody bin = new FileBody(new File("F:\\image\\sendpix0.jpg"));
StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("bin", bin).addPart("comment", comment).build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.基於socket的網路連結操作
(1)服務端
- 用指定的埠例項化一個SeverSocket物件。伺服器就可以用這個埠監聽從客戶端發來的連線請求。
- 呼叫ServerSocket的accept()方法,以在等待連線期間造成阻塞,監聽連線從埠上發來的連線請求。
- 利用accept方法返回的客戶端的Socket物件,進行讀寫IO的操作
- 關閉開啟的流和Socket物件
/**
* 基於TCP協議的Socket通訊,實現使用者登入,服務端
*/
//1、建立一個伺服器端Socket,即ServerSocket,指定繫結的埠,並監聽此埠
ServerSocket serverSocket =newServerSocket(10086);//1024-65535的某個埠
//2、呼叫accept()方法開始監聽,等待客戶端的連線
Socket socket = serverSocket.accept();
//3、獲取輸入流,並讀取客戶端資訊
InputStream is = socket.getInputStream();
InputStreamReader isr =newInputStreamReader(is);
BufferedReader br =newBufferedReader(isr);
String info =null;
while((info=br.readLine())!=null){
System.out.println("Hello,我是伺服器,客戶端說:"+info);
}
socket.shutdownInput();//關閉輸入流
//4、獲取輸出流,響應客戶端的請求
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("Hello World!");
pw.flush();
//5、關閉資源
pw.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
serverSocket.close();
(2)客戶端
- 用伺服器的IP地址和埠號例項化Socket物件。
- 呼叫connect方法,連線到伺服器上。
- 獲得Socket上的流,把流封裝進BufferedReader/PrintWriter的例項,以進行讀寫
- 利用Socket提供的getInputStream和getOutputStream方法,通過IO流物件,向伺服器傳送資料流
//客戶端
//1、建立客戶端Socket,指定伺服器地址和埠
Socket socket =newSocket("127.0.0.1",10086);
//2、獲取輸出流,向伺服器端傳送資訊
OutputStream os = socket.getOutputStream();//位元組輸出流
PrintWriter pw =newPrintWriter(os);//將輸出流包裝成列印流
pw.write("使用者名稱:admin;密碼:admin");
pw.flush();
socket.shutdownOutput();
//3、獲取輸入流,並讀取伺服器端的響應資訊
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while((info=br.readLine())!null){
System.out.println("Hello,我是客戶端,伺服器說:"+info);
}
//4、關閉資源
br.close();
is.close();
pw.close();
os.close();
socket.close();
(3)多執行緒
- 伺服器端建立ServerSocket,迴圈呼叫accept()等待客戶端連線
- 客戶端建立一個socket並請求和伺服器端連線
- 伺服器端接受客戶端請求,建立socket與該客戶建立專線連線
- 建立連線的兩個socket在一個單獨的執行緒上對話
- 伺服器端繼續等待新的連線
//伺服器執行緒處理 和本執行緒相關的socket
Socket socket =null;
public serverThread(Socket socket){
this.socket = socket;
}
ServerSocket serverSocket =newServerSocket(10086);
Socket socket =null;
int count =0;//記錄客戶端的數量
while(true){
socket = serverScoket.accept();
ServerThread serverThread =newServerThread(socket);
serverThread.start();
count++;
System.out.println("客戶端連線的數量:"+count);
}