今日公司要做一个协同办公系统(OA),PC端已经完成。现在要做一个手机端网页端的。从登陆入手,需要向 服务端发送一段请求报文获取响应报文,对响应报文进行解析判断是否登录成功。
当然手机客户端发送请求就不说了,就是普通的web请求。以下重点来讲怎么发送Soap请求报文来获取响应报文你该进行解析。话说多不如上代码。代码中有必要的注释。
这是接口信息,描述了输入输出参数特征
这是需要发送的请求报文和服务地址,还有需要我们接收的响应报文。
当然,http://localhost:8080/v6sp2/WorkflowCommonService?xsd=1这个服务地址前部分是自己项目的地址,是要变得。
这就是所有资料信息。
思路:用HttpClinet 来获取响应报文,document文档解析响应报文
为了结构明确,层次分明,我将冗长的方法封装在了多个方法中,在主方法中体现功能调用顺序,这样思路更清晰些。大家可以看主方法的中的调用顺序进行学习。调用方法出用红色字体标注.思路由黄色底色标注。
public static void main(String[] args) {
StringBuilder soap=new StringBuilder(); //构造请求报文
soap.append(" ");
soap.append(" ");
soap.append(" admin&admin ");
soap.append(" ");
soap.append(" ");
soap.append(" ");
soap.append(" loginname ");
soap.append(" password ");
soap.append(" system ");
soap.append(" ");
soap.append(" ");
soap.append(" ");
String requestSoap=soap.toString();
String serviceAddress="http://IP:Port/WorkflowCommonService?wsdl"; //服务地址(将XXXX替换成自己项目的地址)
String charSet="utf-8";
String contentType="text/xml; charset=utf-8";
//第一步:调用方法getResponseSoap。返回响应报文和状态码
Map responseSoapMap=SoapUtil.getResponseSoap(requestSoap, serviceAddress, charSet, contentType);
Integer statusCode=(Integer)responseSoapMap.get("statusCode");
if(statusCode==200){
String responseSoap=(String)responseSoapMap.get("responseSoap");
String targetNodeName="isSuccess";
//第二步:调用strXmlToDocument方法。
将字符串类型的XML的响应报文 转化成Docunent结构文档
Document doc=XMLUtil.strXmlToDocument(responseSoap);
//第三步:调用getValueByElementName方法。递归获得目标节点的值
String result= XMLUtil.getValueByElementName(doc,targetNodeName);
if(!StringUtils.isEmpty(result)){
System.out.println(result);
}
else{
System.out.println("没有此节点或者没有值!");}
}
else{
System.out.println("请求失败!");
}
}
工具类 SoapUtil.class 。
/**
* Description: 根据请求报文,请求服务地址获取 响应报文
* @param requestSoap 请求报文
* @param serviceAddress 响应报文
* @param charSet 字符集
* @param contentType 类型
* @return map封装的 服务器响应参数和返回报文.PS:statusCode :200正常响应。responseSoap:响应报文
*
thinking:
*
* @author huoge
*
public static Map responseSoap(String requestSoap,String serviceAddress,String charSet, String contentType){
String responseSoap="";
Map resultmap=new HashMap();
PostMethod postMethod = new PostMethod(serviceAddress);
byte[] b = new byte[0];
try {
b = requestSoap.getBytes(charSet);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
InputStream is = new ByteArrayInputStream(b, 0, b.length);
RequestEntity re = new InputStreamRequestEntity(is, b.length, contentType);
postMethod.setRequestEntity(re);
HttpClient httpClient = new HttpClient();
int statusCode = 0;
try {
statusCode = httpClient.executeMethod(postMethod);
resultmap.put("statusCode", statusCode);
} catch (IOException e) {
throw new RuntimeException("执行http请求失败", e);
}
if (statusCode == 200) {
try {
responseSoap = postMethod.getResponseBodyAsString();
resultmap.put("responseSoap", responseSoap);
} catch (IOException e) {
throw new RuntimeException("获取请求返回报文失败", e);
}
} else {
throw new RuntimeException("请求失败:" + statusCode);
}
return resultmap;
}
/**
* Description:将字符串类型的XML 转化成Docunent文档结构
* @param parseStrXml 待转换的xml 字符串
* @return Document
*
* @author huoge
*/
public static Document strXmlToDocument(String parseStrXml){
StringReader read = new StringReader(parseStrXml);
//创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
InputSource source = new InputSource(read);
//创建一个新的SAXBuilder
SAXBuilder sb = new SAXBuilder(); // 新建立构造器
Document doc = null;
try {
doc = sb.build(source);
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
/**
* Description: 根据目标节点名获取值
* @param doc 文档结构
* @param finalNodeName 最终节点名
* @return
*
* @author huoge
*/
public static String getValueByElementName(Document doc,String finalNodeName){
Element root = doc.getRootElement();
HashMap map=new HashMap();
//调用getChildAllText方法。获取目标子节点的值
Map resultmap=getChildAllText(doc, root,map);
String result=(String)resultmap.get(finalNodeName);
return result;
}
/**
* Description: 递归获得子节点的值
* @param doc 文档结构
* @param e 节点元素
* @param resultmap 递归将值压入map中
* @return
*
* @author huoge
*/
public static Map getChildAllText(Document doc, Element e,HashMap resultmap)
{
if (e != null)
{
if (e.getChildren() != null) //如果存在子节点
{
List list = e.getChildren();
for (Element el : list) //循环输出
{
if(el.getChildren().size() > 0) //如果子节点还存在子节点,则递归获取
{
getChildAllText(doc, el,resultmap);
}
else
{
resultmap.put(el.getName(), el.getTextTrim()); //将叶子节点值压入map
}
}
}
}
return resultmap;
}
如果对xml文档解析存在疑点,下篇文章我将带大家学习几种XML解析方法。
对webservice soap请求,可以借助一个功能强大的软件SoapUI进行测试。也是为了防止中途错误不迷途知返。
打开界面是这样的
点击左上角的soap,会弹出弹框让你写入你的项目名(随便起)和服务地址。
如果地址正确的话,会出现这样的列表,选中一个双击点开是这样的:
左右的输入框的请求报文中?是需要传入的参数,直接填入即可,然后点击左上角绿色三角会得到响应报文。是这样的:
我相信这个工具会很有帮助的,当然他的功能远不止这些。。。
祝大家学习工作愉快!