SpringBoot WebService 源代码:https://gitee.com/VipSoft/VipWebService
SpringBoot WebService 及 注意项: https://www.cnblogs.com/vipsoft/p/14993568.html
服务端添加拦截器
import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import java.util.List; import org.apache.cxf.binding.soap.SoapHeader; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.w3c.dom.Element; import javax.xml.soap.SOAPException; @Component public class WsAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private static final String USERNAME = "root"; private static final String PASSWORD = "admin"; public WsAuthInterceptor() { // 定义在哪个阶段进行拦截 super(Phase.PRE_PROTOCOL); } @Override public void handleMessage(SoapMessage soapMessage) throws Fault { List<Header> headers = soapMessage.getHeaders(); String username = null; String password = null; if (headers == null || headers.isEmpty()) { throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息")); } // 获取用户名,密码 for (Header header : headers) { SoapHeader soapHeader = (SoapHeader) header; Element e = (Element) soapHeader.getObject(); username = e.getAttribute("username"); password = e.getAttribute("password"); if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { throw new Fault(new IllegalArgumentException("用户信息为空")); } } // 校验用户名密码 if (!(USERNAME.equals(username) && PASSWORD.equals(password))) { SOAPException soapExc = new SOAPException("认证失败"); System.err.println("用户认证信息错误"); throw new Fault(soapExc); } } }
@Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), demoService()); //绑定要发布的服务 endpoint.publish("/api"); // 暴露webService api,用在资源访问 endpoint.getInInterceptors().add(wsAuthInterceptor); return endpoint; }
--------
客户端调用
SOAP UI
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.his.iron.com"> <soapenv:Header> <Author username="root" password="admin"></Author> </soapenv:Header> <soapenv:Body> <ser:sayHello> <!--Optional:--> <arg>Test</arg> </ser:sayHello> </soapenv:Body> </soapenv:Envelope>
WebService 动态调用
@Override public String soapDynamicTest(String ip) { try{ //创建动态客户端 JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); // Client client = factory.createClient("http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl"); Client client = factory.createClient("http://192.168.1.216:9090/ws/api?wsdl"); // 需要密码的情况需要加上用户名和密码 //client.getOutInterceptors().add(new ClientAuthInterceptor("USER_NAME","PASS_WORD")); // 拦截器的方式 client.getOutInterceptors().add(new ClientCheckInterceptor()); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setConnectionTimeout(2000); //连接超时 httpClientPolicy.setAllowChunking(false); //取消块编码 httpClientPolicy.setReceiveTimeout(120000); //响应超时 conduit.setClient(httpClientPolicy); //region Entity to xml // 假设你有一个 JSON 对象,这里我们简化为一个 Java 对象 MyObject myObject = new MyObject(); // 这个类应该与你的 JSON 结构对应 myObject.setField1("value1"); myObject.setField2("value2"); // 3. 将 Java 对象转换为 XML JAXBContext jaxbContext = JAXBContext.newInstance(MyObject.class); Marshaller marshaller = jaxbContext.createMarshaller(); StringWriter sw = new StringWriter(); marshaller.marshal(myObject, sw); String xml = sw.toString(); //endregion Object[] objects = new Object[0]; // invoke("方法名",参数1,参数2,参数3....); // objects = client.invoke("getCountryCityByIp", ip); objects = client.invoke("sayHello", ip); System.out.println("返回数据:" + objects[0]); // return ((ArrayOfString) objects[0]).getString().toString(); return objects[0].toString(); }catch (Exception e){ e.printStackTrace(); } return ""; }
ClientCheckInterceptor.java
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; import javax.xml.namespace.QName; import java.util.List; public class ClientAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private static final String USERNAME = "root"; private static final String PASSWORD = "admin"; public ClientCheckInterceptor() { super(Phase.PREPARE_SEND); } @Override public void handleMessage(SoapMessage message) throws Fault { List<Header> headers = message.getHeaders(); Document document = DOMUtils.createDocument(); Element authorEle = document.createElement("author"); authorEle.setAttribute("username", USERNAME); authorEle.setAttribute("password", PASSWORD); headers.add(new Header(new QName(""), authorEle)); } }