spring remoting mapping urls

时间:2012-06-18 03:43:51

标签: java spring spring-mvc spring-remoting

我已经按照弹簧远程处理的教程,特别是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>

问题是,如果我的服务接口中有多个方法,是否可以将这些接口方法中的每一个映射到URL本身?

3 个答案:

答案 0 :(得分:4)

HTTPInvokerServiceExporter背后的想法是提供一个端点来接收删除方法调用。

服务器方面,配置一个RemoteExporter会很容易,声明要公开的接口并将其与将处理调用的真实bean相关联。

客户端上,有必要配置基本上需要在服务器端访问的接口的RemoteAcessor

可以使用服务器端的HttpInvokerServiceExporter完成HTTP上的实现,如下例所示:

服务接口:


package foo.bar.services;

public interface MyService {

    public int sum(int num1, int num2);

}

对于这项服务,您将有一个实现(假设为foo.bar.services.DefaultMyService)。

春季背景的展示和配置如下:


<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(bean名称)映射的URL在foo.bar.MyService接口下公开我的/myService实现的实例BeanNameUrlHandlerMapping除了使用URL值(这种情况/myService)将URL映射到bean之外别无其他。

在客户端(使用者),您将配置一个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>

当spring在客户端实例化bean时,会实例化一个代理,然后每个方法调用都会被序列化并通过HTTP发送到端点(在本例中为http://foo.bar.org/springSample/myService。在服务器端,此请求是反序列化和解释,即调用暴露的实际服务上的方法(在我们的案例中为DefaultMyService)。服务将返回一些将被序列化的内容,作为客户端执行的HTTP请求的结果。客户端将接收它并反序列化它并将其返回给原始方法调用器。

正如您所看到的(并从Spring文档中获得):

服务器端将

  

反序列化远程调用对象并序列化远程   调用结果对象。像RMI一样使用Java序列化,但是   提供与Caucho的基于HTTP的Hessian和   粗麻布协议。

客户端将

  

序列化远程调用对象并反序列化远程   调用结果对象。像RMI一样使用Java序列化,但是   提供与Caucho的基于HTTP的Hessian和   粗麻布协议。

在这种情况下与Spring Remoting一起使用的序列化是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序列化)。 / p>

如果您的客户端是Java,您可以明确地使用远程处理并将您的服务作为一个整体公开,如果不是,使用Spring MVC的REST实现是一个很好的解决方案。

可以找到Spring文档here

答案 1 :(得分: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) {
...
}

就是这样,每个控制器有多个映射。

答案 2 :(得分:1)

我想你需要先告诉我们你要做什么。如果您将服务公开给通用Web客户端,REST或SOAP将是更好的选择;如果您将服务暴露给另一个应用程序中的另一个Spring bean,那么Spring Remoting就足够了。

您的弹簧配置文件中的“公开的Web服务”注释似乎不清楚您的目的。

当您向远程客户端公开服务时,您始终需要提供合同以让远程客户端知道可能的内容。 REST使用URL公开该合同; SOAP使用WSDL公开该合同;而Spring Remoting只是直接给客户端在java接口中签约,因此客户端可以将该接口注入到自己的bean中,并像本地定义的bean一样使用它。

在您的问题中,您提到将方法映射到URL,Spring Remoting不能这样做,因为它暴露了接口;你想做什么听起来很震撼我。我同意@stevebrown,使用映射控制器公开您的服务是一种很好的方法。