* 使用HttpUrlCollection进行Http通信,支持文件传输、post和get提交方式 * @param url 服务地址 * @param paras 参数列表 * @param files 文件列表 * @param authenticated * @param httpMethod 请求方式 * @return 返回InputStream输入流 * @throws IOException */ public InputStream httpRequest(String url, List<BasicNameValuePair> paras, ArrayList<File> files, boolean authenticated, String httpMethod) throws IOException { String end = "\r\n"; String twoHyphens = "--"; String boundary = "*****"; HttpURLConnection con = null; DataOutputStream ds = null; InputStream is = null; int responseCode = -1; String error = ""; try { if (httpMethod.equals("GET") && null != paras) { if (!url.contains("?")){ url += "?"; } for (BasicNameValuePair kv : paras) { url += ("&" + kv.key + "=" + kv.value); } } URL uri = new URL(url); con = (HttpURLConnection) uri.openConnection(); if (this.timeout > 0) { con.setConnectTimeout(this.timeout); } else { con.setConnectTimeout(30000); } // con.setReadTimeout(60000); /* 允许Input、Output,不使用Cache */ con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); /* setRequestProperty */ con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); if (httpMethod.equals("POST")) { /* 设定传送的method=POST */ con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); /* 设定DataOutputStream */ ds = new DataOutputStream(con.getOutputStream()); /* 添加键值 */ if (null != paras) { for (BasicNameValuePair kv : paras) { StringBuilder sb = new StringBuilder(); sb.append(end + twoHyphens + boundary + end); sb.append("Content-Disposition: form-data; " + "name=\"" + kv.key + "\"" + end + end); sb.append((null==kv.value)?"":kv.value); // sb.append(twoHyphens + boundary); byte[] bytes = sb.toString().getBytes("utf8"); ds.write(bytes); } ds.write((end + twoHyphens + boundary + end) .getBytes("utf8")); } /* 发送文件 */ if (null != files) { for (File file : files) { ds.writeBytes(twoHyphens + boundary + end); ds.writeBytes("Content-Disposition: form-data; " + "name=\"" + file.getName() + "\";filename=\"" + file.getName() + "\"" + end + end); FileInputStream fStream = new FileInputStream(file); String fileName = file.getName(); int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; int length = -1; long total = 0; long fileLength = file.length(); while ((length = fStream.read(buffer)) != -1) { ds.write(buffer, 0, length); total += length; } ds.write((end + twoHyphens + boundary + end) .getBytes("utf8")); fStream.close(); } /* 所有文件上传完成后加上这一行 */ ds.writeBytes(twoHyphens + boundary + twoHyphens + end); ds.flush(); } } else if (httpMethod.equals("GET")) { //设置为get请求 con.setRequestMethod("GET"); } responseCode = con.getResponseCode(); /* 取得Response内容 */ is = con.getInputStream(); } catch (MalformedURLException e) { responseCode = -2; error = e.getMessage(); e.printStackTrace(); } catch (IOException e) { responseCode = -3; error = e.getMessage(); e.printStackTrace(); } catch (Exception e) { responseCode = -4; error = e.getMessage(); e.printStackTrace(); } finally { if (null != ds) { ds.close(); ds = null; } } return is; }
通过上面的Http连接就可以进行客户端服务器数据之间的传输,当从服务器请求获取数据时,返回的InputStream流,如果采用xml封装数据,下面以Pull解析为例,将InputStream流解析成ContentValues对象:
/** * 读取关键词下的节点数据, 以键值对的形式返回 * @param is Xml数据流 * @param key节点名 * @return 键值对 */ public static ContentValues getAsContentValues(InputStream is, String key ){ try{ is.reset(); }catch(Exception e){ e.printStackTrace(); } ContentValues ret = null;; XmlPullParserFactory factory; try { factory = XmlPullParserFactory.newInstance(); //生成一个Pull解析器 XmlPullParser parser = factory.newPullParser(); parser.setInput(is, "utf-8"); // 解析器和xml节点值类解析xml ret = fromXmlContentValues(parser, key); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (null == ret){ ret = new ContentValues(); } return ret; } private static ContentValues fromXmlContentValues(XmlPullParser parser, String key) throws XmlPullParserException, IOException{ ContentValues ret = null; Boolean keyTag = false;//是否进入key节点 Boolean innerTag = false;//是否进入key的子节点 String subKey = ""; //当前key的子节点名称 int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { String keyName = parser.getName(); if (eventType == XmlPullParser.END_TAG){ if (keyName.contentEquals(key) && !innerTag){ parser.next(); break;//退出key节点 }else if (keyName.contentEquals(subKey)){ innerTag = false; } } if (eventType == XmlPullParser.START_TAG) { if (keyName.contentEquals(key) && !keyTag){ keyTag = true; }else if (keyTag){ //开始读取key的子节点数据 eventType = parser.next(); if (!innerTag){ if (eventType == XmlPullParser.TEXT || eventType == XmlPullParser.CDSECT ){ if (null == ret){ ret = new ContentValues(); } String value = parser.getText(); ret.put(keyName, value); } subKey = keyName; innerTag = true;//进入key的子节点 if (eventType == XmlPullParser.END_TAG){//刚进入就退出的子节点, 说明值为空 if (null == ret){ ret = new ContentValues(); } String value = ""; ret.put(keyName, value); innerTag = false;////退出key的子节点 } } } } eventType = parser.next(); } return ret; }
2、使用HttpClient通信(在2.2之后官方就不推荐使用这种方式了,使用HttpURLConnection)
HttpClient通信就更简单了,直接上代码
/** * 根据给定的url地址访问网络,得到响应内容(这里为GET方式访问) * * @param url * 指定天气url地址 * * @param params 请求参数 * @return 返回结果数据,返回失败时是null */ public String getWeatherFromServe(String url,List<String> parameters) { // 创建一个http请求对象 HttpGet request = new HttpGet(url); // 创建HttpParams以用来设置HTTP参数 HttpParams params = new BasicHttpParams(); //设置布尔参数, // params.setBooleanParameter("boolean", false); //序列化对象参数 // params.setParameter("string", "dsa"); // 设置连接超时或响应超时 HttpConnectionParams.setConnectionTimeout(params, 3000); HttpConnectionParams.setSoTimeout(params, 5000); // 创建一个网络访问处理对象 HttpClient httpClient = new DefaultHttpClient(params); try { // 执行请求参数项 HttpResponse response = httpClient.execute(request); // 判断是否请求成功 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); // 获得响应信息 String content = EntityUtils.toString(response.getEntity()); return content; } else { // 网连接失败,使用Toast显示提示信息 Toast.makeText(mContext, "网络访问失败,请检查手机网络状态!", Toast.LENGTH_LONG).show(); } } catch (Exception e) { e.printStackTrace(); } finally { // 释放网络连接资源 httpClient.getConnectionManager().shutdown(); } return null; }上面的例子中使用的是HttpGet请求方式,也可以使用HttpPost请求。服务器响应的HttpResponse对象获取一个HTTPEntity对象通过getEntity()方法,通过HttpEntity对象就可以获取服务器返回的众多信息。
3、Socket通信
Socket是建立在TCP/IP协议的基础上,就是对TCp/IP的一种封装,Socket提供接口我们使用。关于Socket的文章恐怕一篇两篇也讲不清楚,先放着了,有时间了另开文章详细讲解。