Apache-cxf小结
一、简介
Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
二、使用
1、使用jdk的类发布webservice
a、编写接口和实现类
package org.moy.soap.jdk; import javax.jws.WebService; /** * say something * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ @WebService public interface HelloService { String sayHi(String name); }
package org.moy.soap.jdk; import javax.jws.WebService; /** * say something * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ @WebService public class HelloServiceImpl implements HelloService { @Override public String sayHi(String name) { return String.format("hi , %s" , name); } }
b、编写服务端和客户端
package org.moy.soap.jdk; import javax.xml.ws.Endpoint; /** * say something * * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ public class SoapServer { public static void main(String[] args) { String soapAddress = "http://localhost:8080/ws/soap/hi"; Endpoint.publish(soapAddress, new HelloServiceImpl()); System.out.printf("WebService address : %s?wsdl", soapAddress); } }
package org.moy.soap.jdk; import javax.xml.namespace.QName; import javax.xml.ws.Service; import java.net.MalformedURLException; import java.net.URL; /** * say something * * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ public class SoapClient { public static void main(String[] args) throws MalformedURLException { URL wsdl = new URL("http://localhost:8080/ws/soap/hi?wsdl"); String targetNamespace = "http://jdk.soap.moy.org/"; QName serviceName = new QName(targetNamespace, "HelloServiceImplService"); QName portName = new QName(targetNamespace, "HelloServiceImplPort"); Service service = Service.create(wsdl, serviceName); HelloService helloService = service.getPort(portName, HelloService.class); System.out.println(helloService.sayHi("moy")); } }
c、测试:运行服务后,在运行客户端
2、使用cxf发布webservice
a、新建好web工程,比如我使用maven新建工程,其pom.xml配置文件为
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>webservice-demo</artifactId> <groupId>org.moy.soap</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>soap-webapp</artifactId> <packaging>war</packaging> <name>soap-webapp Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.0.5.RELEASE</spring.version> <cxf.version>3.2.4</cxf.version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- CXF --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> <version>${cxf.version}</version> </dependency> </dependencies> <build> <finalName>soap-webapp</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <charset>${project.build.sourceEncoding}</charset> <server>tomcat7</server> </configuration> </plugin> </plugins> </build> </project>
b、编写接口和实现类
package org.moy.soap.service; import javax.jws.WebService; /** * say something * * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ @WebService public interface HelloService { String say(String name , String word); }
package org.moy.soap.service; import org.springframework.stereotype.Component; import javax.jws.WebService; /** * say something * * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ @WebService @Component public class HelloServiceImpl implements HelloService{ @Override public String say(String name, String word) { return String.format("%s : %s" , name ,word); } }
c、配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- CXF --> <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping> </web-app>
d、配置spring.xml和spring-cxf.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="org.moy"/> <import resource="spring-cxf.xml"/> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:endpoint id="helloService" implementor="#helloServiceImpl" address="/soap/hello" /> </beans>
e、编写调用webservice工具类SoapUtils
package org.moy.soap.utils; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.endpoint.dynamic.DynamicClientFactory; import org.apache.cxf.service.model.BindingInfo; import org.apache.cxf.service.model.BindingOperationInfo; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import javax.xml.namespace.QName; import java.util.Objects; /** * say something * * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ public class SoapUtils { private static DynamicClientFactory factory = DynamicClientFactory.newInstance(); private static long DEFAULT_TIMEOUT = 3 * 60 * 1000; /** * 执行远程服务方法 * * @param wsdl wsdl地址 * @param method 远程服务方法名 * @param params 远程服务方法名 * @return 返回值 * @throws Exception 调用异常 */ public static Object invoke(String wsdl, String method, Object... params) throws Exception { return invoke(wsdl, method, DEFAULT_TIMEOUT, params); } /** * 执行远程服务方法 * * @param wsdl wsdl地址 * @param method 远程服务方法名 * @param timeout 等待时间 * @param params 远程服务方法名 * @return 返回值 * @throws Exception 调用异常 */ public static Object invoke(String wsdl, String method, long timeout, Object... params) throws Exception { Client client = createClient(wsdl, timeout); return invokeByClient(client, method, params); } /** * 执行远程服务方法 * * @param client org.apache.cxf.endpoint.Client * @param method 远程服务方法名 * @param params 参数 * @return 返回值 * @throws Exception 调用异常 */ public static Object invokeByClient(Client client, String method, Object... params) throws Exception { QName operateQName = getOperateQName(client, method); Object[] result = client.invoke(operateQName, params); return result[0]; } /** * 创建客户端 * * @param wsdl wsdl地址 * @return 客户端 */ public static Client createClient(String wsdl) { return createClient(wsdl, DEFAULT_TIMEOUT); } /** * 创建客户端 * * @param wsdl wsdl地址 * @param timeout 请求等待时间 * @return org.apache.cxf.endpoint.Client */ public static Client createClient(String wsdl, long timeout) { validateWsdl(wsdl); Client client = factory.createClient(wsdl); setHttpConduit(client, timeout); return client; } private static void setHttpConduit(Client client, long timeout) { HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = createHttpClientPolicy(timeout); conduit.setClient(policy); } private static HTTPClientPolicy createHttpClientPolicy(long timeout) { HTTPClientPolicy policy = new HTTPClientPolicy(); policy.setAllowChunking(Boolean.FALSE); policy.setConnectionTimeout(timeout); policy.setReceiveTimeout(timeout); return policy; } /** * 校验wsdl合法性 * * @param wsdl wsdl地址 */ private static void validateWsdl(String wsdl) { if (Objects.isNull(wsdl) || wsdl.length() < 5) { throw new IllegalArgumentException(String.format("[%s]所对应的webService地址不合法!", wsdl)); } } /** * 针对SEI和SIB不在统一个包内的情况, * 先查找操作对应的QName,client通过QName调用对应操作 * * @param client 客户端 * @param operation 方法名 * @return QName */ private static QName getOperateQName(Client client, String operation) { Endpoint endpoint = client.getEndpoint(); String namespaceURI = endpoint.getService().getName().getNamespaceURI(); QName opName = new QName(namespaceURI, operation); BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding(); BindingOperationInfo bindingInfoOperation = bindingInfo.getOperation(opName); if (Objects.isNull(bindingInfoOperation)) { for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) { if (operation.equals(operationInfo.getName().getLocalPart())) { opName = operationInfo.getName(); break; } } } return opName; } }
f、使用maven运行tomcat7插件编写测试类App
package org.moy.soap.service; import org.moy.soap.utils.SoapUtils; /** * say something * * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a> * @since 1.0.0 */ public class App { public static void main(String[] args) throws Exception { String address = "http://localhost:8080/soap-webapp/ws/soap/hello?wsdl"; Object result = SoapUtils.invoke(address, "say", "moy", "hi"); System.out.println(result); } }
三、总结
新的项目基本很少会用webservice了,还是记录一下,免得以后忘了。
yexiangyang
moyyexy@gmail.com