spring hessian远程调用
2016-11-11 16:04
288 查看
hessian初识
在了解hessian之前,一般的java远程方法调用无非就是下面几种:1. http请求访问接口返回json数据(这是比较常见的方式)。
2. Java RMI (Remote Method Invocation)。
3. EJB远程接口调用。(没具体了解和应用过,有兴趣的同学可以去该篇博客去看看。什么是EJB)
4. Hessian以及Spring HttpInvoker。
有遗漏的别喷哈。
Hessian像RMI一样,使用二进制消息进行客户端和服务端的交互,它的二进制消息可以移植到其他非Java的语言中包括PHP、Python、C++和C#。因为Hessian是基于HTTP的,所以HessianSeriviceExporter实现为一个spring MVC控制器。
hessian的spring整合
在公司的项目中,我们的hessian远程调用是这样的,分为3个项目:1.接口项目
某些数据库的共用数据我们需要在其他几个项目中访问,为此没必要在每个项目中都重复的写这些访问数据库的实现,所以提出了写一个远程调用的项目来为这几个项目提供远程调用。(不是同一个数据库的访问)。此接口项目只是定义一些业务层的接口。我的例子里面是用maven项目的,这里的项目结构就是普通的javaweb项目结构,但是只有entity和service的结构。
domain的实体类
/** * 用户实体类 * @author kidd * */ public class User implements Serializable{ /** * */ private static final long serialVersionUID = 6022973364082179332L; private Integer id; private String name; private int sex; public User() { } public User(Integer id, String name, int sex) { this.id = id; this.name = name; this.sex = sex; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } }
业务层的接口
public interface UserService { /** * 通过主键id获取用户信息 * @param id 主键id * @return */ public User getUserById(int id); }
github项目地址:hessian_api_demo
2.服务端项目(也称接口项目的实现项目)
在此项目中,主要是实现接口项目定义的业务接口。在此例子中,只是简单的测试远程调用接口。需要配置spring上文的xml和远程调用的spring-remote.xml。
项目结构
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.kidd</groupId> <artifactId>hessian_remote_server</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <properties> <version.spring>4.2.5.RELEASE</version.spring> <version.logback>1.1.2</version.logback> <version.slf4j>1.7.6</version.slf4j> </properties> <dependencies> <!-- 导入的是api的项目,如果有用的nexus,可以将其打包后导入私服中,如没有直接用mavne命令加入本地仓库 --> <dependency> <groupId>com.kidd</groupId> <artifactId>hessian_remote_api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- spring dependency start --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${version.spring}</version> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${version.spring}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${version.spring}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${version.spring}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> <version>${version.spring}</version> </dependency> <!-- spring dependency end --> <!-- logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${version.slf4j}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${version.logback}</version> </dependency> <!-- 代码直接调用common-logging会被桥接到slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${version.slf4j}</version> </dependency> <dependency> <groupId>com.caucho</groupId> <artifactId>hessian</artifactId> <version>4.0.38</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.18</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>hessian_remote_server</finalName> </build> </project>
spring-remote.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" 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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <bean name="/userService" class="org.springframework.remoting.caucho.HessianServiceExporter"> <!-- 注意,这里的关联的bean是自动装配的,在impl的实现中,我给userService的实现类起了别名的 --> <property name="service" ref="userService" /> <property name="serviceInterface" value="com.kidd.api.service.UserService" /> </bean> </beans>
spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!-- bean配置扫描 --> <context:component-scan base-package="com.kidd.server.service"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" /> </context:component-scan> </beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.su 11c4d n.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>hessian_remote_server</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <filter> <filter-name>CharacterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置远程调用的servlet --> <servlet> <servlet-name>hessian</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-remote.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <!-- 配置前缀,在客户端项目中会用到 --> <servlet-name>hessian</servlet-name> <url-pattern>/remote/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
service实现类
/** * 远程调用的服务项目业务service实现类 * @author kidd * */ @Service("userService") public class UserServiceImpl implements UserService{ // @Autowired // private UserDao userDao; @Override public User getUserById(int id) { return new User(1, "张三", 1); // return userDao.getUserById(id); } }
项目github地址:hessian_remote_server
3.客户端项目
此项目作为调用远程服务的项目,需要引入api项目的依赖。没什么好说的,直接看配置和代码。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.kidd</groupId> <artifactId>hessian_client</artifactId> <packaging>war</packaging> <version>1.0.0</version> <!-- 参数配置 --> <properties> <!-- spring版本号 --> <spring.version>4.2.5.RELEASE</spring.version> <!-- jacksono版本号 --> <jackson.version>2.4.5</jackson.version> <!-- commons-logging版本号 --> <commons-logging.version>1.2</commons-logging.version> <slf4j.version>1.7.21</slf4j.version> </properties> <dependencies> <!-- 如果是当前工作区,可以不将api项目添加到本地的maven仓库中,如果不是,需要添加到maven仓库中,不然无法依赖 --> <dependency> <groupId>com.kidd</groupId> <artifactId>hessian_remote_api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- junit测试包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- 添加spring支持 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- (添加日志支持)代码直接调用common-logging会被桥接到slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <!-- 远程调用依赖 --> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>com.caucho</groupId> <artifactId>hessian</artifactId> <version>4.0.38</version> </dependency> </dependencies> <build> <finalName>hessian_client</finalName> </build> </project>
spring-common.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置自动扫描的包 --> <!-- 不扫描这两个包 --> <context:component-scan base-package="com.kidd.client.service,com.kidd.client.dao"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" /> </context:component-scan> <context:annotation-config /> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="2"></property> <property name="locations"> <list> <!-- 远程调用的配置 --> <value>classpath:config/resconfig.properties</value> </list> </property> </bean> <!-- 导入远程调用接口 --> <import resource="classpath:spring/spring-remote.xml" /> </beans>
spring-remote.xml(远程调用的xml配置)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- user接口 --> <bean name="userService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean"> <property name="serviceUrl" value="${remote.root}/userService" /> <property name="serviceInterface" value="com.kidd.api.service.UserService" /> </bean> </beans>
这里说明一下,注入的bean是api接口项目定义的UserService,这是hessian调用远程的bean的配置。
${remote.root}在resconfig.properties里面,指向的是服务端项目的地址。
resconfig.properties
#RPC_URL remote.root=http://localhost:9090/hessian_remote_server/remote
在服务端项目中,有在web.xml中配置了servlet的一个url地址,前缀是remote/*,所以调用时要写上完整的地址。
测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:spring/spring-common.xml" }) public class BaseTest { @Autowired private UserService userService; @Test public void testHessian(){ user = userService.getUserById(1); System.out.println(user); } }
我这里测试是成功的,能够远程调用服务端项目。
附上github地址:hessian_client_demo
相关文章推荐
- 《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用
- Spring使用Hessian实现远程调用
- 《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用
- Spring的Hessian,Burlap,HttpInvoker远程调用
- 《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用
- 《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用
- 远程服务调用之RMI、Hessian、Burlap、Spring的HTTPinvoker
- hessian远程调用及spring中使用hessian
- Spring + Hessian 实现轻量级分布式远程调用【包含rmi方式重构】
- Spring结合Hessian协议远程调用方法名不能重载
- Spring2.5远程调用Hessian的例子
- Spring+Hessian搭建远程方法调用
- spring技术内幕18-Spring使用Hessian实现远程调用
- Spring远程调用技术<2>-Hessian和Burlap
- Spring与远程调用RMI、Hessian、Burlap、HttpInvoker、Jax-WS
- Spring 与Hessian 整合的简单远程调用实例
- Spring使用Hessian实现远程调用
- 《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用
- 远程调用原理与对比RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB
- 关于远程调用(XFire/HttpInvoker/Hessian etc.)及远程服务管理的一些随想