记录一下webservice的cxf框架的简单实用。
Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。
开发前还是要解决jar问题,这次实例使用的maven管理jar,所以贴上pom配置
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- spring版本号 -->
<spring.version>4.0.2.RELEASE</spring.version>
<!-- mybatis版本号 -->
<mybatis.version>3.2.6</mybatis.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
<!--shiro版本号-->
<shiro.version>1.3.2</shiro.version>
<!--cxf-->
<cxf.version>2.2.3</cxf.version>
</properties>
<dependencies>
<!--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>
</dependencies>
首先,我们根据cxf的规范使用注解建造出需要用的service文件
接口:
package cn.com.trueway.demo.service;
import cn.com.trueway.demo.entity.DefaultBean;
import cn.com.trueway.demo.entity.DemoPojo;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* Created by wdq on 2019/1/21.
*/
@WebService(targetNamespace="http://localhost/service/webServiceImpl/")
public interface IWebService {
/**
* 插入
* @param demoPojo
*/
@WebMethod
public void insert(@WebParam(name="demoPojo")DemoPojo demoPojo);
/**
* 列表查询(cxf不能直接传递list,所以只能把list封装到一个单独类中)
* @return
*/
@WebMethod
public DefaultBean getResultList();
}
注解WebService的targetNamespace字段代表的是当前service的暴露地址(也就是访问地址),同时方法的参数也需要使用注解Webparam声明,否则会出现接收不到参数的情况。
实现类:
package cn.com.trueway.demo.service.impl;
import cn.com.trueway.demo.dao.DemoDao;
import cn.com.trueway.demo.entity.DefaultBean;
import cn.com.trueway.demo.entity.DemoPojo;
import cn.com.trueway.demo.service.IWebService;
import javax.annotation.Resource;
/**
* Created by wdq on 2019/1/21.
*/
@javax.jws.WebService
public class WebService implements IWebService {
@Resource
DemoDao demoDao;
@Override
public void insert(DemoPojo demoPojo) {
//模拟插入操作
demoDao.insertDemo(demoPojo);
}
@Override
public DefaultBean getResultList() {
//模拟查询操作,并将结果集放入封装类中
DefaultBean bean = new DefaultBean();
bean.setDfBeanList(demoDao.selectAll());
return bean;
}
}
在service实现类中,我们唯一需要注意的就是dao层注入的时候使用的是@Resource根据bean名称注入而不是@Autowired。
defaultBean代码:
package cn.com.trueway.demo.entity;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
/**
* webservice传递map,list参数及返回值
* @author wdq
*
*/
@XmlRootElement
public class DefaultBean implements Serializable{
private static final long serialVersionUID = 1L;
private List<DemoPojo> dfBeanList;
private List<Object[]> dfObjectList;
private Map<String, Object> dfMap;
public List<DemoPojo> getDfBeanList() {
return dfBeanList;
}
public void setDfBeanList(List<DemoPojo> dfBeanList) {
this.dfBeanList = dfBeanList;
}
public List<Object[]> getDfObjectList() {
return dfObjectList;
}
public Map<String, Object> getDfMap() {
return dfMap;
}
public void setDfObjectList(List<Object[]> dfObjectList) {
this.dfObjectList = dfObjectList;
}
public void setDfMap(Map<String, Object> dfMap) {
this.dfMap = dfMap;
}
}
肯定有人好奇DefaultBean是个什么鬼,这个也是博主自己踩过的坑,在cxf中,返回值和参数是不支持不能序列化对象的,而list、map等这些接口是不能直接返回的,所以我们需要使用一个自己的封装类把他们再封装一遍。
配置好java代码后就需要整合spring了,新建一个spring-webservice.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 这三个文件在cxf.jar中 -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!--=============== 实现类的bean,需要spring注入 ============================ -->
<!-- 身份校验拦截器 -->
<!--<bean id="qdzwAuthInterceptor"
class="cn.com.trueway.mob.webservice.AuthInterceptor" />-->
<jaxws:server id="webService" serviceClass="cn.com.trueway.demo.service.impl.WebService"
address="/webServiceImpl">
<!--<jaxws:inInterceptors>
<ref bean="qdzwAuthInterceptor" />
</jaxws:inInterceptors>-->
</jaxws:server>
</beans>
jaxws:server代表cxf中的服务端,serviceClass填写的是刚刚写好的service实现类地址,address中填写的是暴露地址,同service接口中注解的targetNamespace字段。最后还要再web.xml中配置一下接口拦截规则:
<!-- cxf -->
<servlet>
<servlet-name>CXFServletQdzw</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServletQdzw</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
配置了拦截规则为/service/*也就代表着你如果要访问接口的话项目名偶就要附带上这个service才能访问到,注意,service中的暴露地址中也要考虑这个拦截前缀。
都配置完以后访问一下接口地址试试,
这样就表示服务暴露成功,这样我们的服务端就ok啦,客户端的话有了这个接口地址就可以让工具自动生成了,详细使用请参考webservice生成cxf客户端代码