2012-06-18 88 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