使用HttpClient 发送get、post请求,及其解析xml返回数据
一、关于HttpClient的使用:
可以参考这个博客地址,这里有详细的介绍,需要的可以先看一下:
地址是:http://blog.csdn.net/wangpeng047/article/details/19624529
二、项目中用到HttpClient 去请求一个地址,但是用get请求如果参数过多,不同的浏览器会导致不同程度的参数丢失,所以还应该要有post的请求的方式,在加上post请求方式的后,发现不能用原来解析get请求的方式来解析服务器返回的数据,经多方查找资料最终找到了解决方案,故记之;
代码如下:
1 package com.shusheng.util; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.UnsupportedEncodingException; 6 import java.util.ArrayList; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 import java.util.regex.Matcher; 11 import java.util.regex.Pattern; 12 13 import javax.xml.parsers.DocumentBuilder; 14 import javax.xml.parsers.DocumentBuilderFactory; 15 import javax.xml.parsers.ParserConfigurationException; 16 17 18 import org.apache.http.HttpEntity; 19 import org.apache.http.HttpResponse; 20 import org.apache.http.NameValuePair; 21 import org.apache.http.client.ClientProtocolException; 22 import org.apache.http.client.HttpClient; 23 import org.apache.http.client.entity.UrlEncodedFormEntity; 24 import org.apache.http.client.methods.CloseableHttpResponse; 25 import org.apache.http.client.methods.HttpGet; 26 import org.apache.http.client.methods.HttpPost; 27 import org.apache.http.impl.client.CloseableHttpClient; 28 import org.apache.http.impl.client.DefaultHttpClient; 29 import org.apache.http.impl.client.HttpClients; 30 import org.apache.http.message.BasicNameValuePair; 31 import org.apache.http.util.EntityUtils; 32 import org.dom4j.DocumentException; 33 import org.dom4j.DocumentHelper; 34 import org.w3c.dom.DOMException; 35 import org.w3c.dom.Document; 36 import org.w3c.dom.Element; 37 import org.w3c.dom.NodeList; 38 import org.xml.sax.SAXException; 39 40 public class SendSmsMessage { 41 //验证用户信息 42 private static final String username = "username"; 43 private static final String password = "password"; 44 //字符编码及其他参数 45 private static final String charset = "utf-8"; 46 private static final String url = "http://127.0.0.1:8080/WebAPI/dtest.actioin"; 47 /* 48 * 因请求返回的数据中只需要code和result两个字段的信息,因此方法只返回一个存有这两个值的map 49 */ 50 //get方式请求 51 public static Map<String,String> sendMessageByGet(String content,String phones){ 52 Map<String,String> map = new HashMap<String, String>(); 53 HttpClient httpClient = new DefaultHttpClient(); 54 String fullUrl = url + "?user="+username+"&pwd="+password+"&mobiles="+phones+"&contents="+content; 55 HttpGet httpGet = new HttpGet(fullUrl); 56 try { 57 HttpResponse response = httpClient.execute(httpGet); 58 HttpEntity entity = response.getEntity(); 59 if (null != entity) { 60 InputStream in = entity.getContent();//将返回的内容流入输入流内 61 // 创建一个Document解析工厂 62 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 63 DocumentBuilder builder = factory.newDocumentBuilder(); 64 // 将输入流解析为Document 65 Document document = builder.parse(in);//用输入流实例化Document 66 67 Element rootElement = document.getDocumentElement(); 68 69 NodeList codeNode = rootElement.getElementsByTagName("Code"); 70 map.put("Code", codeNode.item(0).getTextContent()); 71 72 NodeList resultNode = rootElement.getElementsByTagName("Result"); 73 map.put("Result", resultNode.item(0).getTextContent()); 74 75 } 76 } catch (ClientProtocolException e) { 77 e.printStackTrace(); 78 } catch (IllegalStateException e) { 79 e.printStackTrace(); 80 } catch (DOMException e) { 81 e.printStackTrace(); 82 } catch (IOException e) { 83 e.printStackTrace(); 84 } catch (ParserConfigurationException e) { 85 e.printStackTrace(); 86 } catch (SAXException e) { 87 e.printStackTrace(); 88 } 89 return map; 90 } 91 92 //post方式请求 93 public static Map<String,String> sendMessageByPost(String content,String phones){ 94 Map<String,String> map = new HashMap<String, String>(); 95 // 创建默认的httpClient实例. 96 CloseableHttpClient httpclient = HttpClients.createDefault(); 97 // 创建httppost 98 HttpPost httppost = new HttpPost(url); 99 // 创建参数队列 100 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); 101 formparams.add(new BasicNameValuePair("user", username)); 102 formparams.add(new BasicNameValuePair("pwd", password)); 103 formparams.add(new BasicNameValuePair("mobiles", phones)); 104 formparams.add(new BasicNameValuePair("contents", content)); 105 106 UrlEncodedFormEntity uefEntity; 107 try{ 108 uefEntity = new UrlEncodedFormEntity(formparams, charset); 109 httppost.setEntity(uefEntity); 110 System.out.println("executing request " + httppost.getURI()); 111 CloseableHttpResponse response = httpclient.execute(httppost); 112 try{ 113 HttpEntity entity = response.getEntity(); 114 if (entity != null) { 115 //将返回的数据直接转成String 116 String str = EntityUtils.toString(entity, "UTF-8") ; 117 System.out.println("--------------------------------------"); 118 //注意这里不能写成EntityUtils.toString(entity, "UTF-8"),因为EntityUtils只能调用一次,否则会报错:java.io.IOException: Attempted read from closed stream 119 System.out.println("Response content: " + str); 120 System.out.println("--------------------------------------"); 121 122 //这里用str作为参数获得 Document 对象 123 org.dom4j.Document document = DocumentHelper.parseText(str); 124 org.dom4j.Element rootElement = document.getRootElement(); 125 126 String code = rootElement.element("Code").getText(); 127 String result = rootElement.element("Result").getText(); 128 map.put("Code", code); 129 map.put("Result", result); 130 } 131 }catch (DocumentException e) { 132 // TODO Auto-generated catch block 133 e.printStackTrace(); 134 }finally{ 135 response.close(); 136 } 137 138 } catch (ClientProtocolException e) { 139 e.printStackTrace(); 140 } catch (UnsupportedEncodingException e1) { 141 e1.printStackTrace(); 142 } catch (IOException e) { 143 e.printStackTrace(); 144 }finally{ 145 // 关闭连接,释放资源 146 try { 147 httpclient.close(); 148 } catch (IOException e) { 149 e.printStackTrace(); 150 } 151 } 152 153 return map ; 154 } 155 156 //验证手机号方法 157 public static boolean checkPhoneNo(String phone){ 158 if(phone==null || phone.trim().equals("")){ 159 return false; 160 } 161 String regExp = "^[1]([3][0-9]{1}|59|58|88|89)[0-9]{8}$"; 162 Pattern p = Pattern.compile(regExp); 163 Matcher m = p.matcher(phone); 164 return m.find(); 165 } 166 167 public static void main(String args[]){ 168 //System.out.println(checkPhoneNo(null)); 169 sendMessageByPost("【post请求】测试20151117_006","[正确手机号]"); 170 } 171 }
这里贴一下服务器的返回String类型的xml数据:
1 <?xml version="1.0" encoding="utf-8"?> 2 <APIResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/"> 3 <Code>12270</Code> 4 <Result>短信提交成功</Result> 5 </APIResult>
三、以上代码也可以看做是用java解析返回类型为xml的数据的方法;通过inputstream或者String 创建Document对象,然后通过该对象来解析每个分支的数据;上面代码中,如果在pos方式请求方法里用get方法那种解析xml的方式(即使用InputStream)会报错:java.io.IOException: Attempted read from closed stream;因此才使用String来创建Document的方式解析post请求返回的xml数据。有需要可以自己测试下,反正是个单独的类调试非常方便。
以上内容来自工作中遇到的问题以及上网查询所得,记以温之。
边系鞋带边思考人生.