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