CXF整合spring入门helloworld

 下面的例子是摘抄的CXF官网的例子,然后自己动手测试成功之后的结果

另外,添加了验证的处理

首先是添加Maven依赖:

	<dependencies>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>${cxf-version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>${cxf-version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http-jetty</artifactId>
			<version>${cxf-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring-version}</version>
		</dependency>
	</dependencies>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<cxf-version>2.7.8</cxf-version>
		<spring-version>3.2.6.RELEASE</spring-version>
	</properties>

然后开始server端:

 在web.xml中添加CXF的servlet(拦截符合 /cxf/* 的所有请求):

	<servlet>
		<servlet-name>CXFService</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
	</servlet>

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

 在applicationContext.xml中引入CXF的配置文件:cxf-servlet.xml,这样是为了将CXF的配置放到单独的文件中

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 启动注入功能 -->
	<context:annotation-config />
	<!-- 启动扫描component功能 -->
	<context:component-scan base-package="com.tch.test.cxf.server" />
	
	<import resource="cxf-servlet.xml"/>
	
</beans>

  

cxf-servlet.xml文件的内容为:

<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/schemas/jaxws.xsd">
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	<jaxws:endpoint id="helloWorld" implementor="#helloWorldWebService" address="/HelloWorld">
		<jaxws:inInterceptors>
			<!-- 添加头信息处理的拦截器 -->
			<ref bean="soapHeaderInterceptor"/>
		</jaxws:inInterceptors>
	</jaxws:endpoint>
</beans>

头信息处理拦截器:

package com.tch.test.cxf.server.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.springframework.stereotype.Component;
import org.w3c.dom.NodeList;

/**
 *  获取soap头信息
 */
@Component("soapHeaderInterceptor")
public class ReadSoapHeader extends AbstractPhaseInterceptor<SoapMessage> {

    private SAAJInInterceptor saa = new SAAJInInterceptor();

    public ReadSoapHeader() {
    	
        super(Phase.PRE_PROTOCOL);
//      super(Phase.USER_LOGICAL);
        getAfter().add(SAAJInInterceptor.class.getName());
        
    }

    public void handleMessage(SoapMessage message) throws Fault {
    	
    	// 获取request。
		HttpServletRequest request = (HttpServletRequest) message
				.get(AbstractHTTPDestination.HTTP_REQUEST);
		
		System.out.println(request.getRequestURI());
		System.out.println(request.getRequestURL());
		
        SOAPMessage mess = message.getContent(SOAPMessage.class);
        if (mess == null) {
            saa.handleMessage(message);
            mess = message.getContent(SOAPMessage.class);
        }
        SOAPHeader head = null;
        try {
            head = mess.getSOAPHeader();
        } catch (SOAPException e) {
            e.printStackTrace();
        }
        if (head == null) {
            return;
        }
        try {
            //读取自定义的节点
            NodeList nodes = head.getElementsByTagName("tns:spId");
            NodeList nodepass = head.getElementsByTagName("tns:spPassword");
            
            boolean isVerifyPassed = false;
            //获取节点值,简单认证
            if (nodes.item(0).getTextContent().equals("wdw")) {
                if (nodepass.item(0).getTextContent().equals("wdwsb")) {
                	isVerifyPassed = true;
                	System.out.println("认证成功");
                }
            }
            if(! isVerifyPassed){//表明没有验证通过
            	 SOAPException soapExc = new SOAPException("认证错误");
                 throw new Fault(soapExc);
            }
        } catch (Exception e) {
            SOAPException soapExc = new SOAPException("认证错误");
            throw new Fault(soapExc);
        }
    }

}

 
 

接下来是服务端发布的服务接口:

package com.tch.test.cxf.server.service;
import javax.jws.WebService;
 
@WebService
public interface HelloWorld {
    String sayHi(String text);
}

 实现类:

package com.tch.test.cxf.server.service;
import javax.jws.WebService;

import org.springframework.stereotype.Component;

@Component("helloWorldWebService")
@WebService(endpointInterface = "com.tch.test.cxf.server.service.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
 
    public String sayHi(String text) {
        System.out.println("sayHi called , text : "+text);
        return "Hello " + text;
    }
    
}

 哦了,然后启动项目,就发布web服务了。

访问以下看看是否成功:(cxf-server是我的项目名称)

http://localhost:8080/cxf-server/cxf/HelloWorld?wsdl

 成功的话,就会看到下面的内容了:

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.server.cxf.test.tch.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloWorldImplService" targetNamespace="http://service.server.cxf.test.tch.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.server.cxf.test.tch.com/" elementFormDefault="unqualified" targetNamespace="http://service.server.cxf.test.tch.com/" version="1.0">
<xs:element name="sayHi" type="tns:sayHi"/>
<xs:element name="sayHiResponse" type="tns:sayHiResponse"/>
<xs:complexType name="sayHi">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHiResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHiResponse">
<wsdl:part element="tns:sayHiResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHi">
<wsdl:part element="tns:sayHi" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="HelloWorld">
<wsdl:operation name="sayHi">
<wsdl:input message="tns:sayHi" name="sayHi"></wsdl:input>
<wsdl:output message="tns:sayHiResponse" name="sayHiResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloWorldImplServiceSoapBinding" type="tns:HelloWorld">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHi">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sayHi">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHiResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorldImplService">
<wsdl:port binding="tns:HelloWorldImplServiceSoapBinding" name="HelloWorldImplPort">
<soap:address location="http://localhost:8080/cxf-server/cxf/HelloWorld"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

 这样,发布服务就成功了。

接下来是调用服务,也就是服务消费端:(我的消费端项目名称是cxf-client)

同样的,在applicationContext.xml里面引入单独的CXF配置文件cxf-servlet.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 启动扫描component功能 -->
	<context:component-scan base-package="com.tch.test.cxf.server" />
	
	<import resource="cxf-servlet.xml"/>
	
</beans>

 cxf-servlet.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	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/schemas/jaxws.xsd">

	<jaxws:client id="helloClient" serviceClass="com.tch.test.cxf.server.service.HelloWorld" address="http://localhost:8080/cxf-server/cxf/HelloWorld">
		<jaxws:outInterceptors>
			<!-- 添加头信息的拦截器 -->
			<ref bean="addSoapHeaderInterceptor"/>
		</jaxws:outInterceptors>
	</jaxws:client>
		
</beans>

添加头信息的拦截器:

package com.tch.test.cxf.server.interceptor;


import java.util.List;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
 *  在发送消息前,封装Soap Header 信息
 */
@Component("addSoapHeaderInterceptor")
public class AddSoapHeader extends AbstractSoapInterceptor {
      private static String nameURI="http://127.0.0.1:8080/cxfTest/ws/HelloWorld";   
      
        public AddSoapHeader(){   
            super(Phase.WRITE);   
        }   
        
        public void handleMessage(SoapMessage message) throws Fault {   
            String spPassword="wdwsb";   
            String spName="wdw";   
               
            QName qname=new QName("RequestSOAPHeader");   
            Document doc=DOMUtils.createDocument();   
            //自定义节点
            Element spId=doc.createElement("tns:spId");   
            spId.setTextContent(spName);   
            //自定义节点
            Element spPass=doc.createElement("tns:spPassword");   
            spPass.setTextContent(spPassword);
               
            Element root=doc.createElementNS(nameURI, "tns:RequestSOAPHeader");   
            root.appendChild(spId);   
            root.appendChild(spPass);   
               
            SoapHeader head=new SoapHeader(qname,root);   
            List<Header> headers=message.getHeaders();   
            headers.add(head);   
            System.out.println(">>>>>添加header<<<<<<<");
        }   

}

其中的接口跟cxf-server是一样的:

package com.tch.test.cxf.server.service;
import javax.jws.WebService;
 
@WebService
public interface HelloWorld {
    String sayHi(String text);
}

 接下来我们测试一下调用是否成功:

package com.tch.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tch.test.cxf.server.service.HelloWorld;

public class T1 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // your Spring ApplicationContext
		HelloWorld client = (HelloWorld) context.getBean("helloClient");	
		System.out.println(client.sayHi("this is cxf demo"));
	}
	
}

如果成功就可以看到输出了  Hello this is cxf demo  啦!如果修改一下AddSoapHeader里面的头信息内容,就会发现验证失败,从而达到验证账号密码的效果。。。

猜你喜欢

转载自dreamoftch.iteye.com/blog/1998183
今日推荐