Android 网络请求HttpURLConnection 和 HttpClient详解
Android一般通過http協(xié)議向服務(wù)端接口發(fā)送請求,常用有POST和GET傳輸方式。這種請求通常借助于HttpClient,HttpClient 是 Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包。通過HttpClient可以不借助瀏覽器,從而簡化了客戶端與服務(wù)器端之間的交互。
HttpPost httpPost=new HttpPost(reqUrl);
HttpResponse?httpResponse=new DefaultHttpClient().execute(httpPost);
DefaultHttpClient是HttpClient接口的默認實現(xiàn),new DefaultHttpClient().execute(httpPost);則是使用一個匿名內(nèi)部類來處理請求。該匿名內(nèi)部類繼承自DefaultHttpClient,而DefaultHttpClient實現(xiàn)了HttpClient接口,所有可以重寫HttpClient接口下execute的方法來處理請求。
Android?Post請求的兩種方式
(1)、HttpPost
?
HttpPost httpRequest =new HttpPost(url);List <NameValuePair> params=new ArrayList<NameValuePair>();//Post方式用NameValuePair[]陣列儲存params.add(new BasicNameValuePair("name","name"));try{ //設(shè)置請求參數(shù)httpRequest.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));//創(chuàng)建HttpClient實例HttpClient client = new DefaultHttpClient();//請求超時client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 20000);//讀取超時client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 20000 );//取得HTTP responseHttpResponse httpResponse = client.execute(httpRequest);//若狀態(tài)碼為200 ok if(httpResponse.getStatusLine().getStatusCode()==200){//取出回應(yīng)字串String strResult=EntityUtils.toString(httpResponse.getEntity());}else{;}}catch(ClientProtocolException e){Toast.makeText(getApplicationContext(), e.getMessage().toString(),Toast.LENGTH_SHORT).show();e.printStackTrace();} catch (UnsupportedEncodingException e) {Toast.makeText(getApplicationContext(), e.getMessage().toString(),Toast.LENGTH_SHORT).show();e.printStackTrace();} catch (IOException e) {Toast.makeText(getApplicationContext(), e.getMessage().toString(),Toast.LENGTH_SHORT).show();e.printStackTrace();}(2)、HttpURLConnection?
try{
? ? ?//建立連接
? ? ?URL url=new URL(url);
? ? ?HttpURLConnection httpConn=(HttpURLConnection)url.openConnection();
? ? ?
? ? ?設(shè)置連接屬性
? ? ?httpConn.setDoOutput(true);//使用 URL 連接進行輸出
? ? ?httpConn.setDoInput(true);//使用 URL 連接進行輸入
? ? ?httpConn.setUseCaches(false);//忽略緩存
? ? ?httpConn.setRequestMethod("POST");//設(shè)置URL請求方法
? ? ?String requestString = "客服端要以以流方式發(fā)送到服務(wù)端的數(shù)據(jù)...";
? ? ?
? ? ?//設(shè)置請求屬性
? ? //獲得數(shù)據(jù)字節(jié)數(shù)據(jù),請求數(shù)據(jù)流的編碼,必須和下面服務(wù)器端處理請求流的編碼一致
? ? ? ? ? byte[] requestStringBytes = requestString.getBytes("utf-8");
? ? ? ? ? httpConn.setRequestProperty("Content-length", "" + requestStringBytes.length);
? ? ? ? ? httpConn.setRequestProperty("Content-Type", "application/octet-stream");
? ? ? ? ? httpConn.setRequestProperty("Connection", "Keep-Alive");// 維持長連接
? ? ? ? ? httpConn.setRequestProperty("Charset", "UTF-8");
? ? ? ? ? //
? ? ? ? ? String name=URLEncoder.encode("張三","utf-8");
? ? ? ? ? httpConn.setRequestProperty("name", name);
? ? ? ? ??
? ? ? ? ? //建立輸出流,并寫入數(shù)據(jù)
? ? ? ? ? OutputStream outputStream = httpConn.getOutputStream();
? ? ? ? ? outputStream.write(requestStringBytes);
? ? ? ? ? outputStream.close();
? ? ? ? ?//獲得響應(yīng)狀態(tài)
? ? ? ? ? int responseCode = httpConn.getResponseCode();
? ? ? ? ? if(HttpURLConnection.HTTP_OK == responseCode){//連接成功
? ? ? ? ? ?
? ? ? ? ? ?//當正確響應(yīng)時處理數(shù)據(jù)
? ? ? ? ? ?StringBuffer sb = new StringBuffer();
? ? ? ? ? ? ? String readLine;
? ? ? ? ? ? ? BufferedReader responseReader;
? ? ? ? ? ? ?//處理響應(yīng)流,必須與服務(wù)器響應(yīng)流輸出的編碼一致
? ? ? ? ? ? ? responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), ENCODING_UTF_8));
? ? ? ? ? ? ? while ((readLine = responseReader.readLine()) != null) {
? ? ? ? ? ? ? ?sb.append(readLine).append("\n");
? ? ? ? ? ? ? }
? ? ? ? ? ? ? responseReader.close();
? ? ? ? ? }
? ? }catch(Exception ex){
? ? ?ex.printStackTrace();
? ? }
HttpClient和HttpURLConnection是訪問HTTP的兩種方式,
HttpURLConnection是一個抽象類,繼承自URLConnection抽象類,基于標準Java接口(java.net),可以實現(xiàn)簡單的基于URL請求、響應(yīng)功能;HttpClient基于Apache接口(org.appache.http),使用起來更方面更強大。一般來說,使用這種接口比較多。運用這兩種方式,android可以訪問網(wǎng)頁、下載圖片或文件、上傳文件,甚至參數(shù)配置適當時,可以抓取服務(wù)器的很多數(shù)據(jù)。如用android做多圖上傳到服務(wù)器。
首先我們先解析目標url請求時的一些參數(shù)
如提請求的url地址Request URL,提交的方式Request Method,服務(wù)器端的IP地址及端口Remote Address,請求頭Request?Headers,請求負載(表單參數(shù))Request Payload,進而我們就可以在代碼里面進行設(shè)置,然后發(fā)送請求
?
/*** 解析multipart/form-data方式提交的請求,并以同樣的方式再提交*/@SuppressWarnings("unchecked")public static HttpURLConnection doPostMultipartFormData(java.net.URL url,MultipartHttpServletRequest request){//分割字符串String BOUNDARY = UUIDTool.getUUID().toUpperCase();String BOUNDARYSP = "--";String BOUNDARYSTR = BOUNDARYSP + BOUNDARY;String LINESP = "\r\n";HttpURLConnection conn = null;try{conn = (HttpURLConnection) url.openConnection();conn.setUseCaches(false);conn.setDoOutput(true);// 是否輸入?yún)?shù)conn.setConnectTimeout(3000);conn.setRequestMethod("POST");conn.setRequestProperty("Accept","text/html, application/xhtml+xml, */*");conn.setRequestProperty("Accept-Language", "zh-CN");conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");conn.setRequestProperty("Connection", "Keep-Alive");conn.setRequestProperty("Accept-Charset", "UTF-8");//conn.setRequestProperty("contentType", "UTF-8");conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY+"; charset=UTF-8");OutputStream out = new DataOutputStream(conn.getOutputStream()); //byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();// 定義最后數(shù)據(jù)分隔線 StringBuffer multiParamsData = new StringBuffer();//組裝普通參數(shù)Map params = request.getParameterMap();for(Object key : params.keySet()){Object paramvalue = params.get(key);if(paramvalue!=null){if(paramvalue instanceof String[]){for(String param : (String[])paramvalue){multiParamsData.append(BOUNDARYSTR);multiParamsData.append(LINESP);multiParamsData.append("Content-Disposition: form-data; name=\""+key+"\"");multiParamsData.append(LINESP);multiParamsData.append("Content-Type: text/plain; charset=UTF-8");multiParamsData.append(LINESP);multiParamsData.append(LINESP);multiParamsData.append(param);multiParamsData.append(LINESP);}}else{multiParamsData.append(BOUNDARYSTR);multiParamsData.append(LINESP);multiParamsData.append("Content-Disposition: form-data; name=\""+key+"\"");multiParamsData.append(LINESP);multiParamsData.append("Content-Type: text/plain; charset=UTF-8");multiParamsData.append(LINESP);multiParamsData.append(LINESP);multiParamsData.append(paramvalue);multiParamsData.append(LINESP);}}}//System.out.println(multiParamsData.toString());out.write(multiParamsData.toString().getBytes("UTF-8"));//組裝文件Map<String, MultipartFile> files = request.getFileMap();int i = 1;for(String key : files.keySet()){StringBuffer multiFilesData = new StringBuffer();MultipartFile multipartFile = files.get(key);multiFilesData.append(BOUNDARYSTR);multiFilesData.append(LINESP);multiFilesData.append("Content-Disposition: form-data; name=\""+key+"\"; filename=\""+multipartFile.getOriginalFilename()+"\"");multiFilesData.append(LINESP);multiFilesData.append("Content-Type:application/octet-stream");multiFilesData.append(LINESP);multiFilesData.append(LINESP);//multiData.append(paramvalue);out.write(multiFilesData.toString().getBytes("UTF-8"));DataInputStream in = new DataInputStream(multipartFile.getInputStream()); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } out.write(LINESP.getBytes("UTF-8"));in.close();// System.out.println(multiFilesData.toString()+"<file content; length:"+readStream(multipartFile.getInputStream()).length+">");}//System.out.println(BOUNDARYSTR+BOUNDARYSP);out.write((BOUNDARYSTR+BOUNDARYSP+LINESP).getBytes("UTF-8")); out.flush(); out.close(); //byte[] bypes = params.getBytes("UTF-8");//System.out.println("2>>>>>>"+new String(params,"UTF-8")); // conn.getOutputStream().write(params);}catch(ConnectException e){}catch(Exception e){logger.error("HttpRequest Error:",e);}return conn;}?
HttpPsot結(jié)合Handle
?
new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubMessage message=new Message();HttpPost httpPost=new HttpPost(reqUrl);try{httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));HttpResponse httpResponse;try{httpResponse=new DefaultHttpClient().execute(httpPost);if(httpResponse.getStatusLine().getStatusCode()==200){String result = EntityUtils.toString(httpResponse.getEntity());if(!result.isEmpty()){message.what=0;message.obj=result;myHandler.sendMessage(message);}else{message.what=1;myHandler.sendMessage(message);}}else{message.what=1;myHandler.sendMessage(message);}}catch(Exception e){e.printStackTrace();}}catch(Exception e){e.printStackTrace();}}}).start(); static Handler myHandler=new Handler(){@Overridepublic void handleMessage(android.os.Message msg) {if(msg.what==1){resultCallback.getReslt("1");}else if(msg.what==0){String result=(String) msg.obj;}};};涉及到網(wǎng)絡(luò)數(shù)據(jù)傳輸,AndroidManifest.xml中要設(shè)置相應(yīng)的權(quán)限。
?
?
<uses-permission android:name="android.permission.INTERNET" />同時可以對網(wǎng)絡(luò)狀態(tài)做一些相應(yīng)的處理。
?
?
/** * 檢測網(wǎng)絡(luò)是否連接* @return */ private boolean isNetConnected() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); if (cm != null) { NetworkInfo[] infos = cm.getAllNetworkInfo(); if (infos != null) { for (NetworkInfo ni : infos) { if (ni.isConnected()) { return true; } } } } return false; } /*** 設(shè)置網(wǎng)絡(luò)* @param context*/private void isNetworkAvailable(Context context) {new AlertDialog.Builder(LoginActivity.this).setTitle("網(wǎng)絡(luò)設(shè)置提示").setMessage("網(wǎng)絡(luò)不可用,是否現(xiàn)在設(shè)置網(wǎng)絡(luò)?").setPositiveButton("設(shè)置",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {if(android.os.Build.VERSION.SDK_INT > 10 ){//3.0以上打開設(shè)置界面,也可以直接用ACTION_WIRELESS_SETTINGS打開到wifi界面startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));} else {startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));}overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);}}).setNegativeButton("取消", null).show();轉(zhuǎn)載于:https://www.cnblogs.com/zz-cl/p/6012473.html
總結(jié)
以上是生活随笔為你收集整理的Android 网络请求HttpURLConnection 和 HttpClient详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Intellij IDEA -01 如何
- 下一篇: 有返回值的多线程demo