WebService 是一套標(biāo)準(zhǔn),而不是一種具體的技術(shù)。不同的平臺(tái),不同的語(yǔ)言,大都提供了對(duì) WebService 的開(kāi)發(fā)實(shí)現(xiàn)。
在 JAVA 領(lǐng)域里,WebService 的框架有不少,常用的就有 AXIS,XFire , CXF 等 .
Apache CXF 是一個(gè)開(kāi)源的 Services 框架 , 它 的前身是 Apache CeltiXfire , 繼承自 Celtix 和 XFire 兩大開(kāi)源項(xiàng)目 ,
CXF 實(shí)現(xiàn)了 JAX-WS (Java API For XML-WebService) API,對(duì) JAX-WS 提供了全面的支持 , 而且可以和 Spring 進(jìn)行無(wú)縫集成。
CXF 支持多種標(biāo)準(zhǔn) :
支持 JAX-WS 、 JAX-WSA 、JSR-181 和 SAAJ;
支持 SOAP 1.1 、1.2 、WS-I BasicProfile 、WS-Security 、WS-Addressing 、WS-RM 和 WS-Policy;
支持 WSDL ( Web Services Description Language ) 1.1 、2.0;
支持 MTOM;
為幫助理解,下面引用一段摘自網(wǎng)絡(luò)的文字內(nèi)容 :
" 什么是 WebServices
從表面上看,Webservice 就是一個(gè)應(yīng)用程序,它向外界暴露出一個(gè)能夠通過(guò) Web 進(jìn)行調(diào)用的 API 。也就是說(shuō),可以利用編程的方法通過(guò) Web 來(lái)調(diào)用這個(gè)應(yīng)用程序。
對(duì) Webservice 更精確的解釋 : Webservice 是建立可互操作的分布式應(yīng)用程序的新平臺(tái)。Webservice 平臺(tái)是一套標(biāo)準(zhǔn),它定義了應(yīng)用程序如何在 Web 上實(shí)現(xiàn)互操作性。
你可以用任何你喜歡的語(yǔ)言,在任何你喜歡的平臺(tái)上寫 Webservice ,只要我們可以通過(guò) Webservice 標(biāo)準(zhǔn)對(duì)這些服務(wù)進(jìn)行查詢和訪問(wèn)。
不管你的 Webservice 是用什么工具,什么語(yǔ)言寫出來(lái)的,只要你用 SOAP 協(xié)議通過(guò) HTTP 來(lái)調(diào)用它,總體結(jié)構(gòu)都一致。通常,你用你自己喜歡的語(yǔ)言(如VB 6或者VB.NET)
來(lái)構(gòu)建你的 Webservice,然后用 SOAP Toolkit 或者 .NET 的內(nèi)建支持來(lái)把它暴露給 Web 客戶。于是,任何語(yǔ)言,任何平臺(tái)上的客戶都可以閱讀其WSDL文檔,
以調(diào)用這個(gè) Webservice。客戶根據(jù) WSDL 描述文檔,會(huì)生成一個(gè) SOAP 請(qǐng)求消息。Webservice 都是放在 Web 服務(wù)器 (如IIS) 后面的,客戶生成的 SOAP 請(qǐng)求
會(huì)被嵌入在一個(gè) HTTP POST 請(qǐng)求中,發(fā)送到 Web 服務(wù)器來(lái)。Web 服務(wù)器再把這些請(qǐng)求轉(zhuǎn)發(fā)給 Webservice 請(qǐng)求處理器。請(qǐng)求處理器的作用在于,解析收到的 SOAP 請(qǐng)求,
調(diào)用 Webservice,然后再生成相應(yīng)的 SOAP 應(yīng)答。Web 服務(wù)器得到 SOAP 應(yīng)答后,會(huì)再通過(guò) HTTP 應(yīng)答的方式把它送回到客戶端。 "
環(huán)境 :
JDK 1.6
eclipse 3.6
CXF 2.5.3
spring 3.0
編寫 HelloWorld :
下載 Apache CXF : http://cxf.apache.org/download.html
導(dǎo)入 CXF 所需的 jar 包 :
commons-logging-1.1.1.jar
cxf-2.5.3.jar
geronimo-activation_1.1_spec-1.1.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.7.1.jar
geronimo-jaxws_2.2_spec-1.1.jar
geronimo-jms_1.1_spec-1.1.1.jar
geronimo-servlet_2.5_spec-1.1.2.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.3.jar
jaxb-api-2.2.3.jar
jaxb-impl-2.2.4-1.jar
neethi-3.0.2.jar
saaj-api-1.3.4.jar
saaj-impl-1.3.12.jar
wsdl4j-1.6.2.jar
wss4j-1.6.5.jar
xml-resolver-1.2.jar
xmlschema-core-2.0.2.jar
也可以將 CXF lib 下的 jar 包全部導(dǎo)入,以及導(dǎo)入 spring 所需 jar 包 .
服務(wù)器端 ( web project,項(xiàng)目名 : ws ) ---
1 . 編寫 HelloWorld 接口,并將其標(biāo)注成 WebService 的標(biāo)準(zhǔn) java 接口
package com.fancy.service;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
public String sayHi(String message);
}
2 . 編寫 HelloWorld 的實(shí)現(xiàn)類
package com.fancy.service.impl;
import javax.jws.WebService;
import com.fancy.service.HelloWorld;
@WebService(endpointInterface = "com.fancy.service.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
public String sayHi(String message) {
return "Hi " + message + " !";
}
}
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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
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://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 配置請(qǐng)參考官網(wǎng): http://cxf.apache.org/docs/jax-rs-and-jax-ws.html -->
<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 id="helloWorld" class="com.fancy.service.impl.HelloWorldImpl" />
<!-- JAX-WS -->
<!-- implementor 指定 WebService 實(shí)現(xiàn)類, address 指定訪問(wèn)地址 -->
<jaxws:endpoint implementor="#helloWorld" address="/helloworld" publish="true" />
</beans>
以上配置中的 cxf.xml,cxf-extension-soap.xml,cxf-servlet.xml 實(shí)際上是放在 cxf-2.5.3.jar 里面的 META-INF 文件夾的 cxf 目錄下,由于我們已經(jīng)導(dǎo)入了這個(gè) jar 包,
所以在這里,我們只需要這樣配置就行,其他的就可以不用管了,至于更多的詳細(xì)信息,請(qǐng)參考幫助文檔 : http://cxf.apache.org/docs/jax-rs-and-jax-ws.html
web.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.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>/webservice/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
OK,到此服務(wù)器端已經(jīng)開(kāi)發(fā)完成,部署運(yùn)行,打開(kāi)你最熟悉的瀏覽器,訪問(wèn) : http://localhost:8080/ws/webservice/helloworld?wsdl
如果能查看到 WSDL 文件的內(nèi)容信息如下,說(shuō)明服務(wù)器端已經(jīng)沒(méi)問(wèn)題了 :

客戶端 ( web project,項(xiàng)目名 : ws_client ) ---
如果你對(duì) CXF 或 Axis 比較熟悉的話,可以使用 wsdl2java 命令來(lái)根據(jù) wsdl 文件直接生成客戶端的 java 代碼,其中,CXF 的 WSDL to Java 的命令參數(shù)
請(qǐng)自行參考官網(wǎng)文檔 : https://cwiki.apache.org/CXF20DOC/wsdl-to-java.html 順便說(shuō)一下,使用 CXF 的 wsdl2java 命令需要配置一下環(huán)境變量,
下面采用手工方式編寫客戶端測(cè)試代碼 :
1 . 首先需要?jiǎng)?chuàng)建一個(gè)與服務(wù)器端相同的 HelloWorld 接口,這是服務(wù)端給我們暴露的服務(wù),客戶端的這個(gè) HelloWorld 接口代碼的編寫需與服務(wù)端的一致 .
package com.fancy.service.client;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
public String sayHi(String message);
}
2 . 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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
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://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="wsclient" class="com.fancy.service.client.HelloWorld" factory-bean="wsclientFactory" factory-method="create" />
<bean id="wsclientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.fancy.service.client.HelloWorld" />
<property name="address" value="http://192.168.1.113:8080/ws/webservice/helloworld" />
</bean>
</beans>
Tips : 這里配置的 <property name="address" value="http://192.168.1.113:8080/ws/webservice/helloworld" />,其中 address 的屬性值 value 要與服務(wù)器端
applicationContext.xml 配置中的 <jaxws:endpoint implementor="#helloWorld" address="/helloworld" publish="true" /> 的 address 對(duì)應(yīng)起來(lái)。
3 . Junit 測(cè)試
package junit.test;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.fancy.service.client.HelloWorld;
/**
* -----------------------------------------
* @描述 客戶端測(cè)試
* @作者 fancy
* @郵箱 fancydeepin@yeah.net
* @日期 2012-10-4 <p>
* -----------------------------------------
*/
public class ClientTestApp {
private static ApplicationContext context = null;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
context = null;
}
@Test
public void clientTest(){
HelloWorld helloworld = (HelloWorld)context.getBean("wsclient");
String message = helloworld.sayHi("fancy");
System.out.println(message);
}
}
測(cè)試的時(shí)候,必須保證服務(wù)器是開(kāi)著的,后臺(tái)打印輸出結(jié)果 :
Hi fancy !