这几天一直在学习远程调用只是,今天学习spring与hessian整合发布远程服务,研究了一天,各种错误,各种网上找答案。皇天不负有心人,总算整合出一个简单的demo。不多说直接,来点有营养的! 因为Hessian是基于Http协议的框架,所以服务端是一个web程序,结构如下 pom.xml依赖如下
<dependencies> <dependency> <groupId>com.caucho</groupId> <artifactId>hessian</artifactId> <version>4.0.7</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.5.RELEASE</version> </dependency> </dependencies>实体类spitter.java
package com.spittr.entity; import java.io.Serializable; public class Spitter implements Serializable { /** * */ private static final long serialVersionUID = 1563056272025335248L; private Long id; private String username; private String password; private String firstName; private String lastName; private String email; public Spitter() {} public Spitter(String username, String password, String firstName, String lastName, String email) { this(null, username, password, firstName, lastName, email); } public Spitter(Long id, String username, String password, String firstName, String lastName, String email) { this.id = id; this.username = username; this.password = password; this.firstName = firstName; this.lastName = lastName; this.email = email; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }spring 配置类
package com.spittr.config; import java.util.Properties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.remoting.caucho.HessianProxyFactoryBean; import org.springframework.remoting.caucho.HessianServiceExporter; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; import com.caucho.hessian.client.HessianProxyFactory; import com.spittr.remote.SpitterService; @Configuration @ComponentScan(basePackages = { "com.spittr.*" }) @EnableWebMvc public class MainConfig { // 创建hessian服务发布器,因为hessian是基于http的远程协议,因为需要发布为web应用 @Bean public HessianServiceExporter hessianExportSpitterService(SpitterService spitterService) { // Hessian没有注册表,因此也就没必要为Hessian服务进行命名 HessianServiceExporter exporter = new HessianServiceExporter(); exporter.setService(spitterService); exporter.setServiceInterface(SpitterService.class); return exporter; } //配置hessian映射处理器 @Bean public HandlerMapping hessianMapping() { SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); Properties mappings = new Properties(); mappings.setProperty("/spitter.service", "hessianExportSpitterService"); handlerMapping.setMappings(mappings); return handlerMapping; } }配置映射处理器,将/spitter.service 的请求转发到hessianExportSpitterService处理。 注意:这里handlerMapping 是SimpleUrlHandlerMappig,根据name来查询bean的,所以 可以看得出配置发布服务HessianServiceExporter 与Spring整合的java rmi远程代码很相似。
spring的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"> <!-- 启动注解 --> <context:annotation-config></context:annotation-config> <!-- 导入配置类 --> <beans:bean class="com.spittr.config.MainConfig"></beans:bean> </beans:beans>因为原先用的是java配置Spring,在这里直接将java配置导入到Spring xml配置中 web.xml如下
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.service</url-pattern> </servlet-mapping> --> </web-app>服务类
package com.spittr.remote; import java.util.List; import com.spittr.entity.Spitter; public interface SpitterService { public List<Spitter> getRencentSpitters(int count); public void saveSpitter(Spitter spitter); public Spitter getSpitter(long id); }实现类
package com.spittr.service; import java.util.List; import org.springframework.stereotype.Service; import com.spittr.entity.Spitter; import com.spittr.remote.SpitterService; @Service public class SpitterServiceImp implements SpitterService { public SpitterServiceImp() { // TODO Auto-generated constructor stub } @Override public List<Spitter> getRencentSpitters(int count) { // TODO Auto-generated method stub return null; } @Override public void saveSpitter(Spitter spitter) { System.out.println("save done"); } @Override public Spitter getSpitter(long id) { Spitter spitter = new Spitter(); spitter.setUsername("spitter " +id); spitter.setId(id); System.out.println(spitter.getUsername()); System.out.println(spitter); return spitter; } }启动tomacat并发布服务。
服务端项目结构 pom.xml
<dependencies> <dependency> <groupId>com.caucho</groupId> <artifactId>hessian</artifactId> <version>4.0.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> </dependencies>实体类与接口与服务端一直,同时注意包名的一致性。 Spring 配置类
package com.spittr.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.remoting.caucho.HessianProxyFactoryBean; import com.spittr.remote.SpitterService; @Configuration @ComponentScan(basePackages={"com.spittr.*"}) public class MainConfig { @Bean(name="spitterService") public HessianProxyFactoryBean spitterService(){ HessianProxyFactoryBean proxyFactoryBean = new HessianProxyFactoryBean(); proxyFactoryBean.setServiceUrl("http://localhost:8888/SpringHessianDemo/spitter.service"); proxyFactoryBean.setServiceInterface(SpitterService.class); return proxyFactoryBean; } }利用Spring容器获得一个远程代理工厂实例HessianProxyFactoryBean 。proxyFactoryBean提供了getObject方法,返回被代理的一个实例。 测试类:
package spittr.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.remoting.caucho.HessianProxyFactoryBean; import com.spittr.config.MainConfig; import com.spittr.entity.Spitter; import com.spittr.remote.SpitterService; public class ClientTest { @Test public void clientTest(){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); HessianProxyFactoryBean bean = applicationContext.getBean(HessianProxyFactoryBean.class); SpitterService spitterService=(SpitterService) bean.getObject(); Spitter spitter = spitterService.getSpitter(2); System.out.println(spitter); } }测试结果 客户端 服务端 测试成功!