背景:对接oa系统,需要用
webservice
方式对接,对方提供了
wsdl地址和对应文件
,之后说要在请求头信息上添加对应的验证信息(
非标准的验证,是自定义的头信息
,服务端自己解析处理)。现场环境为
内网环境
,只能通过vpn访问,并且测试的时候
不能频繁发增量包
,因为项目启动时间比较长,耽误现场实施配置东西。
首先对接接口
第一步:反向生成客户端(这应该是对接webservice接口最简单的方式了)
关于webservice基本知识强烈建议首先参考:
反向生成客户端,首先看看项目用的哪个版本的jdk,然后到jdk bin界面删除原路径后输入cmd回车后即可
对应命令为
wsimport -p cn.cad.mobile -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
命令解析:
-p 后为你生成文件的src下的包名
-s 后要把文件生成在哪个地方,“.”即为当前路径。
最后部分为给出的wsdl链接,或者为wsdl文件(访问这个链接后右键另存为,然后改一下后缀即可)
这样客户端就生成了,具体如何使用,参考上方的链接。
第二步:测试联调,本地测试
需要使用
soapui测试工具
首先生成客户端,点击soap,然后将wsdl链接输入点ok即可。
然后生成服务端
相当于本地已经有了对应的服务端,访问对应链接发现没有问题
展示出对应的wsdl文件则没有问题,第二次打开的时候需要右键服务端开启。
自己写的测试类能返回200即可,说明接口能通
jar包测试
将自己写完的测试类打成jar包后,在现场进行测试即,这样既能测试接口是否通了,也能不影响试试人员调试现场问题,不用频繁换包。
javaproject工程打jar包参考
补充
生成客户端并补充头部的方法,都是增加拦截的方法(注释的上下部分),
package com.limy.test.common.tt;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.limy.test.common.AddHeaderInterceptor;
import com.limy.test.common.WsUtils;
public class Test {
public static void main(String[] args) {
// JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
// // 记录入站消息
// factory.getInInterceptors().add(new LoggingInInterceptor());
// // 记录出站消息
// factory.getOutInterceptors().add(new LoggingOutInterceptor());
// // 添加消息头验证信息。如果服务端要求验证用户密码,请加入此段代码
//
// factory.getOutInterceptors().add(new AddHeaderInterceptor("123", "456"));
// factory.setServiceClass(MobileCodeWSSoap.class);
// factory.setAddress("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
// // 使用MTOM编码处理消息。如果需要在消息中传输文档附件等二进制内容,请加入此段代码
// // Map props = new HashMap();
// // props.put("mtom-enabled", Boolean.TRUE);
// // factory.setProperties(props);
//
// // 创建服务代理并返回
// MobileCodeWSSoap ws = (MobileCodeWSSoap) factory.create();
MobileCodeWSSoap ws = WsUtils.getProxyEkPws();
String resu = ws.getMobileCodeInfo("15733883789", "");
System.out.println(resu);
// URL wsdlLocation;
// MobileCodeWSSoap ws = null;
// try {
// wsdlLocation = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
// ws = (MobileCodeWSSoap) new MobileCodeWS(wsdlLocation).getMobileCodeWSSoap();
// Client client = ClientProxy.getClient(ws);
// client.getInInterceptors().add(new LoggingInInterceptor());
// client.getOutInterceptors().add(new LoggingOutInterceptor());
// client.getOutInterceptors().add(new AddHeaderInterceptor("456", "484565"));
//
// } catch (MalformedURLException e) {
// e.printStackTrace();
// }
// System.out.println(ws.getMobileCodeInfo("15733883789", ""));;
}
}
最后有一个增加头信息验证的部分,因为不是标准的头信息验证,需要用稍微特殊的方式增加对应头信息,下面是具体的监听代码。
当时遇见的问题是子节点不想有对应的命名空间部分,上面的代码无法实现,所以用了下面未注释的。
package com.limy.test.common;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
private String user;
private String password;
public AddHeaderInterceptor(String user, String password) {
super(Phase.PREPARE_SEND); // 发送SOAP消息之前调用拦截器
this.user=user;
this.password=password;
}
public void handleMessage(SoapMessage message) throws Fault {
String namespace = "http://sys.webservice.client"; //命名空间
String prefix = "tns"; //前缀
List<Header> headers=message.getHeaders();
// try {
//
// SOAPElement requestSOAPHeaderElm = SOAPFactory.newInstance().createElement("RequestSOAPHeader",prefix,namespace);
//
// SOAPElement userElm = SOAPFactory.newInstance().createElement("user",prefix,namespace); //user标签
// SOAPElement posswordElm = SOAPFactory.newInstance().createElement("possword",prefix,namespace); //possword标签
// userElm.addTextNode(user);
// posswordElm.addTextNode(password);
//
// requestSOAPHeaderElm.addChildElement(userElm);
// requestSOAPHeaderElm.addChildElement(posswordElm);
//
// SoapHeader hh = new SoapHeader(new QName("RequestSOAPHeader"), requestSOAPHeaderElm);
// headers.add(hh);
//
// } catch (SOAPException e) {
// e.printStackTrace();
// }
Document doc=DOMUtils.createDocument();
Element ele = doc.createElementNS(namespace, "RequestSOAPHeader");
ele.setPrefix(prefix);
Element idElement=doc.createElementNS(namespace,"user");
idElement.setPrefix(prefix);
idElement.setTextContent(user);
Element passElement=doc.createElementNS(namespace,"password");
passElement.setPrefix(prefix);
passElement.setTextContent(password);
ele.appendChild(idElement);
ele.appendChild(passElement);
headers.add(new Header(new QName(namespace,"RequestSOAPHeader",prefix),ele));
}
}
致此结束。
从这一顿操作中,感觉猜了无数的坑,最后还是完成了,而且最后用的另一种打jar包的方法(自定义.MF文件)
重新又理解了最初写helloword并让黑白框显示出helloword的过程,挺好。
最后是webservice需要的jar包为(不包括gson的)