WebService 是一套標準,而不是一種具體的技術。不同的平臺,不同的語言,大都提供了對 WebService 的開發實現。
在 JAVA 領域里,WebService 的框架有不少,常用的就有 AXIS,XFire , CXF 等 .
Apache CXF 是一個開源的 Services 框架 , 它 的前身是 Apache CeltiXfire , 繼承自 Celtix 和 XFire 兩大開源項目 ,
CXF 實現了 JAX-WS (Java API For XML-WebService) API,對 JAX-WS 提供了全面的支持 , 而且可以和 Spring 進行無縫集成。
CXF 支持多種標準 :
支持 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;
為幫助理解,下面引用一段摘自網絡的文字內容 :
" 什么是 WebServices
從表面上看,Webservice 就是一個應用程序,它向外界暴露出一個能夠通過 Web 進行調用的 API 。也就是說,可以利用編程的方法通過 Web 來調用這個應用程序。
對 Webservice 更精確的解釋 : Webservice 是建立可互操作的分布式應用程序的新平臺。Webservice 平臺是一套標準,它定義了應用程序如何在 Web 上實現互操作性。
你可以用任何你喜歡的語言,在任何你喜歡的平臺上寫 Webservice ,只要我們可以通過 Webservice 標準對這些服務進行查詢和訪問。
不管你的 Webservice 是用什么工具,什么語言寫出來的,只要你用 SOAP 協議通過 HTTP 來調用它,總體結構都一致。通常,你用你自己喜歡的語言(如VB 6或者VB.NET)
來構建你的 Webservice,然后用 SOAP Toolkit 或者 .NET 的內建支持來把它暴露給 Web 客戶。于是,任何語言,任何平臺上的客戶都可以閱讀其WSDL文檔,
以調用這個 Webservice。客戶根據 WSDL 描述文檔,會生成一個 SOAP 請求消息。Webservice 都是放在 Web 服務器 (如IIS) 后面的,客戶生成的 SOAP 請求
會被嵌入在一個 HTTP POST 請求中,發送到 Web 服務器來。Web 服務器再把這些請求轉發給 Webservice 請求處理器。請求處理器的作用在于,解析收到的 SOAP 請求,
調用 Webservice,然后再生成相應的 SOAP 應答。Web 服務器得到 SOAP 應答后,會再通過 HTTP 應答的方式把它送回到客戶端。 "
環境 :
JDK 1.6
eclipse 3.6
CXF 2.5.3
spring 3.0
編寫 HelloWorld :
下載 Apache CXF : http://cxf.apache.org/download.html
導入 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 包全部導入,以及導入 spring 所需 jar 包 .
服務器端 ( web project,項目名 : ws ) ---
1 . 編寫 HelloWorld 接口,并將其標注成 WebService 的標準 java 接口
package com.fancy.service;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
public String sayHi(String message);
}
2 . 編寫 HelloWorld 的實現類
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">
<!-- 配置請參考官網: 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 實現類, address 指定訪問地址 -->
<jaxws:endpoint implementor="#helloWorld" address="/helloworld" publish="true" />
</beans>
以上配置中的 cxf.xml,cxf-extension-soap.xml,cxf-servlet.xml 實際上是放在 cxf-2.5.3.jar 里面的 META-INF 文件夾的 cxf 目錄下,由于我們已經導入了這個 jar 包,
所以在這里,我們只需要這樣配置就行,其他的就可以不用管了,至于更多的詳細信息,請參考幫助文檔 : 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,到此服務器端已經開發完成,部署運行,打開你最熟悉的瀏覽器,訪問 : http://localhost:8080/ws/webservice/helloworld?wsdl
如果能查看到 WSDL 文件的內容信息如下,說明服務器端已經沒問題了 :

客戶端 ( web project,項目名 : ws_client ) ---
如果你對 CXF 或 Axis 比較熟悉的話,可以使用 wsdl2java 命令來根據 wsdl 文件直接生成客戶端的 java 代碼,其中,CXF 的 WSDL to Java 的命令參數
請自行參考官網文檔 : https://cwiki.apache.org/CXF20DOC/wsdl-to-java.html 順便說一下,使用 CXF 的 wsdl2java 命令需要配置一下環境變量,
下面采用手工方式編寫客戶端測試代碼 :
1 . 首先需要創建一個與服務器端相同的 HelloWorld 接口,這是服務端給我們暴露的服務,客戶端的這個 HelloWorld 接口代碼的編寫需與服務端的一致 .
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 要與服務器端
applicationContext.xml 配置中的 <jaxws:endpoint implementor="#helloWorld" address="/helloworld" publish="true" /> 的 address 對應起來。
3 . Junit 測試
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;
/**
* -----------------------------------------
* @描述 客戶端測試
* @作者 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);
}
}
測試的時候,必須保證服務器是開著的,后臺打印輸出結果 :
Hi fancy !
posted on 2012-10-04 16:13
fancydeepin 閱讀(6847)
評論(4) 編輯 收藏