我试过两种办法,第一种 soap2 jar包,但是没成功;第二种,用http方式调用,成功了,现在记录分享一下。
http调用是拼写了报文的,你让后台自己调用一下,把请求报文全部发给你,你自己看着他的,然后拼一个一模一样的字符串出来,传给后台就好,调用就OK。
一、知道两个概念
soapAction:找后台拿来ip,在网页打开,能看到如下
contentType:我现在设置的是 application/soap+xml;charset=utf-8;这个需要你和你们后台对应好,不然不会调用成功的。
二、拼写请求报文,和后台要来他调用的报文,自己看着拼一个一模一样的,http 发送,就OK了。
这是我的。拼写的时候要仔细,做到一字不差。
三、下面我把发送请求报文的工具类发出来
mport android.util.Log;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpUtil {
//发送xml 并返回数据
// public static String sendSoapPost(String url, String xml,
// String contentType, String soapAction) {
// String urlString = url;
// HttpURLConnection httpConn = null;
// OutputStream out = null;
// String returnXml = "";
// try {
// httpConn = (HttpURLConnection) new URL(urlString).openConnection();
// httpConn.setRequestProperty("Content-Type", contentType);
// if (null != soapAction) {
// httpConn.setRequestProperty("SOAPAction", soapAction);
// }
// httpConn.setRequestMethod("POST");
// httpConn.setDoOutput(true);
// httpConn.setDoInput(true);
// httpConn.connect();
// out = httpConn.getOutputStream(); // 获取输出流对象
// httpConn.getOutputStream().write(xml.getBytes("UTF-8")); // 将要提交服务器的SOAP请求字符流写入输出流
// out.flush();
// out.close();
// int code = httpConn.getResponseCode(); // 用来获取服务器响应状态
// String tempString = null;
// StringBuffer sb1 = new StringBuffer();
// if (code == HttpURLConnection.HTTP_OK) {
// BufferedReader reader = new BufferedReader(
// new InputStreamReader(httpConn.getInputStream(),
// "UTF-8"));
// while ((tempString = reader.readLine()) != null) {
// sb1.append(tempString);
// }
// if (null != reader) {
// reader.close();
// }
// } else {
// BufferedReader reader = new BufferedReader(
// new InputStreamReader(httpConn.getErrorStream(),
// "UTF-8"));
// // 一次读入一行,直到读入null为文件结束
// while ((tempString = reader.readLine()) != null) {
// sb1.append(tempString);
// }
// if (null != reader) {
// reader.close();
// }
// }
// // 响应报文
// returnXml = sb1.toString();
// } catch (Exception e) {
// e.printStackTrace();
// }
// return returnXml;
// }
//发送xml 并返回数据
public static InputStream sendSoapPost(String url, String xml, String contentType, String soapAction) {
String urlString = url;
HttpURLConnection httpConn = null;
OutputStream out = null;
try {
httpConn = (HttpURLConnection) new URL(urlString).openConnection();
httpConn.setRequestProperty("Content-Type", contentType);
if (null != soapAction) {
httpConn.setRequestProperty("SOAPAction", soapAction);
}
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.connect();
out = httpConn.getOutputStream(); // 获取输出流对象
httpConn.getOutputStream().write(xml.getBytes("UTF-8")); // 将要提交服务器的SOAP请求字符流写入输出流
out.flush();
out.close();
int code = httpConn.getResponseCode(); // 用来获取服务器响应状态
String tempString = null;
StringBuffer sb1 = new StringBuffer();
if (code == HttpURLConnection.HTTP_OK) {
Log.e("sendSoapPost",httpConn.getResponseMessage());
return httpConn.getInputStream();
}
// 响应报文
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 通用 生成 发送的 xml 包
public static String creatXml(String payaction,String paymsg,String md5){
String paytype = "26";
StringBuilder sb = new StringBuilder("");
sb.append("<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">");
sb.append(" <s:Header>");
sb.append(" <a:Action s:mustUnderstand=\"1\">http://tempuri.org/IHYPayService/hypayexchange</a:Action>");
sb.append(" <a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>");
sb.append(" <a:To s:mustUnderstand=\"1\">http://47.94.82.223:8740/Service/HYService/HYPayService.svc?wsdl</a:To>");
sb.append("</s:Header>");
sb.append(" <s:Body>");
sb.append(" <hypayexchange xmlns=\"http://tempuri.org/\">");
sb.append( " <paytype>" + paytype + "</paytype><payaction>" + payaction + "</payaction>");
sb.append(" <paymsg>" + paymsg + "</paymsg>");
sb.append(" <paymac>"+ md5 + "</paymac>");
sb.append(" </hypayexchange>");
sb.append(" </s:Body>");
sb.append(" </s:Envelope>");
String dataXml = sb.toString();
return dataXml;
}
}
四、下面,请求成功后,拿到返回的 InputStream ,开始解析吧,解析我采用的 xml解析的 sax 解析,下面是代码
// nodeName,注意:这个是,返回的xml 数据的,你要的 json 数据 外层的 节点名称,节点都是对应的。我的是 hypayexchangeResult
//方法:解析xml数据并返回,返回值类型是HashMap
public static List<HashMap<String, String>> readXML(InputStream inputStream, String nodeName) {
try {
//实例化SAX工厂类
SAXParserFactory factory=SAXParserFactory.newInstance();
//实例化SAX解析器。
SAXParser sParser=factory.newSAXParser();
//实例化工具类MyHandler,设置需要解析的节点
SaxHandler myHandler=new SaxHandler(nodeName);
// 开始解析
sParser.parse(inputStream, myHandler);
// 解析完成之后,关闭流
inputStream.close();
//返回解析结果。
Log.e("readXML",myHandler.getList().toString());
return myHandler.getList(); //在这里返回解析之后的数据
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
(1)、下面是 SaxHandler 类,不能少了
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
//类:MyHandler,继承DefaultHandler类,用于解析XML数据。
//之后在MainActivity中通过设定具体的nodeName来实例化MyHandler
public class SaxHandler extends DefaultHandler {
private List<HashMap<String, String>> list = null; //解析后的XML内容
private HashMap<String, String> map = null; //存放当前需要记录的节点的XML内容
private String currentTag = null;//当前读取的XML节点
private String currentValue = null;//当前节点的XML文本值
private String nodeName = null;//需要解析的节点名称
public SaxHandler(String nodeName) {
// 设置需要解析的节点名称
this.nodeName = nodeName;
}
@Override
public void startDocument() throws SAXException {
// 接收文档开始的通知
// 实例化ArrayList用于存放解析XML后的数据
list = new ArrayList<HashMap<String, String>>();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 接收元素开始的通知
if (qName.equals(nodeName)) {
//如果当前运行的节点名称与设定需要读取的节点名称相同,则实例化HashMap
map = new HashMap<String, String>();
}
//Attributes为当前节点的属性值,如果存在属性值,则属性值也读取。
if (attributes != null && map != null) {
for (int i = 0; i < attributes.getLength(); i++) {
//读取到的属性值,插入到Map中。
map.put(attributes.getQName(i), attributes.getValue(i));
}
}
//记录当前节点的名称。
currentTag = qName;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// 接收元素中字符数据的通知。
//当前节点有值的情况下才继续执行
if (currentTag != null && map != null) {
//获取当前节点的文本值,ch这个直接数组就是存放的文本值。
currentValue = new String(ch, start, length);
if (currentValue != null && !currentValue.equals("")
&& !currentValue.equals("\n")) {
//读取的文本需要判断不能为null、不能等于”“、不能等于”\n“
map.put(currentTag, currentValue);
}
}
//读取完成后,需要清空当前节点的标签值和所包含的文本值。
currentTag = null;
currentValue = null;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 接收元素结束的通知。
if (qName.equals(nodeName)) {
//如果读取的结合节点是我们需要关注的节点,则把map加入到list中保存
list.add(map);
//使用之后清空map,开始新一轮的读取person。
map = null;
}
}
//方法:获取解析之后的数据
public List<HashMap<String, String>> getList() {
return list;
}
}五、 拿到解析好的数据了
List<HashMap<String, String>> list= SaxService.readXML(resultXml, "hypayexchangeResult");
String hypayexchangeResult = "";
for (int i = 0; i < list.size(); i++) {
hypayexchangeResult = list.get(i).get("hypayexchangeResult");
}
hypayexchangeResult :这就是你最终想要的 json 数据了,拿去解析吧。
因为之前没有调用过 webService,也是折腾了不少时间,经过解决这个问题,明白了一个道理。
有时候,努力的方向不对,你需要付出很多倍的时间和经理,可能最终还是没有成功;所以,选对努力的方向很重要。