2012-06-18 90 views
3

我已經按照春季遠程處理教程,特別是HttpInvokerServiceExporter,並且在設置客戶端和服務器(factorybean)時都沒有問題。彈簧遠程處理映射網址

的問題是,我使用Spring MVC注意到,每個接口被映射到一個特定的URL

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
     <property name="mappings"> 
      <props> 
       <prop key="hello.htm">test_service</prop> 
      </props> 
     </property> 
    </bean> 

    <!-- *********************exposed web services*************************--> 
    <bean name="test_service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> 
     <property name="serviceInterface" value="foo.webservices.HelloServiceInterface" /> 
     <property name="service"> 
      <ref bean="helloService"></ref> 
     </property> 

問題是,如果我在服務接口有1個多方法,是有可能映射這些接口方法中的每一個都是一個URL本身?

回答

4

HTTPInvokerServiceExporter背後的想法是提供一個接收移除方法調用的端點。

服務器端側很容易配置RemoteExporter,聲明您想要公開的接口並將其關聯到將處理調用的真實bean。

客戶端這將是必要的配置RemoteAcessor基本上需要接口將在服務器端訪問。

通過HTTP實施,可以在服務器端像下面的示例使用HttpInvokerServiceExporter來完成:

服務接口:


package foo.bar.services; 

public interface MyService { 

    public int sum(int num1, int num2); 

} 

對於此服務,你將有一個實現(比方說foo.bar.services.DefaultMyService)。

上Spring上下文博覽會和配置會是什麼樣子:


<bean name="myService" class="foo.bar.DefaultMyService" /> 
<bean name="/myService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> 
    <property name="service" ref="myService"/> 
    <property name="serviceInterface" value="foo.bar.MyService"/> 
</bean> 

有了這個配置我只是爲了有我的執行MyService正在通過由映射的URL下foo.bar.MyService接口暴露一個實例/myService(bean名稱)在最簡單的情況下使用BeanNameUrlHandlerMapping,除了將URL映射到具有URL值的bean(本例爲/myService)之外別無其他。

在客戶端(消費者),您將有一個配置的bean,只是聲明您期望遠程端暴露的接口。對於我們的服務會是這樣的:

<bean id="httpInvokerProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
    <property name="serviceUrl" value="http://foo.bar.org/springSample/myService"/> 
    <property name="serviceInterface" value="foo.bar.MyService"/> 
</bean> 

目前春季實例客戶端上的豆子,一個代理實例化,然後每一個方法調用將被序列化並通過HTTP發送到終端(在這種情況下http://foo.bar.org/springSample/myService 。在服務器端,這個請求被反序列化和解釋,即調用真實服務的方法被暴露(在我們的例子中,DefaultMyService)。服務將返回一些將被序列化的結果給客戶端執行的HTTP請求。客戶端會收到並反序列化它並將其返回給原始方法調用者。

正如你所看到的(並從S普林文檔):

服務器側將

反序列遠程調用對象和遠程串行化 調用結果對象。像RMI一樣使用Java序列化,但 提供了與Caucho的基於HTTP的Hessian和Burlap協議相同的簡易設置。

客戶機端將

序列化遠程調用對象和遠程反序列 調用結果對象。像RMI一樣使用Java序列化,但 提供了與Caucho的基於HTTP的Hessian和Burlap協議相同的簡易設置。

與春季遠程處理在這種情況下使用的序列化是Java序列化,這意味着HTTP請求保持包含序列化對象(實體主體是好事,記住,在這種情況下,JVM版本和類的版本必須是兼容)。

博覽會是作爲一個整體進行,你不能分開它有一個URL該接口的每個方法。因此,使用Spring MVC會更容易,並且創建一個控制器(@Controller)爲接口上的每個方法實現一個方法,將它標註爲@RequestMapping(帶有所需的URL),並按照以下示例調用服務上的方法:

控制器樣品


package foo.bar; 

import foo.bar.service.MyService; 

@Controller 
public class MyService { 
    @Autowired 
    private MyService myService; 

    @RequestMapping("/sum/{num1}/{num2}") 
    public int sum(@PathVariable("num1") int num1, @PathVariable("num2") int num2) { 
     return myService.sum(num1, num2); 
    } 

} 

使用上下文配置

<context:component-scan base-package="foo.bar"/> 

它將映射噸他對foo.bar,並自動在包中發現的類,這意味着Service實現(DefaultMyService)可以與@Service@Autowired映射到控制器的樣品中進行的,沒有上下文XML的bean配置。

但是,這將使您的服務通過REST接口公開,這意味着它將處理其他消費者(如PHP消費者可能會完成的HTTP簡單請求(這不能用Spring Remoting完成,因爲它使用純Java序列化)。

如果你的客戶是Java中,你可以明確地使用遠程處理和暴露你的服務作爲一個整體,如果不使用Spring MVC中的REST實現是一個很好的解決方案。

Spring文檔可以發現here

+0

我需要知道的。謝謝! – goh

1

我真的推薦用@Controller註釋來定義你的控制器。從Spring documentation開始,將組件掃描添加到您的Spring配置中。

<context:component-scan base-package="your.package.path"/> 

然後,在一類,比如,your.package.path.WhateverController,註釋類:

@Controller 
WhateverController 

和註釋你的方法用@RequestMapping:

@RequestMapping(value = "/helloWorld") 
public ModelAndView helloWorld() { 
... 
} 

@RequestMapping(value = "/project/{projectId}") 
public ModelAndView helloWorld(@PathVariable String projectId) { 
... 
} 

這關於它,每個控制器有多個映射。

+0

嘿史蒂夫,這也可與HttpInvokerServiceExporter – goh

+0

有你連接到這個類的任何原因? – stevedbrown

+0

主要是因爲Java序列化的。 – goh

1

我認爲你需要告訴我們你首先要做什麼。如果您將服務暴露給通用Web客戶端,REST或SOAP將是更好的選擇;如果你將服務暴露給另一個應用程序中的另一個Spring bean,那麼Spring Remoting就足夠了。

在你的spring配置文件中的評論「暴露的Web服務」似乎不清楚你的目的。

當您向遠程客戶端公開服務時,您總是需要提供合同讓遠程客戶端知道可能的情況。 REST使用URL公開該合同; SOAP使用WSDL公開該合約;而Spring Remoting只是直接爲客戶端提供java接口中的契約,所以客戶端可以將該接口注入到它自己的bean中,並像使用本地定義的bean一樣使用它。

在你提到的將方法映射到URL的問題中,Spring Remoting不能這樣做,因爲它暴露了接口;你想做什麼聽起來很REST給我。我同意@stevebrown,揭示你的服務使用映射控制器是一個好方法。

+0

感謝您的建議! – goh