Apache CXF Spring SOAP Handler example

1. 環境說明

jdk 1.6.0-29

apache cxf 2.7.7

2. 新建web project,並添加apache cxf/lib目錄下所需jar,軟件目錄如下:

3. 程序代碼

Book.java

package com.unei.bean;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Book")
public class Book {
	private int bookId;
	private String bookISBNnumber;
	private String bookName;
	private double price;
	private String author;

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public int getBookId() {
		return bookId;
	}

	public void setBookId(int bookId) {
		this.bookId = bookId;
	}

	public String getBookISBNnumber() {
		return bookISBNnumber;
	}

	public void setBookISBNnumber(String bookISBNnumber) {
		this.bookISBNnumber = bookISBNnumber;
	}

	public String getBookName() {
		return bookName;
	}

	public void setBookName(String bookName) {
		this.bookName = bookName;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}
}

IBookService.java

package com.unei.service;

import javax.jws.WebMethod;
import javax.jws.WebService;

import com.unei.bean.Book;

@WebService
public interface IBookService {
	@WebMethod
	public void addBook(Book book);
	@WebMethod
	public void deleteBook(int bookId);
	@WebMethod
	public void updateBook(Book book);
	@WebMethod
	public Book getBook(int bookId);
}
BookService.java

package com.unei.service.impl;

import com.unei.bean.Book;
import com.unei.service.IBookService;

public class BookService implements IBookService{

	@Override
	public void addBook(Book book) {
		System.out.println("addBook:"+book.getBookName());
	}

	@Override
	public void deleteBook(int bookId) {
		System.out.println("deleteBook:"+bookId);
	}

	@Override
	public void updateBook(Book book) {
		System.out.println("updateBook:"+book.getBookName());
	}

	@Override
	public Book getBook(int bookId) {
		Book book=new Book();
		book.setBookId(4);
		book.setBookName("getBook");
		book.setBookISBNnumber("ABCDEFG");
		book.setPrice(20.00);
		return book;
	}

}
CheckHandler.java

package com.unei.handler;

import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;


public class CheckHandler implements SOAPHandler<SOAPMessageContext>{
	
	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		System.out.println("Server:handleMessage....");
		Boolean isResponse=(Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
		if(!isResponse){
			System.out.println("request....");
			
			try {
				SOAPMessage soapMsg=context.getMessage();
				SOAPEnvelope soapEnv=soapMsg.getSOAPPart().getEnvelope();
				SOAPHeader soapHeader=soapEnv.getHeader();
				//if no header,add one,throw exception
				if(soapHeader==null){
					soapHeader=soapEnv.addHeader();
					generateSoapErrMessage(soapMsg, "No SOAP header.");
				}
				
				//Get 
				Iterator it=soapHeader.extractHeaderElements(SOAPConstants.URI_SOAP_ACTOR_NEXT);
				
				if(it==null||!it.hasNext()){
					generateSoapErrMessage(soapMsg, "No header block for next");
				}
				
				Node a=(Node)it.next();
				System.out.println(a.getValue());
				
			} catch (SOAPException e) {
				e.printStackTrace();
			}
		}else{
			System.out.println("response....");
		}
		return true;
	}

	@Override
	public boolean handleFault(SOAPMessageContext context) {
		return false;
	}

	@Override
	public void close(MessageContext context) {
		
	}

	@Override
	public Set<QName> getHeaders() {
		return null;
	}
	
	private void generateSoapErrMessage(SOAPMessage msg,String reason){
		try {
			SOAPBody soapBody=msg.getSOAPPart().getEnvelope().getBody();
			SOAPFault soapFault=soapBody.addFault();
			soapFault.setFaultString(reason);
			throw new SOAPFaultException(soapFault);
		} catch (SOAPException e) {
			e.printStackTrace();
		}
		
	}
}

web.xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">
	<!-- 指明spring配置文件在何處 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:applicationContext.xml</param-value>
	</context-param>
	<!-- 加載spring配置文件applicationContext.xml -->
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	<servlet>
		<servlet-name>cxf</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>cxf</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>

</web-app>

applicationContext.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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-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
    ">

	<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.xml" />
	<aop:aspectj-autoproxy proxy-target-class="true" />
	<bean id="bsServiceBean" class="com.unei.service.impl.BookService" />
	<bean id="inLog" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	<bean id="outLog" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>

	<jaxws:server id="bookService" serviceClass="com.unei.service.IBookService" address="/bs">
		<jaxws:serviceBean>
			<ref bean="bsServiceBean" />
		</jaxws:serviceBean>

		  
		<jaxws:inInterceptors>
			<ref bean="inLog" />
		</jaxws:inInterceptors>
		
		<jaxws:outInterceptors>
			<ref bean="outLog"/>
		</jaxws:outInterceptors>
		
		<jaxws:handlers>
			<bean class="com.unei.handler.CheckHandler"/>
		</jaxws:handlers>
	</jaxws:server>
</beans>
在<jaxws:server>標籤中添加<jaxws:handlers>標籤,聲明handler


4. 客戶端,新建java project,添加apache cxf/lib目錄下所需jar,項目結構如下

5. 項目代碼

CheckHandler.java

package com.unei.handler;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class CheckHandler implements SOAPHandler<SOAPMessageContext>{

	@Override
	public void close(MessageContext arg0) {
		
	}

	@Override
	public boolean handleFault(SOAPMessageContext arg0) {
		return false;
	}

	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		Boolean isRequest=(Boolean)context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY);
		
		if(isRequest){
			System.out.println("request...");
			SOAPMessage soapMsg=context.getMessage();
			SOAPEnvelope soapEnv;
			try {
				soapEnv = soapMsg.getSOAPPart().getEnvelope();
				SOAPHeader soapHeader=soapEnv.getHeader();
				
				if(soapHeader==null){
					soapHeader=soapEnv.addHeader();
				}
				
				String mac=getMACAddress();
				
				QName qname=new QName("http://localhost","macAddress");
				SOAPHeaderElement soapHeaderElement=soapHeader.addHeaderElement(qname);
				
				soapHeaderElement.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT);
				soapHeaderElement.addTextNode(mac);
				soapMsg.saveChanges();
				
				soapMsg.writeTo(System.out);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}else{
			System.out.println("response...");
		}
		return true;
	}

	@Override
	public Set<QName> getHeaders() {
		return null;
	}

	private String getMACAddress() throws Exception{
		InetAddress ip;
		StringBuilder sb=new StringBuilder();
		ip=InetAddress.getLocalHost();
		System.out.println("Current IP address:"+ip.getHostAddress());
		NetworkInterface network=NetworkInterface.getByInetAddress(ip);
		byte[] mac=network.getHardwareAddress();
		System.out.println("Current MAC address:");
		for(int i=0;i<mac.length;i++){
			sb.append(String.format("%02X%s",mac[i],(i<mac.length-1)?"-":""));
		}
		
		System.out.println(sb.toString());
		return sb.toString();
	}
}

Client.java

package com.unei.app;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.unei.soap.client.Book;
import com.unei.soap.client.IBookService;


public class Client {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		IBookService client=(IBookService)context.getBean("client");
		Book b=new Book();
		b.setBookId(1);
		b.setBookName("new book");
		client.addBook(b);
	}

}

applicationContext.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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-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
    ">

	<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.xml" />
	<aop:aspectj-autoproxy proxy-target-class="true" />
	<!--  
	<bean id="client" class="com.unei.soap.client.IBookService" factory-bean="clientFactory"
		factory-method="create"/>
	
	<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
		<property name="serviceClass" value="com.unei.soap.client.IBookService"/>
		<property name="address" value="http://localhost:8080/soap/services/bs"/>
	</bean>
	-->
	
	<jaxws:client id="client" serviceClass="com.unei.soap.client.IBookService" 
		address="http://localhost:8080/soap/services/bs">
		<jaxws:handlers>
			<bean class="com.unei.handler.CheckHandler"/>
		</jaxws:handlers>
	</jaxws:client>
</beans>

6.程序測試

客戶端輸出:

request...
Current IP address:192.168.1.101
Current MAC address:
00-1F-C6-D6-DC-E8
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><macAddress xmlns="http://localhost" SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next">00-1F-C6-D6-DC-E8</macAddress></SOAP-ENV:Header><soap:Body><ns2:addBook xmlns:ns2="http://service.unei.com/"><arg0><bookId>1</bookId><bookName>new book</bookName><price>0.0</price></arg0></ns2:addBook></soap:Body></soap:Envelope>response...

服務器端輸出:

2013-10-4 21:26:17 org.apache.cxf.services.IBookServiceService.IBookServicePort.IBookService
信息: Inbound Message
----------------------------
ID: 1
Address: http://localhost:8080/soap/services/bs
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[531], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.7]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><macAddress xmlns="http://localhost" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next">00-1F-C6-D6-DC-E8</macAddress></SOAP-ENV:Header><soap:Body><ns2:addBook xmlns:ns2="http://service.unei.com/"><arg0><bookId>1</bookId><bookName>new book</bookName><price>0.0</price></arg0></ns2:addBook></soap:Body></soap:Envelope>
--------------------------------------
Server:handleMessage....
request....
00-1F-C6-D6-DC-E8
addBook:new book
Server:handleMessage....
response....
2013-10-4 21:26:17 org.apache.cxf.services.IBookServiceService.IBookServicePort.IBookService
信息: Outbound Message
---------------------------
ID: 1
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body><ns2:addBookResponse xmlns:ns2="http://service.unei.com/"/></soap:Body></soap:Envelope>
--------------------------------------


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章