Android 网络请求HttpURLConnection 和 HttpClient详解

Android一般通过http协议向服务端接口发送请求,常用有POST和GET传输方式。这种请求通常借助于HttpClient,HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。通过HttpClient可以不借助浏览器,从而简化了客户端与服务器端之间的交互。

HttpPost httpPost=new HttpPost(reqUrl);

HttpResponse httpResponse=new DefaultHttpClient().execute(httpPost);

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请求时的一些参数


如提请求的url地址Request URL,提交的方式Request Method,服务器端的IP地址及端口Remote Address,请求头Request Headers,请求负载(表单参数)Request Payload,进而我们就可以在代码里面进行设置,然后发送请求

	/**
	 * 解析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();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zz_cl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值