我已经学习了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本身?
发布于 2012-06-24 02:16:49
HTTPInvokerServiceExporter背后的思想是提供一个端点来接收remove方法调用。
在服务器端,只需配置一个RemoteExporter,声明要公开的接口并将其关联到将处理调用的实际bean即可。
在客户端上,有必要配置基本上需要在服务器端访问的接口的RemoteAcessor。
通过超文本传输协议的实现可以在服务器端使用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实现的一个实例在foo.bar.MyService接口下通过/myService (bean名称)映射的URL公开,在最简单的情况下,使用BeanNameUrlHandlerMapping将URL映射到具有URL值的bean (本例中为/myService)。
在客户端(使用者),您将配置一个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和Burlap协议相同的设置简易性。
客户端将
序列化远程调用对象并反序列化远程调用结果对象。与RMI一样使用Java序列化,但提供与Caucho的基于HTTP的Hessian和Burlap协议相同的设置简易性。
在这种情况下,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映射到控制器,就像示例中所做的那样,而不需要在context xml上进行任何bean配置。
但是这将通过REST接口公开您的服务,这意味着它将处理HTTP普通请求,这些请求可以由其他使用者(如PHP使用者)完成(这不能使用Spring Remoting完成,因为它使用纯Java序列化)。
如果您的客户端是Java,您可以明确使用远程处理并将您的服务作为一个整体公开,如果不是这样,使用Spring MVC的REST实现是一个很好的解决方案。
Spring文档可以在here中找到
发布于 2012-06-21 14:52:24
我非常推荐用@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) {
...
}就是这样,每个控制器有多个映射。
发布于 2012-06-22 23:53:07
我认为你需要先告诉我们你想做什么。如果要将服务公开给通用web客户端,REST或SOAP将是更好的选择;如果要将服务公开给另一个应用程序中的另一个Spring bean,那么Spring Remoting可能就足够了。
spring配置文件中的注释"exposed web services“似乎不清楚您的目的。
当您向远程客户端公开一个服务时,您总是需要提供一个契约,让远程客户端知道什么是可能的。REST使用URL公开该约定;SOAP使用WSDL公开该约定;Spring Remoting只是在java接口中直接向客户端提供该约定,因此客户端可以将该接口注入到自己的bean中,并将其用作本地定义的bean。
在您的问题中,您提到了将方法映射到URL,Spring Remoting无法做到这一点,因为它公开了接口;对我来说,您想要做的事情听起来非常简单。我同意@stevebrown的观点,使用映射控制器公开你的服务是一个很好的方法。
https://stackoverflow.com/questions/11076692
复制相似问题