springboot 整合cxf axis2
整合原因: axis2与springboot集成度很差,但客户端可连接asp.net的webservice。 而cxf整 合springboot很容易,但是客户端调用asp.net特困难。
故,ws服务用cxf,客户端用axis2.
- 依赖
<!--AXIS2--> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-kernel</artifactId> <version>1.7.9</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-ant-plugin</artifactId> <version>1.7.9</version> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-corba</artifactId> <version>1.7.9</version> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-jaxws</artifactId> <version>1.7.9</version> </dependency> <!-- cxf--> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.3.11</version> <exclusions> <exclusion> <artifactId>XmlSchema</artifactId> <groupId>org.apache.ws.commons.schema</groupId> </exclusion> </exclusions> </dependency>
2 服务端
(1) 配置
import javax.xml.ws.Endpoint; import org.apache.cxf.Bus; import org.apache.cxf.jaxws.EndpointImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CxfConfig { @Autowired private Bus bus; @Autowired private TestService testService; @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(bus, testService); endpoint.publish("/TestService"); return endpoint; } }
(2) 服务器接口
说明,方法sendRequest 能够被axis2 的OMElement指定参数名调用。另外暴露的方法、参数的命名空间最好一致。
import com.fasterxml.jackson.core.JsonProcessingException; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; @WebService(name = "TestService", // 暴露服务名称 targetNamespace = "http://www.yx.com/"// ) public interface TestService { @WebMethod @WebResult(name = "String") String sendMessage(@WebParam(name = "username") String username) throws JsonProcessingException; @WebMethod(operationName ="sendRequest",action = "http://www.yx.com/sendRequest") @WebResult(name = "String") String sendRequest(@WebParam(name = "xmlStr",targetNamespace = "http://www.yx.com/") String xmlStr) throws JsonProcessingException; }
(3) 接口实现
说明:endpointInterface 是指所实现的接口的 包路径。如:TestService 在com.isv1.apif下,那么路径为:com.isv1.api.TestService
import javax.jws.WebParam; import javax.jws.WebService; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.XmlUtil; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.stereotype.Component; import java.util.Map; /** * <p> * cxf 测试服务端 * </p> * * @author: fyh * @since: 2021/7/16 */ @WebService(serviceName = "TestService", // 与接口中指定的name一致 targetNamespace = "http://www.yx.com/", // 与接口中的命名空间一致, endpointInterface = "xxxx.TestService"// 接口地址 ) @Component public class TestServiceImpl implements TestService { @Override public String sendMessage(String username) throws JsonProcessingException { SysRole role = new SysRole(); role.setId(1L); role.setName("doctor"); role.setDescription("医生"); String xmlstr = XmlUtil.mapToXmlStr(BeanUtil.beanToMap(role)); return xmlstr; } @Override public String sendRequest( String xmlStr) { try { Map<String, Object> rootMap = XmlUtil.xmlToMap(xmlStr); ParamBodyDto<DrugRequestDto> bodyDtoTest = DrugParamUtil.toParamBodyDto(rootMap); return RpsUtil.toXmlFromHead("0", "成功"); } catch (Exception e) { e.printStackTrace(); return RpsUtil.toXmlFromHead("-1", "失败"); } } }
(4)运行测试
特别说明:经过以上就可使用了。服务器的端口,就是springboot常规项目的端品。Webservice服务器的对外提供的接口默认就是:http://localhost:8000/services/TestService?wsdl
注意:1、8000是application中通过port配置指定的。 2、“?wsdl”必须加。 3、“/services/”是cxf webservice默认暴露的服务地址。
3 客户端调用 ws方法
String url="http://localhost:8000/services/TestService?wsdl"; ServiceClient sender = new ServiceClient(); EndpointReference endpointReference = new EndpointReference(url); Options options = new Options(); options.setAction("http://www.yx.com/sendRequest");//指定action options.setTo(endpointReference); sender.setOptions(options); OMFactory fac = OMAbstractFactory.getOMFactory(); // 这个和qname差不多,设置命名空间 OMNamespace omNs = fac.createOMNamespace("http://www.yx.com/", "sendRequest"); OMElement data = fac.createOMElement("sendRequest", omNs); // 对应参数的节点,xmlStr是参数名称 String[] strs = new String[] { "xmlStr" }; // 参数值 String[] val = new String[] { xml }; for (int i = 0; i < strs.length; i++) { OMElement inner = fac.createOMElement(strs[0],omNs); inner.setText(val[i]); data.addChild(inner); } // 发送数据,返回结果 OMElement result = sender.sendReceive(data); System.out.println(result.toString());
注: 客户端调用的引用,为了方便copy党, 现把测试用的所有import贴上。多余的自行删除
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.XmlUtil; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.cxf.endpoint.Client; import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; import java.rmi.RemoteException; import javax.xml.bind.DatatypeConverter; import javax.xml.namespace.QName; import javax.xml.ws.Service; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.*;