CXF是一个开源的webService框架,提供了很多功能,可以实现快速开发。
CXF支持的协议 SOAP1.1/SOAP1.2 REST
CXF支持的数据格式xml,json
一:CXF的安装:
http://cxf.apache.org/download.html
二:包结构
1.安装jdk
2.配置cxf的环境变量
在CLASSPATH中添加 D:\apache-cxf-2.5.2\lib
新建CXF_HOME D:\apache-cxf-2.5.2
在PATH中添加 D:\apache-cxf-2.5.2\bin
测试,在cmd下加入wsdl2java–h
参照如上所示的例子配置CXF这样CXF就可以适用了,与webservice一样的道理,可以用cxf来创建服务或是客户端程序。@WebService
publicinterface WeatherInterface {
public String queryWeather(String cityName);
}
publicclass WeatherInterfaceImpl implements WeatherInterface {
@Override
public String queryWeather(String cityName) {
System.out.println("from client..."+cityName);
if("北京".equals(cityName)){
return"冷且霾";
} else {
return"暖且晴";
}
}
}
publicclass WeatherServer {
publicstaticvoid main(String[] args) {
//JaxWsServerFactoryBean发布服务
JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
//设置服务接口
jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class);
//设置服务实现类
jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl());
//设置服务地址
jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/weather");
//发布
jaxWsServerFactoryBean.create();
}
}
直接访问适用说明书,就可以确定是否发布成功了。
服务端加上如下所示的注解,就可以发布SOAP1.2的服务了。
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
如下图所示是定义的拦截器
如上图所示是拦截器,在发布服务的前后都可以,设置拦截器。
Ø 拦截器可以拦截请求和响应
Ø 拦截器可以有多个
Ø 拦截器可以根据需要自定义
可以定义多个拦截器,放入拦截器列表中
二 生成客户端代码
Wsdl2java命令是CXF提供的生成客户端的工具,他和wsimport类似,可以根据WSDL生成客户端代码
Wsdl2java常用参数:
-d,指定输出目录
-p,指定包名,如果不指定该参数,默认包名是WSDL的命名空间的倒序
Wsdl2java支持SOAP1.1和SOAP1.2
//JaxWsProxyFactoryBean调用服务端
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
//设置服务接口
jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class);
//设置服务地址jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:12345/weather");
//获取服务接口实例
WeatherInterface weatherInterface = jaxWsProxyFactoryBean.create(WeatherInterface.class);
//调用查询方法
String weather = weatherInterface.queryWeather("保定");
System.out.println(weather);
}
接下来介绍如何在实际的开发中整合发布SOAP协议
第一步:在spring文件中进行配置。
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<!-- <jaxws:server发布SOAP协议的服务,对JaxWsServerFactoryBean类封装-->
<jaxws:serveraddress="/weather"serviceClass="cn.itcast.ws.cxf.server.WeatherInterface">
<jaxws:serviceBean>
<refbean="weatherInterface"/>
</jaxws:serviceBean>
</jaxws:server>
<!-- 配置服务实现类 -->
<beanname="weatherInterface"class="cn.itcast.ws.cxf.server.WeatherInterfaceImpl"/>
</beans>
配置CXF的servlet
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appxmlns: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_3_0.xsd"id="WebApp_ID"version="3.0">
<display-name>ws_2_cxf_spring_server</display-name>
<!-- 设置spring的环境 -->
<context-param>
<!--contextConfigLocation是不能修改的 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置CXF的Servlet -->
<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>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
如上所示是web.xml的配置文件,里面有servlet的映射路径
WSDL地址规则:http://ip:端口号/项目名称/servlet拦截路径/服务名称?wsdl
如上所示配置了webservice的服务,启动服务以后,访问wsdl的路径就变成了
如上所示的地址。
CXF配置客户端:
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrshttp://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/corehttp://cxf.apache.org/schemas/core.xsd">
<!-- <jaxws:client实现客户端,对JaxWsProxyFactoryBean类封装-->
<jaxws:clientid="weatherClient"address="http://127.0.0.1:8080/ws_2_cxf_spring_server/ws/weather"serviceClass="cn.itcast.cxf.weather.WeatherInterface"/>
</beans>
如上所示,配置了client以后,就可以通过注入的方式
,把weatherClient注入到服务的实现类里面,为view层提供数据接口。
CXF发布Rest服务:
l REST就是一种编程风格,它可以精确定位网上资源(服务接口、方法、参数)
l REST支持数据格式:XML、JSON
l REST支持发送方式:GET,POST
如下所示为Student类加上@XmlRootElemnt就可以实现,response数据的json与xml格式的转换
@XmlRootElement(name="student")//@XmlRootElement可以实现对象和XML数据之间的转换
public class Student {
privatelongid;
private String name;
private Date birthday;
publiclong getId() {
returnid;
}
publicvoid setId(longid) {
this.id = id;
}
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
public Date getBirthday() {
returnbirthday;
}
publicvoid setBirthday(Date birthday) {
this.birthday = birthday;
}
}
如下所示是即将发布的rest服务通过@Path @pathParam 就可以把地址映射转换为/student/query/{xxx}的方式了。
@WebService
@Path("/student")//@Path("/student")就是将请求路径中的“/student”映射到接口上
publicinterface StudentInterface {
//查询单个学生
@GET//指定请求方式,如果服务端发布的时候指定的是GET(POST),那么客户端访问时必须使用GET(POST)
@Produces(MediaType.APPLICATION_XML)//指定服务数据类型
@Path("/query/{id}")//@Path("/query/{id}")就是将“/query”映射到方法上,“{id}”映射到参数上,多个参数,以“/”隔开,放到“{}”中
public Student query(@PathParam("id")longid);
//查询多个学生
@GET//指定请求方式,如果服务端发布的时候指定的是GET(POST),那么客户端访问时必须使用GET(POST)
@Produces(MediaType.APPLICATION_XML)//指定服务数据类型
@Path("/queryList/{name}")//@Path("/queryList/{name}")就是将“/queryList”映射到方法上,“{name}”映射到参数上,多个参数,以“/”隔开,放到“{}”
public List<Student> queryList(@PathParam("name")String name);
}
发布一个服务:
//JAXRSServerFactoryBean发布REST的服务
JAXRSServerFactoryBean jaxRSServerFactoryBean = new JAXRSServerFactoryBean();
//设置服务实现类
jaxRSServerFactoryBean.setServiceBean(new StudentInterfaceImpl());
//设置资源类,如果有多个资源类,可以以“,”隔开。
jaxRSServerFactoryBean.setResourceClasses(StudentInterfaceImpl.class);
//设置服务地址
jaxRSServerFactoryBean.setAddress("http://127.0.0.1:12345/user");
//发布服务
jaxRSServerFactoryBean.create();
}
如下是服务查询的结果:
客户端:如下所示是客户端调用程序
public class HttpClient {
public static void main(String[] args) throws IOException {
//第一步:创建服务地址,不是WSDL地址
URL url = new URL("http://127.0.0.1:12345/user/student/query/110");
//第二步:打开一个通向服务地址的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//第三步:设置参数
//3.1发送方式设置:POST必须大写
connection.setRequestMethod("POST");
//3.2设置数据格式:content-type
//3.3设置输入输出,因为默认新创建的connection没有读写权限,
connection.setDoInput(true);
//第五步:接收服务端响应,打印
int responseCode = connection.getResponseCode();
if(200 == responseCode){//表示服务端响应成功
InputStream is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String temp = null;
while(null != (temp = br.readLine())){
sb.append(temp);
}
System.out.println(sb.toString());
//dom4j解析返回数据,课下作业
is.close();
isr.close();
br.close();
}
}
}