rmi远程调用被拒绝_Spring 5.2.2 技术的集成—RMI、Hessian

   接下来一段时间介绍了Spring框架与许多javaEE(及相关)技术的集成。首先从远程WEB服务开始介绍。Spring使用各种技术为远程处理提供支持。远程处理简化了远程支持服务的开发,通过Java接口和对象作为输入和输出实现。目前,Spring支持以下远程处理技术:

  • 远程方法调用(Remote Method Invocation ,RMI):通过使用RmiProxyFactoryBean 和RmiServiceExporter,Spring支持传统的RMI(使用java.rmi.Remote接口和java.rmi.RemoteException)以及通过RMI调用器(使用任何Java接口)进行透明远程处理。

  • Spring HTTP Invoker:Spring提供了一种特殊的远程处理策略,允许通过HTTP进行Java序列化,支持任何Java接口(就像RMI调用器那样)。相应的支持类是HttpInvokerProxyFactoryBean 和HttpInvokerServiceExporter。

  • Hessian:通过使用Spring的HessianProxyFactoryBean 和HessianServiceExporter,可以通过Caucho提供的基于HTTP的轻量级二进制协议透明地公开你的服务。

  • JavaWeb服务:Spring通过JAX-WS为Web服务提供远程处理支持。

  • JMS:spring-jms模块中的JmsInvokerServiceExporter 和JmsInvokerProxyFactoryBean 类支持通过JMS作为底层协议进行远程处理。

  • AMQP:通过AMQP作为底层协议的远程处理由单独的Spring AMQP项目支持。

在介绍Spring的远程处理功能时,我们使用以下域模型和相应的服务:

public class Account implements Serializable{    private String name;    public String getName(){        return name;    }    public void setName(String name) {        this.name = name;    }}public interface AccountService {    public void insertAccount(Account account);    public ListgetAccounts(String name);}// 实现程序目前什么也不做public class AccountServiceImpl implements AccountService {    public void insertAccount(Account acc) {        //处理业务...    }    public ListgetAccounts(String name) {        // 处理业务...    }}

     从使用RMI向远程客户端公开服务开始,并讨论使用RMI的缺点。然后以一个使用Hessian作为协议的示例继续。

1、RMI

      通过使用Spring对RMI的支持,你可以通过RMI透明地公开你的服务。设置完成后,你基本上拥有一个类似于远程EJB的配置,除了没有对安全上下文传播或远程事务传播的标准支持。当你使用RMI调用器时,Spring确实为这种额外的调用上下文提供了衔接,因此你可以(例如)插入安全框架或自定义安全凭证。

1.1、使用RmiServiceExporter暴露服务

        使用RmiServiceExporter,我们可以将AccountService对象的接口公开为RMI对象。接口可以通过使用RmiProxyFactoryBean访问,或者在传统RMI服务的情况下通过普通RMI访问。RmiServiceExporter明确支持通过RMI调用器公开任何非RMI服务。

      我们首先要在Spring容器中设置服务。下面的示例演示如何执行此操作:

"accountService"     bean>

     接下来,我们必须使用RmiServiceExporter公开我们的服务。下面的示例演示如何执行此操作:

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">        <property name="serviceName" value="AccountService"/>    <property name="service" ref="accountService"/>    <property name="serviceInterface" value="example.AccountService"/>        <property name="registryPort" value="1199"/>bean>

     在前面的示例中,我们覆盖RMI注册表的端口。通常,你的应用程序服务器还维护一个RMI注册表,最好不要干扰它。此外,服务名称用于绑定服务。因此,在前面的示例中,服务被绑定到'rmi://HOST:1199/AccountService'。我们稍后使用这个URL在客户端链接服务。

    servicePort属性已被省略(默认为0)。这意味着使用匿名端口与服务通信。

1.2、在客户端连接服务

     我们的客户端是一个简单的对象,它使用AccountService 来管理帐户,如下例所示:

public class SimpleObject {    private AccountService accountService;    public void setAccountService(AccountService accountService) {        this.accountService = accountService;    }    // 使用accountService的其他方法}

为了在客户端上链接服务,我们创建一个单独的Spring容器,以包含以下简单对象和服务链接配置节点:

class=    <property name="accountService" ref="accountService"/>bean>"accountService"     <property name="serviceUrl" value="rmi://HOST:1199/AccountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

这就是我们需要做的,以支持客户端上的远程帐户服务。Spring透明地创建一个调用器,并通过RmiServiceExporter远程启用帐户服务。在客户端,我们使用RmiProxyFactoryBean将其链接起来。

2、使用Hessian通过HTTP远程调用服务

    Hessian提供了一个基于HTTP的二进制远程处理协议。它是由Caucho开发的,你可以在https://www.caucho.com/进行进一步了解。

2.1、Hessian

     Hessian通过HTTP进行通信,并使用一个定制的servlet进行通信。通过使用Spring的DispatcherServlet 原则,我们可以连接这样一个servlet来公开你的服务。首先,我们必须在应用程序中创建一个新的servlet,如下面的web.xml文件:

<servlet>    <servlet-name>remotingservlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>    <load-on-startup>1load-on-startup>servlet><servlet-mapping>    <servlet-name>remotingservlet-name>    <url-pattern>/remoting/*url-pattern>servlet-mapping>

如果你熟悉Spring的DispatcherServlet原则,那么你可能知道现在必须创建一个名为remoting的Spring容器配置remoting-servlet.xml在WEB-INF目录中。下一步将使用应用程序上下文。

     或者,考虑使用Spring更简单的HttpRequestHandlerServlet。这样可以将远程暴露定义嵌入根应用程序上下文(默认情况下,在WEB-INF/applicationContext.xml),单个servlet定义指向特定的暴露的bean。在本例中,每个servlet名称都需要与其目标暴露的bean名称相匹配。

2.2、使用HessianServiceExporter暴露您的bean

     在新创建的名为远程处理的应用程序上下文中remoting-servlet.xml,我们创建一个HessianServiceExporter 来暴露我们的服务,如下例所示:

"accountService"     bean>"/AccountService"     <property name="service" ref="accountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

 现在我们已经准备好在客户端连接服务了。没有明确指定的处理程序映射(将请求url映射到服务上),所以我们使用BeanNameUrlHandlerMapping 。因此,服务在包含DispatcherServlet 实例的映射(如前所定义)中的bean名称所指示的URL处暴露:https://HOST:8080/remoting/AccountService。

     或者,你可以在根应用程序上下文中(例如,在WEB-INF/applicationContext.xml中)创建HessianServiceExporter 的应用程序上下文,如下例所示:

"accountExporter"     <property name="service" ref="accountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

在后一种情况下,你应该在web.xml文件,最终结果相同:暴露服务被映射到位于/remoting/AccountService的请求路径。请注意,servlet名称需要与目标导出器的bean名称匹配。下面的示例演示如何执行此操作:

<servlet>    <servlet-name>accountExporterservlet-name>    <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServletservlet-class>servlet><servlet-mapping>    <servlet-name>accountExporterservlet-name>    <url-pattern>/remoting/AccountServiceurl-pattern>servlet-mapping>

3、在客户端的服务中链接

    通过使用HessianProxyFactoryBean,我们可以在客户端链接服务。同样的原则适用于RMI示例。我们提到使用以下示例创建一个单独的AccountService 或SimpleObject ,其中使用AccountBean管理以下实例:

class=    <property name="accountService" ref="accountService"/>bean>"accountService"     <property name="serviceUrl" value="https://remotehost:8080/remoting/AccountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

4、对通过Hessian公开的服务应用HTTP基本身份验证

    Hessian的一个优点是我们可以很容易地应用HTTP基本身份验证,因为这两个协议都是基于HTTP的。常规HTTP服务器安全机制可以通过使用web.xml文件例如,安全功能。通常,您不需要在这里使用每用户安全凭据。相反,您可以使用在HessianProxyFactoryBean 级别定义的共享凭据(类似于JDBC  DataSource),如下例所示:

class=    <property name="interceptors" ref="authorizationInterceptor"/>bean>"authorizationInterceptor"        class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">    <property name="authorizedRoles" value="administrator,operator"/>bean>

在前面的示例中,我们显式地提到了BeanNameUrlHandlerMapping 映射,并设置了一个拦截器,以便仅允许管理员和操作员调用此应用程序上下文中提到的bean。

     前面的例子没有展示一种灵活的安全基础设施。有关安全性的更多配置,请查看Spring Security项目。

欢迎关注和转发Spring中文社区(加微信群,可以关注后加我微信):

34ec1c92e067b58592155acf36ef7407.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值