原有一套.net程序已经大量部署,使用c#作为客户端调用另一端c#写的web services,现在想把服务端换成java,原有的.net客户端代码不动,实现对java webservice端的支持。
说实在的结合springboot和webservice一共写不了几行代码就可以把webservices服务端开发出来,可问题出在原有的webservice客户端代码不能改动,这个事就变成了写个java的webservice端,可以模拟的和c#开发的那个webservice端哪哪都一样。
很不幸,低版本.net实现的webservices服务端不是特别标准,调用的时候客户端发出来的soap消息很难适配到java这边的webservices服务端,折腾了两天最后直接用springboot的controller接收soap消息体然后自己解析soap 消息xml解决了。
以下为soap请求消息体内容
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ReceiveOrder xmlns="http://www.abc.com.cn/">
<name>www.abc.com.cn</name>
<password>123456</password>
<xxxID>123456</xxxID>
<xxxCode>123456</xxxCode>
<orderId>123456</orderId>
<orderType>123456</orderType>
<sendType>123456</sendType>
<orderDate>2022-08-03T08:45:01</orderDate>
<orderOperator>张三</orderOperator>
<requireDate>2022-08-03T23:59:59</requireDate>
<operateDate>2022-08-04T10:29:07.520401+08:00</operateDate>
<productNameIds>
<string>abc</string>
<string>def</string>
</productNameIds>
<units>
<string>U</string>
<string>U</string>
</units>
<specifications>
<float>1</float>
<float>1</float>
</specifications>
<amountBag>0</amountBag>
<orderTypeName>正常预约</orderTypeName>
</ReceiveOrder>
</soap:Body>
</soap:Envelope>
接收与处理的controller代码:
@Controller
public class TestController {
private static final Logger logger = LoggerFactory.getLogger(TestController.class.getName());
@RequestMapping("/testrecvxml")
@ResponseBody
public String testRecvXml(HttpServletRequest request) throws IOException {
//从http request对象中获取soap消息内容
Reader body = request.getReader();
StringBuilder sb = new StringBuilder();
char[] buf = new char[1024];
int len;
while ((len = body.read(buf)) != -1) {
sb.append(buf, 0, len);
}
body.close();
//以上是从http request对象中获取soap消息内容
//解析soap消息内容
try {
InputStream bStream = new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage(null, bStream);
SOAPBody soapBody = soapMessage.getSOAPBody();
Iterator<SOAPElement> iterator = soapBody.getChildElements();
SOAPElement receiveOrderElement=null;
if (iterator.hasNext()) {
receiveOrderElement = iterator.next();
}
if (null == receiveOrderElement) {
//如果没有取到soap消息内容中<ReceiveOrder xmlns="http://www.abc.com.cn/">,则返回错误信息
return "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" +
" <soap:Body>\n" +
" <ReceiveOrderResponse xmlns=\"http://www.abc.com.cn/\" />\n" +
" </soap:Body>\n" +
"</soap:Envelope>";
}
//初始化接收订单对象
ReceiveOrderPojo receiveOrderPojo = new ReceiveOrderPojo();
//用于格式化日期
java.text.SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Iterator receiveChildNodeElements = receiveOrderElement.getChildElements();
//以下开始遍历 xml节点里面的所有子节点
while (receiveChildNodeElements.hasNext()) {
SOAPElement currentSoapNodeElement = (SOAPElement) receiveChildNodeElements.next();
String currentNodeName = currentSoapNodeElement.getLocalName();
String currentNodeValue = currentSoapNodeElement.getValue();
if ("name".equals(currentNodeName)) {
receiveOrderPojo.setName(currentNodeValue);
} else if ("password".equals(currentSoapNodeElement.getLocalName())) {
receiveOrderPojo.setPassword(currentNodeValue);
} else if ("xxxID".equals(currentNodeName)) {
receiveOrderPojo.setXxxID(currentNodeValue);
} else if ("operateDate".equals(currentNodeName)) {
Date date = sdf.parse(currentNodeValue);
receiveOrderPojo.setOperateDate(date);
} else if ("productNameIds".equals(currentNodeName)) {
Iterator subChildElements = currentSoapNodeElement.getChildElements();
while (subChildElements.hasNext()) {
SOAPElement tmpSoapElement = (SOAPElement) subChildElements.next();
String localName1 = tmpSoapElement.getLocalName();
String literalValue1 = tmpSoapElement.getValue();
if ("string".equals(localName1)) {
receiveOrderPojo.getProductNameIds().add(literalValue1);
}
}
} else if ("specifications".equals(currentNodeName)) {
Iterator subChildElements = currentSoapNodeElement.getChildElements();
while (subChildElements.hasNext()) {
SOAPElement tmpSoapElement = (SOAPElement) subChildElements.next();
String localName1 = tmpSoapElement.getLocalName();
String literalValue1 = tmpSoapElement.getValue();
if ("float".equals(localName1)) {
receiveOrderPojo.getSpecifications().add(Float.valueOf(literalValue1));
}
}
} else if ("amountBag".equals(currentNodeName)) {
Integer val = Integer.parseInt(currentNodeValue);
receiveOrderPojo.setAmountBag(val);
} else if ("orderTypeName".equals(currentNodeName)) {
receiveOrderPojo.setOrderTypeName(currentNodeValue);
}
}
logger.debug(receiveOrderPojo.toString());
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
}
以上是接收代码,返回值未处理,要返回正常的soap message response还是基于SOAPMessage去编程处理返回数据就可以了。