Android通常经过http协议向服务端接口发送请求,经常使用有POST和GET传输方式。这种请求一般借助于HttpClient,HttpClient 是 Apache Jakarta Common 下的子项目,能够用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。经过HttpClient能够不借助浏览器,从而简化了客户端与服务器端之间的交互。
html
HttpPost httpPost=new HttpPost(reqUrl);
java
HttpResponse httpResponse=new DefaultHttpClient().execute(httpPost);
android
DefaultHttpClient是HttpClient接口的默认实现,new DefaultHttpClient().execute(httpPost);则是使用一个匿名内部类来处理请求。该匿名内部类继承自DefaultHttpClient,而DefaultHttpClient实现了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{ //设置请求参数 httpRequest.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8)); //建立HttpClient实例 HttpClient client = new DefaultHttpClient(); //请求超时 client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 20000); //读取超时 client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 20000 ); //取得HTTP response HttpResponse httpResponse = client.execute(httpRequest); //若状态码为200 ok if(httpResponse.getStatusLine().getStatusCode()==200){ //取出回应字串 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();
////设置链接属性
httpConn.setDoOutput(true);//使用 URL 链接进行输出
httpConn.setDoInput(true);//使用 URL 链接进行输入
httpConn.setUseCaches(false);//忽略缓存
httpConn.setRequestMethod("POST");//设置URL请求方法
String requestString = "客服端要以以流方式发送到服务端的数据...";
//设置请求属性
//得到数据字节数据,请求数据流的编码,必须和下面服务器端处理请求流的编码一致
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);
//创建输出流,并写入数据
OutputStream outputStream = httpConn.getOutputStream();
outputStream.write(requestStringBytes);
outputStream.close();
//得到响应状态
int responseCode = httpConn.getResponseCode();
if(HttpURLConnection.HTTP_OK == responseCode){//链接成功
//当正确响应时处理数据
StringBuffer sb = new StringBuffer();
String readLine;
BufferedReader responseReader;
//处理响应流,必须与服务器响应流输出的编码一致
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),能够实现简单的基于URL请求、响应功能;HttpClient基于Apache接口(org.appache.http),使用起来更方面更强大。通常来讲,使用这种接口比较多。运用这两种方式,android能够访问网页、下载图片或文件、上传文件,甚至参数配置适当时,能够抓取服务器的不少数据。如用android作多图上传到服务器。
网络
首先咱们先解析目标url请求时的一些参数app
如提请求的url地址Request URL,提交的方式Request Method,服务器端的IP地址及端口Remote Address,请求头Request Headers,请求负载(表单参数)Request Payload,进而咱们就能够在代码里面进行设置,而后发送请求ide
/** * 解析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);// 是否输入参数 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();// 定义最后数据分隔线 StringBuffer multiParamsData = new StringBuffer(); //组装普通参数 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结合Handle
new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Message 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(){ @Override public void handleMessage(android.os.Message msg) { if(msg.what==1){ resultCallback.getReslt("1"); }else if(msg.what==0){ String result=(String) msg.obj; } }; };
涉及到网络数据传输,AndroidManifest.xml中要设置相应的权限。
<uses-permission android:name="android.permission.INTERNET" />
同时能够对网络状态作一些相应的处理。
/** * 检测网络是否链接 * @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; } /** * 设置网络 * @param context */ private void isNetworkAvailable(Context context) { new AlertDialog.Builder(LoginActivity.this) .setTitle("网络设置提示") .setMessage("网络不可用,是否如今设置网络?") .setPositiveButton("设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if(android.os.Build.VERSION.SDK_INT > 10 ){ //3.0以上打开设置界面,也能够直接用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();