Apache CXF 提供方便的Spring整合方法,可以通过注解、Spring标签式配置来暴露Web Services和消费Web Services

各种类型的Annotation。@WebService和@WebMethod是WSDL映射Annatotion。这些Annotation将描述Web Service的WSDL文档元素和Java源代码联系在一起。

@SOAPBinding是一个绑定的annotation用来说明网络协议和格式。



1、@WebService annotation的元素name,serviceName和targetNamespace成员用来描述

wsdl:portType,wsdl:service,和targetNameSpace生成WebService中的WSDL文件。

2、@SOAPBinding是一个用来描述SOAP格式和RPC的协议的绑定Annotation。

3、@WebMethod Annotation的operationName成员描述了wsdl:operation,而且它的操作描

述了WSDL文档中的SOAPAction头部。这是客户端必须要放入到SQAPHeader中的数

值,SOAP 1.1中的一种约束。

4、@WebParam Annotation的partName成员描述了WSDL文档中的wsdl:part。

5、@WebResult Annotation的partName成员描述了wsdl:part用来返回WSDL文档的值。



例如下面使用annotation定义了一个webservice:

import java.util.List;

import javax.jws.WebMethod;

import javax.jws.WebParam;

import javax.jws.WebResult;

import javax.jws.WebService;

import com.cxf.pojo.User;



@WebService(targetNamespace = "http://jdk.study.hermit.org/client")

public interface UserService {

@WebMethod(operationName="Insert")

public void insert( @WebParam(name = "userId") String userid,

@WebParam(name = "userName") String username,

@WebParam(name = "userEmail") String useremail,

@WebParam(name = "userAge") int userage);



@WebMethod(operationName="GetUserById")

@WebResult(name = "result")

public User getUserById(@WebParam(name="userid") String userid);



@WebMethod(operationName="GetAllUsers")

@WebResult(name = "result")

public List getAllUsers();

}

其实现类如下所示:

import java.util.List;

import javax.jws.WebService;



import com.cxf.dao.UserDao;

import com.cxf.pojo.User;

import com.cxf.service.UserService;



@WebService(endpointInterface="com.cxf.service.UserService")

public class UserServiceImpl implements UserService {



private UserDao userDao;

public List getAllUsers() {

return userDao.findAllUser();

}



public User getUserById(String userid) {

return userDao.findUserById(userid);

}



public void insert(String userid, String username, String useremail, int userage) {

User user=new User();

user.setUserage(userage);

user.setUseremail(useremail);

user.setUserid(userid);

user.setUsername(username);

userDao.insert(user);

System.out.println("insert successfully!");

}



public void setUserDao(UserDao userDao) {

this.userDao = userDao;

}

}

注意:实现类中的@WebService,其中的endpointInterface成员指定了该类实现的接口



在Spring的配置文件中,需要对其进行配置:

首先在ApplicationContext.xml(Spring的配置文件)中引入CXF的XML Scheam 配置文件),如下:

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

<!—还需要引入以下3个关于CXF的资源文件,这三个文件在cxf.jar中-->

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

…… …… …… …… …… …… …… …… …… ……

</bean>



其次就是在Spring的配置文件中配置webservice,如下所示:

<jaxws:endpoint id="userManager" address="/UserManager"

implementorClass="com.cxf.service.UserService">

<jaxws:implementor>

<bean id="userServiceImpl"

class="com.cxf.service.impl.UserServiceImpl">

<property name="userDao">

<ref bean="userDao" />

</property>

</bean>

</jaxws:implementor>

</jaxws:endpoint>



注意:

①、address 为webservice发布的地址

②、implementorClass 为该webservice实现的接口

③、<jaxws:implementor></jaxws:implementor>之间定义的是implementorClass 指定接口的实现类



另外,在Spring的配置文件中配置完成后,需要修改web.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>



<servlet>

<servlet-name>CXFServlet</servlet-name>

<servlet-class>

org.apache.cxf.transport.servlet.CXFServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>CXFServlet</servlet-name>

<url-pattern>/services/*</url-pattern>

</servlet-mapping>

注意<url-pattern>/ services /*</url-pattern>配置,CXFServlet会拦截此类url,进行处理。上面配置的webservice将通过如下URL访问到:

http://localhost:8080/cxf-ws/services/ UserManager

UserManager为<jaxws:endpoint >标签中address属性对应的值

cxf-ws为本项目的名称



配置完成之后,将项目部署到tomcat上

输入URL:http://localhost:8080/cxf-ws/services/ UserManager?wsdl

将会看到生成的wsdl文件



为了能够直接访问到com.cxf.service.UserService中的insert方法,进行如下测试:

创建一个insertUser.html页面:

<html>

<head>

<script type="text/javascript">

function post() {

var xmlhttp=false;

if (!xmlhttp && typeof XMLHttpRequest!='undefined') {

try {

xmlhttp = new XMLHttpRequest();

} catch (e) {

xmlhttp=false;

}

}

if (!xmlhttp && window.createRequest) {

try {

xmlhttp = window.createRequest();

} catch (e) {

xmlhttp=false;

}

}

var dest = document.getElementByIdx_x('destination').value;

xmlhttp.open("POST", dest, true);

xmlhttp.onreadystatechange=function() {

if (xmlhttp.readyState==4) {

document.getElementByIdx_x("result").innerHTML = xmlhttp.responseText;

}

}

xmlhttp.setRequestHeader("Man", "POST " + dest + " HTTP/1.1")

xmlhttp.setRequestHeader("MessageType", "CALL")

xmlhttp.setRequestHeader("Content-Type", "text/xml");

var texta = document.getElementByIdx_x('texta');

var soapmess = texta.value;

xmlhttp.send(soapmess);

}

</script>

</head>

<body>

hi there

<form id="forma">

<textarea id="texta" rows="10" cols="80">

<?xml version='1.0' encoding='UTF-8'?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">

<SOAP-ENV:Body>

<Insert>

<userId>2005221104210066</userId>

<userName>Leon Cao</userName>

<userEmail>caohongliang2@163.com</userEmail>

<userAge>23</userAge>

</Insert>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

</textarea>

<p>

<input type="text" id="destination" size="50" value="http://localhost:8080/cxf-ws/services/UserManager"></input>

<p>

<input type="button" name="submit" value="Submit"></input>

</form>

<div id="container"></div>

Result:

<hr>

<div id="result">

</div>

<hr>

<div id="soap">

</div>

</body>

</html>

在该测试页面需要注意标记为红色的部分,如下是一个soap message:

<?xml version='1.0' encoding='UTF-8'?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">

<SOAP-ENV:Body>

<Insert>

<userId>2005221104210066</userId>

<userName>Leon Cao</userName>

<userEmail>caohongliang2@163.com</userEmail>

<userAge>23</userAge>

</Insert>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

注意:

①<SOAP-ENV:Body>标签之间<Insert>对应@WebMethod(operationName="Insert")

中的operationName属性的值

②<userId>、<userName>、<userEmail>、<userAge>标签对各自对应着insert方法中

@WebParam中name属性的值:

@WebParam(name = "userId") String userid,

@WebParam(name = "userName") String username,

@WebParam(name = "userEmail") String useremail,

@WebParam(name = "userAge") int userage);

当向webservice上发送该soap消息的时候将自动解析该soap消息,将Insert解析为insert方法,将<userId>、<userName>、<userEmail>、<userAge>标签对之间

的值解析为相对应的参数userid、username、useremail、userage

③<input type="text" id="destination" size="50" value="http://localhost:8080/cxf-ws/services/UserManager"></input>

该文本标签中的value属性为webservice的地址



运行该页面,点击Submit后将在数据库中插入一行数据,即调用了inser方法成功





<!-- sigService客户端对象 -->

<bean id="sigService"

factory-bean="clientBeanFactory" factory-method="create"

>

</bean>

<bean id="clientBeanFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">

<property name="serviceClass" value="com.cxf.interfaces.HelloWorldServiceInf"></property>

<property name="address" value="http://localhost:8080/myWebService/services/Hello"></property>

</bean>





HelloWorldServiceInf aaaa = WebApplicationContextUtils

.getRequiredWebApplicationContext(getServletContext())

.getBean(HelloWorldServiceInf.class);



System.out.println(aaaa.sayHello("1111"));