Spring远程服务----HttpInvoker实现远程调用

本文介绍了Spring的HttpInvoker服务调用,它结合了RMI和Hessian/Burlap的优点,解决了防火墙问题并使用Java标准序列化。内容包括HttpInvoker的核心类、服务端和客户端实现,以及测试和限制。HttpInvokerServiceExporter用于服务端,HttpInvokerProxyFactoryBean则用于客户端生成代理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.简介

    前面说过RMI远程服务使用的是Java标准的对象私有序列化机制,但很难穿越防火墙,而Hessian/Burlap远程服务是基于HTTP的服务,所以不受防火墙限制,但采用了私有的对象序列化机制。Spring框架的HttpInvoker服务综合了RMI服务和Hessian服务的优点,解决了防火墙问题以及采用了Java标准的对象系列化方式。

    Spring整合Hessian远程服务调用与Spring整合HttpInvoker服务调用方式是一样的,仅是在服务端将HessianServiceExporter替换为org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter,客户端只要将HessianProxyFactoryBean换成org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean。因此本文只介绍Java类配置方式,不再介绍XML配置方式。如果想了解XML配置,可参照Hessian远程服务调用方式(Spring远程服务----Hessian和Burlap实现远程调用)。

2.介绍

HttpInvoker远程服务调用中一些重要的类:

  • DispatcherServlet/HttpRequestHandlerServlet:负责将符合配置URL的访问路径的请求转给URL控制器,最终被HttpInvokerServiceExporter处理。
    - HttpInvokerServiceExporterHttpInvokerServiceExporter是一个Spring MVC控制器,可以接收客户端请求,并将这些请求转换成对Spring bean的方法调用。
    在这里插入图片描述
  • HttpInvokerProxyFactoryBeanHttpInvokerProxyFactoryBean是一个代理工厂,用于生成一个代理,该代理使用Spring特有的基于Http协议进行远程通信。

在这里插入图片描述
项目介绍:
——Common项目

  • 服务端和客户端都要使用接口和实体类,将实体类和接口定义到公共项目Common中,打成jar包,在客户端和服务端添加jar包依赖。
<!--common(实体和接口)的jar依赖-->
     <dependency>
      	<groupId>com.corp</groupId>
		<artifactId>common</artifactId>
		<version>1.0.0</version>
     </dependency>

——HttpInvoker服务端:服务端,实现common中的接口,提供HttpInvoker远程服务。

——HttpInvoker客户端:客户端,将远程服务HttpInvoker的代理注入,进行服务的调用。

2.1 Common
  • 实体类Account
    为了远程传输实体类,实体类要实现Serializable接口。
public class Account implements Serializable {

 private static final long serialVersionUID = 1L;
 private String name;

 public String getName() {
   return name;
 }
 public void setName(String name) {
   this.name = name;
 }
 @Override
 public String toString() {
   return "Account [name=" + name + "]";
 }
}
  • 接口AccoutService
public interface AccountService {
  public void insertAccount(Account account);
  public List<Account> getAccounts(String name);
}
2.2 HttpInvokerServer

步骤一:编写接口实现类AccountServiceImpl

@Service
public class AccountServiceImpl implements AccountService{

  public void insertAccount(Account account) {
    return;
  }

  public List<Account> getAccounts(String name) {
    List<Account> accounts = new ArrayList<>();
    Account account = new Account();
    account.setName("DreamTech1113");
    accounts.add(account);
    return accounts;
  }
}

步骤二:类配置方式创建DispatcherServletContextLoadListener

在Servlet3.0环境中,容器会在类路径中查找javax.servlet.ServletContainInitializer接口的类,如果能发现,就会用它来配置Servlet容器,Spring提供了该接口的实现,名称为SpringServletContainInitializer,这个类又会查找实现WebApplicationInitializer的类并将配置的任务交给他们来完成。Spring3.2中引入了一个便利的WebApplicationInitializer基础实现,即AbstractAnnotationConfigDispatcherServletInitializer。因此部署到Servlet3.0时,会以AbstractAnnotationConfigDispatcherServletInitializer类或者扩展类来配置Servlet上下文。

AbstractAnnotationConfigDispatcherServletInitializer会同时创建DispatcherServletContextLoadListener.继承此类重写三个方法:

  • getServletConfigClasses():方法返回的带有@Configuration的注解的类会用来定义DispatcherServlet应用上下文中的bean。
  • getRootConfigClasses():方法返回的带有@Configuration注解的类将用来配置ContextLoadListener创建的应用上下文中的bean。
  • getServletMappings():为DispatcherServlet配置Servlet映射。
public class AccountWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] {WebConfig.class};
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] {RootConfig.class};
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] {"/httpinvoker/*"};
  }
}
@Configuration
//开启包扫描
@ComponentScan(basePackages="com.spring")
public class WebConfig {
  @Bean
  public HttpInvokerServiceExporter accountExporter(AccountService accountService) {
    HttpInvokerServiceExporter httpInvokerExporter = new HttpInvokerServiceExporter();
    httpInvokerExporter.setService(accountService);
    httpInvokerExporter.setServiceInterface(AccountService.class);
    return httpInvokerExporter;
  }
 
  @Bean
  public HandlerMapping httpInvokerMapping() {
    SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    Properties mappings = new Properties();
    //当访问路径是/httpInvoker/accountExporter时,Servlet会请求转给accountExporter方法
    mappings.setProperty("/accountExporter","accountExporter");
    mapping.setMappings(mappings);
    return mapping;
  }
}
@Configuration
@ComponentScan(basePackages="com.spring")
public class RootConfig {
  
}

将服务端项目HttpInvokerServer放到tomcat中,启动tomcat(端口是8080)

2.3 HttpInvokerConsumer

为了方便客户端启动一个tomcat,我们使用SpringBoot项目,将客户端项目的tomcat端口修改为8889,在src/main/resources目录下面新建文件application.properties,内容为

server.port=8889

步骤一:编写服务调用层HttpInvokerContoller

@RestController
public class HttpInvokerController {

  private AccountService accountService;

  @Autowired
  public void setAccountService(AccountService accountService) {
    this.accountService = accountService;
  }
  
  @RequestMapping("/home")
  public List<Account> getAccount() {
    List<Account> accounts = accountService.getAccounts("name");
    return accounts;
  }  
}

步骤二:Java类配置HttpInvoker客户端代理。

@Configuration
public class HttpInvokerClientConfiguration {

  @Bean
  public HttpInvokerProxyFactoryBean httpInvokerProxy() {
    HttpInvokerProxyFactoryBean httpInvokerProxy = new HttpInvokerProxyFactoryBean();
    //标识服务所实现的接口
    httpInvokerProxy.setServiceInterface(AccountService.class);
    //远程服务的地址
    httpInvokerProxy.setServiceUrl("http://localhost:8080/httpinvoker_server/httpinvoker/accountExporter");
    return httpInvokerProxy;
  }
}

步骤三SpringBoot项目启动类。

@SpringBootApplication
@ComponentScan(basePackages="com.spring")
public class Application {
    public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
    }
}
3.测试

页面输入网址:http://localhost:8889/home,结果:

[{“name”:“DreamTech1113”}]

4.问题

HttpInvoker服务综合了RMI服务和Hessian/Burlap服务的优点,但也存在一定限制:

  1. HttpInvoker服务仅是Spring框架所提供的远程服务调用方案,这就意味着客户端和服务端都必须是Spring应用。这暗含客户端和服务端都必须是基于java的。
  2. 由于使用的是java序列化机制,客户端和服务端必须使用相同的版本。
5.参考文档

  1.Spring官方文档
  2.《Spring实战(Spring IN ACTION)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值