使用cxf编写基于spring的web service


在开发过程中,大多数情况下,我们都是基于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方法,这个时候客户端代码和服务端代码都会有输出。

扫描二维码关注公众号,回复: 5369083 查看本文章

基于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>

猜你喜欢

转载自blog.csdn.net/taojin12/article/details/86581817