在开发过程中,大多数情况下,我们都是基于spring框架进行开发的,现在我们就来学习一下,用CXF编写基于spring的web service。
server端编码
1、创建spring的配置文件beans.xml,在其中配置SEI
2、在web.xml中,配置CXF的一些核心组件
服务端案例:
实体类
package bean;
public class Order {
private int id;
private String name;
private double price;
public Order(int id, String name, double price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
发布的接口
package spring;
import javax.jws.WebMethod;
import javax.jws.WebService;
import bean.Order;
@WebService
public interface OrderWS {
@WebMethod
public Order getOrderById(int id);
}
接口的实现类
package spring;
import bean.Order;
public class OrderWSImpl implements OrderWS {
public OrderWSImpl(){
System.out.println("OrderWSImpl class 。。。。。");
}
@Override
public Order getOrderById(int id) {
System.out.println("server getOrde4rById() " + id);
return new Order(id,"feiji",100000);
}
}
spring 的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/jaxws">
<!-- 引入cxf的一些核心配置 -->
<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" />
<!--配置终端 -->
<jaxws:endpoint
id="orderWS"
implementor="spring.OrderWSImpl"
address="/orderws">
<!-- <jaxws:inInterceptors>
<bean class="com.atguigu.day01_ws.interceptor.CheckUserInterceptor"></bean>
</jaxws:inInterceptors> -->
</jaxws:endpoint>
</beans>
web.xml的配置
<?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>day02_ws_cxf_spring</display-name>
<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>
<!-- 配置beans.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<!--
应用启动的一个监听器
-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!--
所有请求都会先经过cxf框架
-->
<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>/*</url-pattern>
</servlet-mapping>
</web-app>
启动项目范问http://localhost:8080/wx-cxf-server-spring/orderws?wsdl就可以访问该接口返回的wsdl文档
client端编码
1、生成客户端代码
2、创建客户端的spring 配置文件beans-client.xml,并配置
3、编写测试类请求web service
在客户端项目的src目录下,执行命令:wsdl2java http://localhost:8080/wx-cxf-server-spring/orderws?wsdl
生成客户端代码。
创建spring的client-beans.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/jaxws">
<!-- serverClass :service的接口路径
address: web service接口的地址
-->
<jaxws:client id="orderClient" serviceClass="spring.OrderWS"
address="http://localhost:8080/wx-cxf-server-spring/orderws"/>
</beans>
客户端接口的测试
package test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.Order;
import spring.OrderWS;
public class ClientTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"client-beans.xml"});
OrderWS client = (OrderWS)context.getBean("orderClient");
Order order = client.getOrderById(24);
System.out.println(order);
}
}
启动main方法,这个时候客户端代码和服务端代码都会有输出。
基于spring的web service的自定义拦截器
1、 server端:
- 在beans.xml中,在endpoint中配置上入拦截器。
服务端检查用户拦截器示例:
package interceptor;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* 检查用户的拦截器
* @author Administrator
*
*/
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
public CheckUserInterceptor(){
super(Phase.PRE_PROTOCOL);
System.out.println("CheckUserInterceptor().......");
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
Header header = message.getHeader(new QName("atguigu"));
if(header != null){
Element atguigu = (Element)header.getObject();
String name = atguigu.getElementsByTagName("name").item(0).getTextContent();
Node node = atguigu.getElementsByTagName("password").item(0);
String password = node.getTextContent();
if("xfzhang".equals(name) && "123456".equals(password)){
System.out.println("server 通过拦截器。。。。。");
return ;
}
}
//不能通过
System.out.println("server 没有通过拦截器.... ");
throw new Fault(new RuntimeException("请求需要一个正确的用户名密码!"));
}
}
在服务端的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/jaxws">
<!-- 引入cxf的一些核心配置 -->
<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" />
<!--配置终端 -->
<jaxws:endpoint
id="orderWS"
implementor="spring.OrderWSImpl"
address="/orderws">
<!-- 添加拦截器-->
<jaxws:inInterceptors>
<bean class="com.atguigu.day01_ws.interceptor.CheckUserInterceptor"></bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
</beans>
2、Client端
客户端的添加用户拦截器:
public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
private String name;
private String password;
public AddUserInterceptor(String name, String password) {
super(Phase.PRE_PROTOCOL);//准备协议化时拦截
this.name = name;
this.password = password;
System.out.println("AddUserInterceptor()....");
}
/*
<Envelope>
<head>
<atguigu>
<name>xfzhang</name>
<password>123456</password>
</atguigu>
<atguigu2>
<name>xfzhang</name>
<password>123456</password>
</atguigu2>
<head>
<Body>
<sayHello>
<arg0>BOB</arg0>
<sayHello>
</Body>
</Envelope>
*/
@SuppressWarnings("deprecation")
@Override
public void handleMessage(SoapMessage msg) throws Fault {
List<Header> headers = msg.getHeaders();
/*
<atguigu>
<name>xfzhang</name>
<password>123456</password>
</atguigu>
*/
Document document = DOMHelper.createDocument();
Element rootEle = document.createElement("atguigu");
Element nameELe = document.createElement("name");
nameELe.setTextContent(name);
rootEle.appendChild(nameELe);
Element passwordELe = document.createElement("password");
passwordELe.setTextContent(password);
rootEle.appendChild(passwordELe);
headers.add(new Header(new QName("atguigu"), rootEle));
System.out.println("client handleMessage()....");
}
}
在客户端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/jaxws">
<jaxws:client id="orderClient"
serviceClass= "spring.OrderWS"
address= "http://localhost:8080/wx-cxf-server-spring/orderws">
<!-- 拦截器-->
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<bean class="client.interceptor.AddUserInterceptor">
<constructor-arg name="name" value="xfzhang"/>
<constructor-arg name="password" value="123456"/>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
</beans>