应该是有两种方法
1、使用WSDL,利用wsimport 命令创建接口类。然后调用。
2、手工写 soap 消息的创建 处理程序。
这次遇到的 WSDL文件,在wsimport命令下 报错,而且就是一个查询操作,所以就自己编写了个SOAP消息处理程序。
基本结构就是 创建SOAP消息,添加内容,发送消息,获取应答,处理结果
需要使用的类库
import java.net.URL;
import java.util.Calendar;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Node;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
消息处理程序
try {
// 创建连接
// ==================================================
SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory
.newInstance();
SOAPConnection connection = soapConnFactory.createConnection();
// 创建消息对象
// ===========================================
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
// message.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "gb2312");
// 创建soap消息主体==========================================
SOAPPart soapPart = message.getSOAPPart();// 创建soap部分
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("adin", "http://3e.pl/ADInterface");
//envelope.setAttribute("xmlns:adin","http://3e.pl/ADInterface"); 这段setAttrbute 在javac下编译运行都可以,但是用到web servlet中就报错 找不到namespace
SOAPBody body = envelope.getBody();
// 根据要传给mule的参数,创建消息body内容。具体参数的配置可以参照应用集成接口技术规范1.1版本
// =====================================
// SOAPElement bodyElement = body.addChildElement(envelope.createName(
// "process", "Request", "http://esb.service.com/"));
SOAPElement query = body.addChildElement("queryData","adin");
// body.addChildElement("adin:getVersion");
SOAPElement modelElement= query.addChildElement("ModelCRUDRequest","adin");
SOAPElement ModelCRUD = modelElement.addChildElement("ModelCRUD","adin");
ModelCRUD.addChildElement("serviceType","adin").addTextNode("QueryAG_PlaintSummary");
ModelCRUD.addChildElement("TableName","adin").addTextNode("AG_PlaintSummary_V");
ModelCRUD.addChildElement("RecordID","adin").addTextNode("0");
SOAPElement DataRow = ModelCRUD.addChildElement("DataRow","adin");
SOAPElement field = DataRow.addChildElement("field","adin");
field.addAttribute(envelope.createName("type"), "String");
field.addChildElement("val","adin").addTextNode("01420004000003380024");
SOAPElement lookup = field.addChildElement("lookup","adin");
SOAPElement lv = lookup.addChildElement("lv","adin");
lv.addAttribute(envelope.createName("val"), "?");
lv.addAttribute(envelope.createName("key"), "?");
SOAPElement ADLoginRequest = modelElement.addChildElement("ADLoginRequest","adin");
ADLoginRequest.addChildElement("user","adin").addTextNode("System");
ADLoginRequest.addChildElement("pass","adin").addTextNode("System");
// Save the message
message.saveChanges();
* 实际的消息是使用 call()方法发送的,该方法接收消息本身和目的地作为参数,并返回第二个 SOAPMessage 作为响应。
* call方法的message对象为发送的soap报文,url为mule配置的inbound端口地址。
*/
URL url = new URL("http://10.110.0.131:9080/ADInterface/services/ModelADService");
// 响应消息
// ===========================================================================
SOAPMessage reply = connection.call(message, url);
// ==================创建soap消息转换对象 转换成string 返回,正常应该解析消息,提取内容。
StringWriter sw = new StringWriter();
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// Extract the content of the reply======================提取消息内容
Source sourceContent = reply.getSOAPPart().getContent();
// Set the output for the transformation
StreamResult result = new StreamResult(sw);
//ByteArrayOutputStream bos = new ByteArrayOutputStream();
transformer.transform(sourceContent, result);
// Close the connection 关闭连接 ==============
// System.out.println("");
sw.flush();
sw.close();
String xmlStr = sw.toString();
connection.close();
return xmlStr;
/*
* 模拟客户端A,异常处理测试
*/
// SOAPBody ycBody = reply.getSOAPBody();
// Node ycResp = ycBody.getFirstChild();
// System.out.print("returnValue:"+ycResp.getTextContent());
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
return "error:"+e.getMessage().toString();
}
复杂的soap消息,利用soapclient 调试 会更加容易。
在使用上述程序 在 tomcat 下是 没有问题 的,在 weblogic 下 就会 死的很惨了。。。。。。
3、所以 几经努力 找到了另一个 webligic 10.3 下 能用的 构建soap消息的方法。。。
新建一个soap消息的xml 文档 soap.xml
使用dom的doc 对象解析 这个 xml文件 ,替换 掉 需要 查询的内容。
然后 将 doc 转换成string ,利用 mimeheaders+ inputstream 构建 soap 消息。
MessageFactory messageFactory = MessageFactory.newInstance();
MimeHeaders mmh = new MimeHeaders();
mmh.setHeader("Content-Type", "text/xml");
SOAPMessage message = messageFactory.createMessage(mmh,new ByteArrayInputStream(SoapStr.getBytes("UTF-8")));
需要在 构建soapmessage 消息的时候 设定 memiheaders 中的 content-type text/xml
在解析的时候 也 无法 直接获取 soap消息中的 doc对象。
然后 又利用 string 转换了一下
研究的 不深,但总算 解决了 问题。
总之 weblogic 对 webservice的 支持 各种 乱。