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 responseHttpResponse 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() {@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;}};};
涉及到网络数据传输,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() {@Overridepublic 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();
转载于:https://www.cnblogs.com/zz-cl/p/6012473.html
Android 网络请求HttpURLConnection 和 HttpClient详解相关推荐
- android网络请求库volley方法详解
使用volley进行网络请求:需先将volley包导入androidstudio中 File下的Project Structrue,点加号导包 volley网络请求步骤: 1. 创建请求队列 ...
- 《Android 网络开发与应用实战详解》——2.3节Android系统架构
本节书摘来自异步社区<Android 网络开发与应用实战详解>一书中的第2章,第2.3节Android系统架构,作者 王东华,更多章节内容可以访问云栖社区"异步社区"公 ...
- 《Android 网络开发与应用实战详解》——1.3节搭建Android应用开发环境
本节书摘来自异步社区<Android 网络开发与应用实战详解>一书中的第1章,第1.3节搭建Android应用开发环境,作者 王东华,更多章节内容可以访问云栖社区"异步社区&qu ...
- 《Android 网络开发与应用实战详解》——2.1节简析Android安装文件
本节书摘来自异步社区<Android 网络开发与应用实战详解>一书中的第2章,第2.1节简析Android安装文件,作者 王东华,更多章节内容可以访问云栖社区"异步社区" ...
- 安卓项目实战之强大的网络请求框架okGo使用详解(一):实现get,post基本网络请求,下载上传进度监听以及对Callback自定义的深入理解
1.添加依赖 //必须使用 compile 'com.lzy.net:okgo:3.0.4'//以下三个选择添加,okrx和okrx2不能同时使用,一般选择添加最新的rx2支持即可 compile ' ...
- Flutter 网络请求框架dio使用详解
前言 dio是一款Flutter 网络请求框架,在GitHub上目前有超过5.9k个star.由国人(Flutter中文网)开发,所以中文文档非常完善. 这里copy了dio官方的文档,便于自己开发时 ...
- Python网络请求urllib和urllib3详解
1. 简介 urllib是Python中请求url连接的官方标准库,在Python2中主要为urllib和urllib2,在Python3中整合成了urllib. 而urllib3则是增加了连接池等功 ...
- Android 网络小说阅读APP实现详解
前言 本人是一个网络文学的骨灰级爱好者,日常看小说都是在各种手机浏览器中阅读,阅读体验不是很好.同时本人学习过Android的一些知识,故决定开发一款小说阅读app提高小说阅读的体验.本系列博客旨在梳 ...
- SpringBoot - 网络请求客户端WebClient使用详解
在 Spring 5 之前,如果我们想要调用其他系统提供的 HTTP 服务,通常可以使用 Spring 提供的 RestTemplate 来访问,不过由于 RestTemplate 是 Spring ...
最新文章
- 干货|100张PPT讲透工业机器人的机械结构
- maven项目没有错,但是在项目头上有红叉的解决方法
- 大头贴计算机教程,美颜相机大头贴在哪里 教你怎么弄动漫大头贴
- 裁员这件事,谁也没有鲍尔默、纳德拉这两届微软CEO演绎的淋漓尽致
- 结构体指针struct stu *p;和结构体变量struct stu p;结构体为什么要用指针引用而不用变量引用
- 【做题记录】[NOI2008] 假面舞会—有向图上的环与最长链
- java容器02--ArrayList源码分析
- iPhone 14系列或均搭载A16芯片:但Pro型号为A16 Pro
- linux 文件路径操作
- 自行实现PHP代码注解特性
- 操作系统实验报告 lab1
- 我是如何完美解决WIN10崩溃无法自动恢复启动问题的
- 本学期课程教学要解决问题要点备忘录
- PID到底是个啥?来给你讲个故事
- c语言快捷键的使用方法,电脑快捷键的使用方法
- layui标签输入框添加禁止点击标志
- 【微软 Azure 认知服务】零基础搭建微软 Azure AI 认知服务实验分享
- 分布式系统、集群的时间同步
- VAR.P和VAR.S
- Elasticsearch 异常处理