jax-ws之webservice security(安全)教程第一天
前言:
在前面的“5天學會jaxws-webservice教程”,我們講了基本的jax-ws的使用。
Jax-ws是業界公認的標準的webservice,它已經成為了一個行業界標準,包括cxf,其實cxf也是呼叫的jax-ws為標準的基於spring的webservice框架。
同時,大家都知道世界上除了j2ee體系外,還存在.net體系,同時有過相關經驗的同事們也知道用ws-security無非就是涉及到“加密”,“解密”,而JAVA的x509所涉及到的證書,公鑰,私鑰與.net體系之間是無法通用的。
但是webservice是因該屬於無所謂語言的一個標準,因此為了讓j2ee的webservice與.net的webservice能夠互相呼叫(當然包括ws-security裡的加密解密),SUN與微軟聯合推出了一個:WCF。
WCF是Windows Communication Foundation的縮寫,原來代號為Indigo,它是MS為SOA(Service Oriented Architecture 面向服務架構)而設計的一套完整的技術框架。利用它能夠開發出分散式(Distributed)應用程式,而且開發難度相比以前的.NETRemoting和ASP.NETXML Web Service等都有了大幅度的降低。
那麼搞J2EE的人如何去支援這個WCF呢?我們不可能去用.net的語言在J2EE工程中寫符合WCF的Webservice?
因此,SUN在jax-ws上推出了一套框架叫:metro,用於支援WCF的webservice.
在下面的介紹中,我們會先以一個jax-ws結合SSH框架的例子來作為一個承上啟下的開頭,現在開始我們的ws-security之旅吧。
該教程為基礎篇,不涉及到QoS與wcf相關,只有閱讀完了本教程,才能過渡到真正的jax-ws的ws-security。真正的可擴充套件的符合wcf標準的WebserviceQoS會在另一篇教程中(METRO)詳細介紹。
1. 引入兩個額外的jar包
jaxws-spring-1.8.jar與xbean-spring-2.8.jar。
2. 修改applicationContext.xml檔案
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xsi:schemaLocation=" http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context/spring-context-3.0.xsd http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsd http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd"> |
請注意紅色加粗部分。
<bean id="roleQuery" class="com.cts.pip.ws.RoleQuery" /> <wss:binding url="/roleQueryService"> <wss:service> <ws:service bean="#roleQuery" /> </wss:service> </wss:binding> |
ü 上面的描述,使得我們的Spring容器根據JAVA類: com.cts.pip.ws.RoleQuery生成相應的wsdl。
ü 這邊的: wss:binding url對映的是我們的web.xml中對映的相應的servleturl。
來看我們的web.xml中如何去對映我們的servleturl的:
<servlet> <servlet-name>jaxws-servlet</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>jaxws-servlet</servlet-name> <url-pattern>/roleQueryService</url-pattern> </servlet-mapping> |
3. 們的webservice
package com.cts.pip.ws; import javax.annotation.Resource; import javax.jws.WebMethod; import javax.jws.WebService; import org.apache.log4j.Logger; import com.cts.pip.dto.*; import java.util.*; import com.cts.pip.service.*; @WebService public class RoleQuery { protected Logger log = Logger.getLogger(this.getClass()); @Resource RoleService roleService; @WebMethod public List<RoleDTO> getRoles(){ List<RoleDTO> roleList=new ArrayList<RoleDTO>(); try{ roleList=roleService.queryRole(); log.info("roleList Size====="+roleList.size()); return roleList; }catch(Exception e){ log.error(e); return null; } } } |
4. 們的webservice成wsdl與生成相關的服務類
(如何編譯參考5天學會jaxws-webservice教程第一天)。
把這個web應用釋出到tomcat中去,啟動tomcat。
我們可以得到wsdl的輸出。
開啟soapui,生成一個soap測試客戶端:
測試一下我們的soap測試客戶端:
可以看到右邊我們得到了3條輸出,這就是webservice通過spring的service,spring的service通過hibernate的dao獲得到資料的soap包。代表我們的webservice服備端已經發布成功。
5. 開發客戶端
這邊如何編譯,如何引用wsdl生成客戶端所需要的stub一併濾過,詳細請參見:5天學會jaxws-webservice教程第一天中相關的內容,下面只給出實現的客戶端,在這邊我們使用的polling方式的webservice客戶端。
package com.cts.pip.ws; import javax.xml.ws.*; import java.util.*; import com.cts.pip.ws.*; import ctsjavacoe.ws.fromjava.CollectionWS; import ctsjavacoe.ws.fromjava.RtnMethodResponse; public class JAXWSSPRINGPollingClient { public static void main(String[] args) throws Exception { RoleQueryService service = new RoleQueryService(); RoleQuery port = service.getRoleQueryPort(); Response<GetRolesResponse> getRoleAsync = port.getRolesAsync(); while (!getRoleAsync.isDone()) { System.out.println("is not done"); } List<RoleDTO> rtnList = new ArrayList<RoleDTO>(); try { GetRolesResponse getRolesResponse = getRoleAsync.get(); rtnList = getRolesResponse.getReturn(); System.out.println("return size======" + rtnList.size()); for (RoleDTO r : rtnList) { System.out.println(r.getRoleId() + " " + r.getRoleName()); } } catch (Exception ex) { ex.printStackTrace(); } } } |