Android使用HttpURLConnect、HttpClient訪問WebService查詢手機號碼歸屬地
阿新 • • 發佈:2019-02-20
本內容適合初學Android網路程式設計、XML解析的童鞋檢視,主要內容已添加註釋,所以只貼程式碼即可。
效果圖:
①訪問網路、解析XML檔案工具類: WebServiceUtil.java
package com.lee.webservicedemo2.util; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.content.Context; import android.util.Log; /** * @author Administrator *網路上很多使用SOAP協議的方法,這裡就使用http */ public class WebServiceUtil { static String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo"; /** * 使用HttpURLConnection的get方式訪問網路,獲取手機號碼歸屬地資料流 * By Lee in 2014年9月3日 * */ public static String getAddressGet(Context context, String mobileNumber) throws IOException { //String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo"; path = path + "?mobileCode=" + URLEncoder.encode(mobileNumber, "utf-8") + "&userId="; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); Log.v("Lee", "GET conn = " + conn); if (conn.getResponseCode() == 200) { Log.v("Lee", "Connect Successed!"); return parserXML(conn.getInputStream()); } else { Log.v("Lee", "Connect failed! + error code: " + conn.getResponseCode()); } return null; } /** * 使用HttpURLConnection的Post方式訪問網路,獲取手機號碼歸屬地資料流 * By Lee in 2014年9月3日 * */ public static String getAddressPost(Context context, String mobileNumber) throws IOException { //String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo"; URL url = new URL(path); String content = "mobileCode=" + URLEncoder.encode(mobileNumber, "utf-8")+ "&userID="; Log.v("Lee", "POST content = " + content); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setUseCaches(false); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", content.getBytes().length + ""); conn.connect(); //one: // conn.getOutputStream().write(content.getBytes()); // conn.getOutputStream().flush(); // conn.getOutputStream().close(); //two: // DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); // dos.writeBytes(content); // dos.flush(); // dos.close(); //three: PrintWriter printer = new PrintWriter(conn.getOutputStream()); printer.print(content); printer.flush(); printer.close(); Log.v("Lee", "POST conn = " + conn); if (conn.getResponseCode() == 200) { Log.v("Lee", "Connect Successed!"); return parserXML(conn.getInputStream()); } else { Log.v("Lee", "Connect failed! + error code: " + conn.getResponseCode()); } return null; } /** * 使用apache HttpClient的get方式訪問網路,獲取手機號碼歸屬地資料流 * By Lee in 2014年9月3日 * * 存在問題:只能查詢一次,之後會出現java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)錯誤, * 網上找了,沒有找到解決方法,不知道是哪裡的問題 * */ public static String getAddressHttpClientGet(Context context, String mobileNumber) throws Exception{ HttpClient httpClient = new DefaultHttpClient(); path = path + "?mobileCode=" + URLEncoder.encode(mobileNumber, "utf-8") + "&userId="; HttpGet httpGet = new HttpGet(path); //httpGet.setHeader("Accept", "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); //httpGet.setHeader(name, value) //System.setProperty("http.keepAlive", "false"); HttpResponse httpResponse = httpClient.execute(httpGet); InputStream inputStream = httpResponse.getEntity().getContent(); //httpGet.abort(); if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ //Log.v("Lee", "HttpClientGet---inputStream = " + inputStream); String addr = parserXML(inputStream); inputStream.close(); httpGet.abort(); return addr; } return null; } /** * 使用apache HttpClient的Post方式訪問網路,獲取手機號碼歸屬地資料流 * By Lee in 2014年9月3日 * */ public static String getAddressHttpClientPost(Context context, String mobileNumber) throws Exception{ HttpClient httpClient = new DefaultHttpClient(); HttpPost httpRequest = new HttpPost(path); List<NameValuePair> vars = new ArrayList<NameValuePair>(); vars.add(new BasicNameValuePair("mobileCode", mobileNumber)); vars.add(new BasicNameValuePair("userId", "")); httpRequest.setEntity(new UrlEncodedFormEntity(vars, HTTP.UTF_8)); HttpResponse httpResponse = httpClient.execute(httpRequest); InputStream inputStream = httpResponse.getEntity().getContent(); //httpGet.abort(); if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ //Log.v("Lee", "HttpClientGet---inputStream = " + inputStream); String addr = parserXML(inputStream); inputStream.close(); httpRequest.abort(); return addr; } return null; } /** * @param inputStream 傳入的是XML檔案流物件 * @return */ public static String parserXML(InputStream inputStream) { SAXParserFactory saxFactory = SAXParserFactory.newInstance(); try { SAXParser parser = saxFactory.newSAXParser(); ParserXMLHandler handler = new ParserXMLHandler(); parser.parse(inputStream, handler); return handler.getAddress(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * XML檔案解析 * Android常用的xml解析方法有DOM、SAX、PULL,這裡其實使用PULL方法更簡易的, * 不過為了熟悉一下SAX的解析流程,本例使用了SAX * */ static class ParserXMLHandler extends DefaultHandler { private String address; private String preTag; //記住前一個節點 public String getAddress() { return address; } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub if (preTag != null) { String content = new String(ch, start, length); if ("string".equals(preTag)) { address = content; Log.v("Lee", "content == " + content); } } } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub preTag = null; } @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub preTag = localName; } } }
主介面程式碼MainActivity.java
package com.lee.webservicedemo2; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.TextView; import com.lee.webservicedemo2.util.WebServiceUtil; /** * 注意新增網路訪問許可權:<uses-permission android:name="android.permission.INTERNET"/> * 測試手機系統的環境:Android 4.3 * * */ public class MainActivity extends Activity { private TextView tv_addr; Handler handler = null; String addr = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_addr = ((TextView)findViewById(R.id.tv_location)); //使用Handler更新UI handler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub if(msg.what == 0x100){ tv_addr.setText(addr); } } }; findViewById(R.id.commit_btn).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub //主執行緒不可訪問網路 new Thread(new Runnable() { @Override public void run() { try { String mobileName = ((EditText) findViewById(R.id.mobilenumber_edit)) .getText().toString().trim(); //至少7位才能查詢 if(mobileName.length() < 7){ addr = null; handler.sendEmptyMessage(0x100); return; } //String temp = WebServiceUtil.getAddressGet(MainActivity.this, mobileName);//GET method String temp = WebServiceUtil.getAddressHttpClientPost(MainActivity.this, mobileName);//使用不同的網路訪問方式 if (temp != null && temp.length() > 0) { addr = temp.substring(temp.indexOf(":") + 1, temp.length()); //此處分隔符是中文:冒號 }else{ addr = null; } //使用Handler更新UI handler.sendEmptyMessage(0x100); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }); } }
佈局檔案activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="請輸入手機號碼:" /> <EditText android:id="@+id/mobilenumber_edit" android:layout_marginTop="4dip" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="至少7位號碼"/> <Button android:id="@+id/commit_btn" android:layout_marginTop="4dip" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查詢"/> <TextView android:id="@+id/tv_location" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>