最近,笔者简单的学习了下cxf webservice,发现与.net的WCF还是有点相似的。java里面能够提供webservice服务的不只这一种,其它的笔者也会慢慢去学习。
cxf webservice的官网地址是http://cxf.apache.org/index.html,下面使用官网的话来介绍下:
Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。它允许创建高性能和可扩展的服务,您可以将这样的服务部署在 Tomcat 和基于 Spring 的轻量级容器中,以及部署在更高级的服务器上,例如 Jboss、IBM® WebSphere® 或 BEA WebLogic。
接下来,笔者将在之前的SpringMVC项目中创建一个cxf webservice 接口,并集成在spring中。然后,将此项目部署在服务器上,利用cxf工具生成model和接口,在本地项目中创建客户端访问webservice接口。
pom.xml:
<!-- cxf webservice -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.1</version>
</dependency>
CustomerService接口类:
package com.qiyongkang.ws.service;
import javax.jws.WebParam;
import javax.jws.WebService;
import com.qiyongkang.sys.model.User;
/** * ClassName:CustomerService <br/> * Function: 客户接口. <br/> * Date: 2015年12月9日 下午3:37:07 <br/> * @author qiyongkang * @version * @since JDK 1.6 * @see */
@WebService
public interface CustomerService {
public User getUserById(@WebParam(name="id")long id);
public long getUserCount(User user);
}
CustomerServiceImpl实现类:
package com.qiyongkang.ws.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import com.qiyongkang.sys.dao.UserMapper;
import com.qiyongkang.sys.model.User;
import com.qiyongkang.ws.service.CustomerService;
/** * ClassName:CustomerServiceImpl <br/> * Function: 实现类. <br/> * Date: 2015年12月9日 下午3:40:23 <br/> * @author qiyongkang * @version * @since JDK 1.6 * @see */
public class CustomerServiceImpl implements CustomerService{
@Autowired
private UserMapper userMapper;
@Override
public User getUserById(long id) {
return userMapper.getUserById(id);
}
@Override
public long getUserCount(User user) {
return userMapper.count(user);
}
}
在source folder下新建一个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: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="customerService" implementor="com.qiyongkang.ws.service.impl.CustomerServiceImpl" address="/customerService" />
<bean id="client" class="com.qiyongkang.ws.service.CustomerService" factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.qiyongkang.ws.service.CustomerService" />
<property name="address" value="http://172.31.26.156:8080/qyk_testSpringMVC/webservice/customerService" />
</bean>
</beans>
注意这里的client bean只是为了本地测试用。
web.xml中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:spring-cxf.xml
</param-value>
</context-param>
<!-- log4j2-begin -->
<!-- <listener> <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> </listener> <filter> <filter-name>log4jServletFilter</filter-name> <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class> </filter> <filter-mapping> <filter-name>log4jServletFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> -->
<!-- log4j2-end -->
<!-- 字符编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 这是一个过滤器代理,所有过滤器将由spring容器进行管理 -->
<!-- <filter> <filter-name>filterProxy</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetBeanName</param-name> <param-value>authorizationFilterChainProxy</param-value> </init-param> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>filterProxy</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> -->
<!-- spring配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springMvc配置 -->
<servlet>
<servlet-name>mvc-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- cxf webservice servlet -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXFServlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
</web-app>
然后笔者将此项目部署在172.31.26.200这台服务器上并启动tomcat,然后访问:http://172.31.26.200:8080/qyk_testSpringMVC/webservice/customerService?wsdl,便会看到此接口的webservice描述,如下图:
现在,webservice服务接口已经有了,接下来就是要创建客户端进行调用了。假设,服务端和客服端是不同的两个人写的,那么编写客户端的人怎么知道此接口怎么使用呢,接口类怎么写?参数和返回值是什么类型的?为了省去这些麻烦,我们可以使用wsdl2java工具类生成契约,也就是model和接口。在命令行运行:wsdl2java -p com.qiyongkang.cxf.contract -d D:\apache-cxf-3.1.1\generate -all http://172.31.26.200:8080/qyk_testSpringMVC/webservice/customerService?wsdl,生成的内容如下图:
这里,其实我们只需要model和接口类就够了。
创建客户端类CustomerServiceClient.java:
package com.qiyongkang.cxf.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.qiyongkang.cxf.contract.CustomerService;
import com.qiyongkang.cxf.contract.User;
/** * ClassName:CustomerServiceClient <br/> * Function: 客户端. <br/> * Date: 2015年12月9日 下午4:12:38 <br/> * @author qiyongkang * @version * @since JDK 1.6 * @see */
public class CustomerServiceClient {
public static void main(String[] args) {
JaxWsProxyFactoryBean svr = new JaxWsProxyFactoryBean();
svr.setServiceClass(CustomerService.class);
svr.setAddress("http://172.31.26.200:8080/qyk_testSpringMVC/webservice/customerService?wsdl");
CustomerService customerService = (CustomerService) svr.create();
User user = null;
user = customerService.getUserById(55);
System.out.println(user.getUserName() + "==" + user.getAge());
User newUser = new User();
newUser.setUserName("111");
long count = customerService.getUserCount(newUser);
System.out.println("查询出的个数为:" + count);
}
}
运行后,结果如下图:
说明调用cxf webservice接口成功啦。
就讲到这里了,其实关于cxf webservice还有很多需要学习的,比如参数、返回的类型、异常的处理等等,笔者也是刚学,就做一个简单的介绍,有些地方写得有问题的欢迎指出,谢谢!