分布式架构探索 - 2. WebService RPC框架之Apache CXF
Apache CXF是一个开源的WebService RPC框架。
例子:
1. 新建一个maven web项目, 添加pom
如下:
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.genesis.architect</groupId> <artifactId>cxf-demo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <cxf.version>3.1.7</cxf.version> <spring.version>4.0.9.RELEASE</spring.version> <junit.version>4.12</junit.version> <jstl.version>1.2</jstl.version> <servlet-api.version>2.5</servlet-api.version> <jsp-api.version>2.0</jsp-api.version> </properties> <!-- pom.xml增加多环境配置的配置 --> <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <package.environment>development</package.environment> </properties> </profile> <profile> <id>pro</id> <properties> <package.environment>production</package.environment> </properties> </profile> <profile> <id>test</id> <properties> <package.environment>testing</package.environment> </properties> </profile> </profiles> <dependencies> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <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-transports-http-jetty</artifactId> <version>${cxf.version}</version> </dependency> <!-- servlet start --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>${jsp-api.version}</version> <scope>provided</scope> </dependency> <!-- servlet end --> </dependencies> <build> <finalName>cxf-demo</finalName> <resources> <resource> <directory>src/main/resources/${package.environment}</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.tld</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.tld</include> </includes> <filtering>false</filtering> </resource> </resources> <plugins> <!-- Jetty 服务器 --> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.2.v20140723</version> <configuration> <httpConnector> <port>8080</port> </httpConnector> <webAppConfig> <contextPath>/${project.artifactId}</contextPath> </webAppConfig> <scanIntervalSeconds>2</scanIntervalSeconds> </configuration> </plugin> <!-- tomcat 服务器 --> <!--<plugin>--> <!--<groupId>org.apache.tomcat.maven</groupId>--> <!--<artifactId>tomcat7-maven-plugin</artifactId>--> <!--<configuration>--> <!--<port>8080</port>--> <!--<path>/${project.artifactId}</path>--> <!--</configuration>--> <!--</plugin>--> <!--打war包到指定的目录下 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.8</version> <executions> <execution> <id>copy-war</id> <phase>package</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>${project.groupId}</groupId> <artifactId>${project.artifactId}</artifactId> <version>${project.version}</version> <type>${project.packaging}</type> </artifactItem> </artifactItems> <!-- <outputDirectory>${dist.console.war.dir}</outputDirectory> --> <!--指定war包保存地址 --> <outputDirectory>${basedir}/WAR/${package.environment}</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
2. 定义远程服务接口,并用@WebService标明是一个远程的WebService
package com.genesis.architect.cxf.service; import javax.jws.WebService; /** * @author KG created on 16/12/4 */ @WebService public interface HelloService { public String sayHello(String content); }
3. 远程服务的实现(通过endpointInterface指明对应的接口)
package com.genesis.architect.cxf.service; import javax.jws.WebService; /** * @author KG created on 16/12/4 */ @WebService(endpointInterface = "com.genesis.architect.cxf.service.HelloService") public class HelloServiceImpl implements HelloService { @Override public String sayHello(String content) { return "hello," + content; } }
4. 配置WebService的终结点实现,并配置地址映射
cxf-server.xml
<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.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <jaxws:endpoint id="helloWorld" implementor="com.genesis.architect.cxf.service.HelloServiceImpl" address="/HelloWorld"/> </beans>
5. web.xml配置WebService监听,添加ws路由映射
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>cxf-spring</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:cxf-server.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping> </web-app>
6. 编写客户端测试
package com.genesis.architect.cxf.client; import com.genesis.architect.cxf.service.HelloService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author KG created on 16/12/4 */ public class CxfClient { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:cxf-client.xml"); HelloService client = (HelloService) context.getBean("helloClient"); System.out.println(client.sayHello("Master HaKu")); } }
7. 客户端调用远程服务的配置文件(cxf-client.xml)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:client id="helloClient" serviceClass="com.genesis.architect.cxf.service.HelloService" address="http://localhost:8080/cxf-demo/ws/HelloWorld" /> </beans>
8. 运行结果
访问:
http://localhost:8080/cxf-demo/ws/HelloWorld?wsdl
可以看到soap的wsdl内容
运行client:
hello,Master HaKu
技术改变世界