• 爲何設計攔截器?html
1. 爲了在webservice請求過程當中,能動態操做請求和響應數據, CXF設計了攔截器.java
• 攔截器分類:web
2. 按所處的位置分:服務器端攔截器,客戶端攔截器spring
3. 按消息的方向分:入攔截器,出攔截器apache
4. 按定義者分:系統攔截器,自定義攔截器服務器
如下是服務器代碼實例:app
import javax.jws.WebMethod;框架
import javax.jws.WebService;dom
import com.atguigu.day02_ws_cxf_spring.bean.Order;jsp
public interface OrderWS {
@WebMethod
public Order getOrderById(int id);
}
import javax.jws.WebService;
import com.atguigu.day02_ws_cxf_spring.bean.Order;
public class OrderWSImpl implements OrderWS {
public OrderWSImpl() {
System.out.println("OrderWSImpl()");
}
@Override
public Order getOrderById(int id) {
System.out.println("server getOrderById(int id)"+id);
return new Order(id, "寶馬", 10000000);
}
}
import java.util.List;
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;
/**
* 查檢用戶的攔截器
* @author Administrator
*
*/
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
public CheckUserInterceptor() {
super(Phase.PRE_PROTOCOL);
System.out.println("CheckUserInterceptor()");
}
/*
<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>
*/
@Override
public void handleMessage(SoapMessage message) throws Fault {
Header header = message.getHeader(new QName("atguigu"));
if(header!=null) {
Element atguiguEle = (Element) header.getObject();
String name = atguiguEle.getElementsByTagName("name").item(0).getTextContent();
String password = atguiguEle.getElementsByTagName("password").item(0).getTextContent();
if("xfzhang".equals(name) && "123456".equals(password)) {
System.out.println("Server 經過攔截器....");
return;
}
}
//不能經過
System.out.println("Server 沒有經過攔截器....");
throw new Fault(new RuntimeException("請求須要一個正確的用戶名和密碼!"));
}
}
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">
<!-- 引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" />
<!-- implementor 實現類的全類名 id address 自定義
jaxws:inInterceptors 入攔截器
bean 配置自定義的入攔截器 全類名-->
<jaxws:endpoint
id="orderWS"
implementor="com.atguigu.day02_ws_cxf_spring.ws.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>
如下是客戶端代碼實例:
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">
<!--1.首先生成客戶端的wsdl路徑下的代碼 找到代理對象
2.serviceClass 配置動態產生接口的代理對象的全類名
3. 服務器端的地址 http://localhost/day02_ws_cxf_spring/orderws 項目名稱+暴露的 address="/orderws"組合地址-->
<jaxws:client id="orderClient"
serviceClass= "com.atguigu.day02_ws_cxf_spring.ws.OrderWS"
address= "http://localhost:8080/day02_ws_cxf_spring/orderws">
<!--jaxws:inInterceptors 出攔截器 bean 配置自定義的出攔截器 全類名-->
<jaxws:outInterceptors>
<!-- <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> -->
<bean class="com.atguigu.day01_ws_cxf_client.interceptor.AddUserInterceptor">
<constructor-arg name="name" value="xfzhang"/>
<constructor-arg name="password" value="1234567"/>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
</beans>
import java.util.List;
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.apache.xml.utils.DOMHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* 建立用戶攔截器
* @author Administrator
*
*/
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;
}
/*
<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()....");
}
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.atguigu.day02_ws_cxf_spring.ws.Order;
import com.atguigu.day02_ws_cxf_spring.ws.OrderWS;
public class ClientTest {
public static void main(String[] args) {
//client-beans.xml 配置在當前項目下的src目錄下 直接引用
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
OrderWS orderWS = (OrderWS) context.getBean("orderClient");//經過配置的id來配置要一致
Order order = orderWS.getOrderById(24);//代理對象回調方法請求數據
System.out.println(order);
}
wsdl生成的bean對象
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>order complex type的 Java 類。
*
* <p>如下模式片斷指定包含在此類中的預期內容。
*
* <pre>
* <complexType name="order">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}int"/>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="price" type="{http://www.w3.org/2001/XMLSchema}double"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "order", propOrder = {
"id",
"name",
"price"
})
public class Order {
protected int id;
protected String name;
protected double price;
/**
* 獲取id屬性的值。
*
*/
public int getId() {
return id;
}
/**
* 設置id屬性的值。
*
*/
public void setId(int value) {
this.id = value;
}
/**
* 獲取name屬性的值。
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}
/**
* 設置name屬性的值。
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}
/**
* 獲取price屬性的值。
*
*/
public double getPrice() {
return price;
}
/**
* 設置price屬性的值。
*
*/
public void setPrice(double value) {
this.price = value;
}
@Override
public String toString() {
return "Order [id=" + id + ", name=" + name + ", price=" + price + "]";
}
}
}