<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Cyh的博客

    Email:kissyan4916@163.com
    posts - 26, comments - 19, trackbacks - 0, articles - 220

    筆記之Spring-Web Service

    Posted on 2009-02-19 00:40 啥都寫點 閱讀(2522) 評論(0)  編輯  收藏 所屬分類: J2EE


  • 定義服務契約:設計由Web服務處理的樣本XML消息。我們將使用這些樣本消息創建用于生成WSDL的XML Schema。

    • 數據契約:定義了進入和流出服務的消息。使用XML模式(XSD)定義。XSD允許我們精確地定義消息的內容。我們不僅能夠定義消息中的元素,還可以指定這些消息的類型以及對消息中數據的限制。  (小提示:盡管手工編寫XSD不是很困難,但是也需要我們做更多的工作,XSD interface工具可以基于內容檢查一個或多個XML文件,生成可以驗證XML文件的XML模式,見PPT 1 。雖然這樣為我們節省了很多工作,但我們不能完全不做工作。這個XSD并不是很好,因為它會假設XML中的數據類型。大多數時候,這些假設沒有問題,但是通常情況下,我們還是需要XSD能夠更精確一點 )  

      操作契約:定義了服務將要執行的操作。

    編寫服務端點:創建類來接收和處理發向Web服務的消息。(消息端點是一個類,用于從客戶端接收XML消息,根據消息的內容,調用內部應用程序對象執行實際的工作。Spring-WS定義了幾個可以創建消息端點的抽象類。見PPT2)

    • 建立基于JDOM消息的端點

      序列化消息載荷:AbstractorMarshallingPayloadEndpoint與其他Spring-WS抽象端點類不同,它并不是從XML元素中抽取信息,而是通過處理對象獲取信息(PPT 3)。見Spring in action P240程序清單9.3 你會發現它比EvaluateHandJDomEndpoint短得多。這是因為EvaluateHandMarshallingEndpoint沒有任何在EvaluateHandJDomEndpoint中所必須的XML解析代碼。 在這里我們沒有看到的是AbstractMarshallingPayloadEndpoint中有一個XML序列化器的引用。當接收到XML消息時,它會在調用invokeInternal()前使用這個序列化器將XML消息變成對象。     Spring-WS的大部分內容是對象-XML映射(OXM)抽象。Spring -WS的OXM提供了幾個OXM實現: JAXB(版本1和版本2)、Castor XML、JiBX、XMLBeans、XStream好處:因為它使用了簡單對象作為參數,所以可以像其他POJO一樣進行單元測試。測試用例可以傳遞到EvaluateHandRequest對象中,并且做出返回EvaluateHandResponse的斷言。

    配置端點和Spring-WS基礎結構:將消息端點與可以將所有內容結合在一起的Spring-WS Bean裝配起來。

    • Spring-WS是基于Spring MVC的,在Spring MVC中,所有請求都由DispatcherServlet操作,這個Servlet會將請求分配給處理請求的控制器。類似的,Spring-WS會在前臺使用MessageDispatcherServlet。它是DispatcherServlet的子類,用于將SOAP請求分配給Spring-WS端點。<servlet>        <servlet-name>spring-ws</servlet-name>           <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>        </servlet>    <servlet-mapping>        <servlet-name>spring-ws</servlet-name>        <url-pattern>/*</url-pattern>    </servlet-mapping>后面會對這個配置進行修改,暫且先作為我們研究Spring-WS的起點

      將消息映射到端點:MessageDispatcherServlet也使用了端點映射來決定由哪個端點接收輸入的XML消息。對于撲克評分服務,我們將使用Spring-WS的PayloadRootQNameEndpointMapping,在Spring中配置如下:<bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping"><property name="endpointMap">  <map>     <entry key="{http://www.springinaction.com/poker/schemas}EvaluateHandRequest"  value-ref="evaluateHandEndpoint"/>  </map> </property>PayloadRootQNameEndpointMapping首先會檢查消息載荷的限定名(QName),接著再通過查詢映射列表(通過endpointMap屬性配置的)找到輸入SOAP消息映射到的端點。

      配置消息序列化器:在對象和XML消息之間進行轉換的關鍵是對象-XML 映射(OXM)。Spring-OXM是Spring-WS的一個子項目,提供對幾種常見OXM解決方案的抽象,其中包括JAXB和Castor XML.   Spring-OXM的核心元素是Marshaller和Unmarshaller接口。Marshaller的實現可以根據Java對象生成XML元素。與之相反,Unmarshaller的實現則被用于根據XML元素構建Java對象。  AbstractMarshallingPayloadEndPoint在處理消息時會使用Spring-OXM的序列化器和反序列化器。當AbstractMarshallingPayloadEndPoint接收到消息時,會將這條XML消息交給Unmarshaller,反序列化成一個對象,并傳遞給invokeInternal()方法。接下來,在invokeInternal()完成處理后,返回的對象則被交給Marshaller,序列化成XML,并傳遞給客戶端。  幸運的是,你不必自己創建Marshaller 和 Unmarshaller的實現。Spring-OXM提供了幾個實現。見PPT(4) 我們為撲克評分服務選擇了Castor XML.所以,需要按下面的方法在Spring中配置CastorMarshaller:  <bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">       <property  name="mappingLocation"  value="classpath:mapping.xml" /></bean>不需要附加的配置,Castor XML就可以進行一些基本的XML序列化工作。但是,我們的OXM進行的工作比默認Castor XML可以處理的工作要更復雜一些。因此,需要使用一個Castor XML映射文件來配置CastorMarshaller。mappingLoaction 屬性指定了Castor XML映射文件的位置。這里,我們將mappingLoaction設置為在應用程序跟classpath中查找名字是mapping.xml的映射文件。  (見spring in action P245 程序清單9.4)

      配置端點異常:我們需要一種方法能夠將Web服務或Spring-WS拋出的任何Java異常轉換成SOAP錯誤。為了實現這個目標,Spring-WS提供了SoapFaultMappingExceptionResolver。見PPT5,SoapFaultMappingExceptionResolver可以處理發生在消息處理過程中的任何未捕捉異常,并生成一個相應的SOAP錯誤返回給客戶端。在Spring中的配置:<bean id="endpointExceptionResolver" class="org.springframework.ws.soap.serer.endpoint.SoapFaultMappingExceptionResolver">    <property name="exceptionMappings">       <props>          <prop key="org.springframework.oxm.UnmarshallingFailureException">      SENDER,Invalid message received  </prop>  <prop key="org.springframework.oxm.ValidationFailureException">      SENDER,Invalid message received  </prop>       </props>    </property>    <property name="defaultFault" value="RECEIVER,Server error" /> </bean>   可以為exceptionMapping屬性配置一個或多個SOAP錯誤定義(被映射到Java異常的)。每個<prop>的Key是需要轉換成SOAP錯誤的Java異常,<prop>的值是一個由兩部分內容構成的值,第一部分是錯誤的類型,第二部分是描述錯誤的字符串。

      提供WSDL文件:你應該注意到我為構成Web服務消息的XML元素選擇的名稱:EvaluateHandRequest和EvaluateHandResponse。這些名字不是任意選擇的。選擇他們的目的是利用Spring-WS中的配置慣例,自動為撲克評分服務創建WSDL。   為了完成這個工作,需要配置Spring-WS的DynamicWsdlllDefinition。它是一個特殊的Bean,MessageDispatcherServlet可以使用它從XML模式生成WSDL。這將非常方便,因為我們已經為契約的數據部分定義了一些XML模式。下面如何配置DynamicWsdlllDefinition:

      <bean id="poker" class="org.springframework.ws.wsdl.wsdlll.DynamicWsdlllDefinition">

         <property name="builter">

              <bean class="org.springframework.ws.wsdl.wsdlll.builder.XsdBasedSoapllWsdl4jDefinitionBuilder">

         <property name="schema" value="/PokerTypes.xsd" />

         <property name="portTypeName" value="Poker" />

         <property name="locationUri" value="http://localhost:8080/Poker-WS/services" />

      </bean>

         </property>

      </bean>

      DynamicWsdlllDefinition通過讀取XML模式的定義來進行工作,在這里用schema屬性指定了PokerTypes.xsd。DynamicWsdlllDefintion會遍歷整個模式文件,查找所有名字以Request和Response結尾元素定義。它假設這些后綴用于指示發向或發自Web服務的消息,并且會在生成的WSDL中創建相應的<wsdl:operation>元素,見PPT6。最后一個DynamicWsdlllDefinition的屬性是  locationUri.這個屬性告訴客戶端服務可以在哪里發現。PPT8中的框圖分解了locationUri屬性中的URL。 談論到<servlet-mapping>,我們需要在Web.xml中添加一個新的<servlet-mapping>,以便 MessageDispatcherServlet可以提供WSDL定義。
              <servlet-mapping>
                    <servlet-name>poker</servlet-name>
                    <url-pattern>*.wsdl</url-pattern>
        </servlet-mapping> 

      • 使用預定義的WSDL:DynamicWsdlllDefinition可以適用于大多數情況,但是,你也可能會遇到一些情況,必須對Web服務的WSDL定義進行更多的控制。在這種情況下,需要自己創建WSDL,接著使用SimpleWsdlllDefinition將它置入到Spring中: <bean id="poker" class="org.springframework.ws.wsdl.wsdlll.SimpleWsdlllDefinition">       <property name="wsdl" value="PokerService.wsdl"> </bean> 預定義WSDL的唯一一個問題(除了創建它很困難外)是它是被靜態定義的。要想解決這個問題,可以讓MessageDispatcherServlet為你重寫WSDL。我們需要做的就是將一個名稱為transformWsdlLocations的<init-param>設置成true,這樣MessageDispatcherServlet就會從下面的位置得到它:<servlet>        <servlet-name>spring-ws</servlet-name>           <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>     <init-param>       <param-name>transformWsdlLocations</param-name>       <param-value>true</param-value>   </init-param></servlet>    

      部署服務:現在可以打包這個Web服務應用程序并進行部署了。因為這個項目選擇了使用Maven 2,所以只需要簡單的輸入下面的命令就可以創建可部署的WAR文件: %   mvn   package   deploy  一旦Maven執行完畢,在目標目錄中就會生成一個Poker-WS.war文件,它適合于部署到大多數Web應用服務器上。

    消費Spring-WS Web服務:使用Spring-WS建立Web服務僅僅展示了它的一半功能。Spring-WS還帶有一個基于相同消息規范的客戶端API。

    • 使用Web服務模板:WebServiceTemplate是Spring-WS客戶端API的核心類,見PPT9。向Web服務發送消息需要生成對每個Web服務客戶端都相同的SOAP封裝和通信樣本代碼。在Spring中配置WebServiceTemplate相當簡單:

      <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">

         <property name="messageFactory">

                 <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">

         </property>

         <property name="messageSender" ref="messageSender" />

      </bean>

      WebServiceTemplate需要知道如何構建發送給服務的消息以及如何發送消息。被置入到messageFactory屬性中的對象負責處理構建消息的任務。這個被置入的對象應該實現Spring-WS的WebServiceMessageFactory接口。幸運的是,不用自己去實現。Spring提供了3中選擇,見PPT10。   messageSender屬性應該被置入一個對WebServiceMessageSender實現的引用。Spring-WS提供了幾種實現,Spring-WS提供了幾種實現,見PPT11.  HttpUrlConnectionMessageSender在Spring中的配置如下:

      <bean id="messageSender" class="org.springframework.ws.transport.http.HttpUrlConnectionMessageSender">

              <property name="uri" value="http://localhost:8080/Poker-WS/services" />

      </bean>  

      url屬性指定了服務的位置。注意,這個URL必須與服務WSDL定義中的URL匹配。

      • 發送消息:在WebServiceTemplate配置完畢后,可以向撲克評分服務發送和接收XML消息。WebServiceTemplate提供了幾個用于發送和接收消息的方法。下面是一個最基本和最容易理解的方法:

        public boolean sendAndReceive(Source requestPayload, Result  responseResult  )throws Exception 。Source對象是發送給Web服務的消息載荷,Result對象則是由從服務返回的消息載荷裝配而成的。程序清單見spring in action(P253)展示的TemplateBasedPokerClient是一個PokerClient接口的實現,它使用了WebServiceTemplate的sendAndReceive()方法與撲克評分服務進行通信。注意,WebServiceTemplate是通過裝定器注入的。因此,TemplateBasedPokerClient必須按下面的方法在Spring中配置:

        <bean id="templateBasedClient" class=".....">

           <property name="webServiceTemplate" ref="webServiceTemplate" />

        </bean>  如果消息比較簡單,手工創建和解析XML消息沒有什么問題。但如果需要構建復雜的消息載荷,會需要大量的代碼。幸運的是,你不必自己處理這些XML。前面你看到了端點是如何使用序列化器在對象和XML直接進行轉換的。現在,我將向你展示WebServiceTemplate如何利用序列化器在客戶端消除對XML處理代碼的需求。

        在客戶端使用序列化器:除了程序清單中的sendAndRecevie()方法,WebServiceTemplate還提供了marshalSendAndReceive()方法。通過這個方法發送和接收的XML消息可以被序列化/反序列化成Java對象。 使用marshalSendAndReceive()方法十分簡單,只需要傳入請求對象參數,并且將響應對象作為返回值。這撲克評分服務中,這些對象分別是EvaluateHandRequest和EvaluateHandResponse。見程序清單9.6 (P255)。 WebServiceTemplate并不知道任何有關序列化/反序列化這些對象的內容,不過它可以被置入一個序列化器和一個反序列化器。

        <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">

           <property name="messageFactory">

                   <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">

           </property>

           <property name="messageSender" ref="messageSender" />

           <property name="marshaller" ref="marshaller"  />

           <property name="unmarshaller" ref="marshaller" />

        </bean>

        MarshallingPokerClient 比TemplateBasedPokerClient 更加簡潔。但是,我們還需要進行一些工作才能使其更加簡潔。來看看如何使用Spring-WS的WebServiceGatewaySupport類來取消對WebServiceTemplate的明確注入。見PPT12

      使用web服務的網關支持: Spring的數據訪問API包含了一個很方便的支持類--這個類可以提供不需要被配置的模板。于此類似,Spring-WS也提供了一個支持類WebServiceGateWaySupport,可以為繼承了它的客戶端類自動提供WebServiceTemplate。 即使WebServiceTemplate不在需要在Spring中定義,你仍然需要通過WebServiceGatewaySupport的屬性配置如果創建WebServiceTemplate的細節。

      <bean id="pokerClientGateway" class=".......">

         <property name="messageFactory">

                 <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">

         </property>

         <property name="messageSender" ref="messageSender" />

         <property name="marshaller" ref="marshaller"  />

         <property name="unmarshaller" ref="marshaller" />

      </bean>

      這些屬性必須被配置為是針對WebServiceTemplate的。



  •                                                                                                        --    學海無涯
            

    主站蜘蛛池模板: 免费国产草莓视频在线观看黄| 亚洲国产精品第一区二区| 亚洲伊人久久大香线蕉啊| 男人都懂www深夜免费网站| 国产AV无码专区亚洲Av| 久久免费精品一区二区| 亚洲AV人无码综合在线观看| 久久亚洲免费视频| 91亚洲自偷手机在线观看| 永久免费视频网站在线观看| 亚洲国产精品xo在线观看| 一个人免费观看在线视频www| 亚洲精品福利你懂| 最近2019中文字幕mv免费看| 亚洲日韩AV一区二区三区四区| 日韩免费视频观看| 无套内谢孕妇毛片免费看看| 亚洲精品无码久久不卡| 一个人免费视频在线观看www| 婷婷亚洲久悠悠色悠在线播放| 无码成A毛片免费| 亚洲国产韩国一区二区| 毛片a级三毛片免费播放| 国产青草亚洲香蕉精品久久| 久久久久国产亚洲AV麻豆| 最近高清中文字幕免费| 亚洲精品精华液一区二区| 久久久久亚洲av成人无码电影| 性色午夜视频免费男人的天堂| 亚洲人成人网毛片在线播放| 婷婷综合缴情亚洲狠狠尤物| 七色永久性tv网站免费看| 亚洲国产成人99精品激情在线| 免费一级特黄特色大片在线观看| a级片免费在线观看| 亚洲最大福利视频| 亚洲精品夜夜夜妓女网| 最近免费中文字幕视频高清在线看| 污视频网站免费在线观看| 亚洲日本中文字幕| 国产乱子伦片免费观看中字|