spring httpinvoker小结

在最近给客户做的两个系统之间,有一些需要相互调用的地方,因为两个系统的架构基本相同,都是采用的spring mvc + mybatis,所以尝试使用了一下spring httpinvoker。目前系统访问平稳,用户量也不是很大,没有出现什么问题。

现在常见的远程调用,主要有RMI、 spring httpinvoker、 hessian、 burlap、 web services、 protobuf等。各种方式都有自己的优缺点,网上有很多相关的对比,这里就不再赘述。但是对于两个都是java开发的系统而言,spring httpinvoker应该是综合了传输效率和开发效率的比较好的方式。

spring invoker调用流程图

spring httpinvoker interaction

spring httpinvoker示例

使用了maven开发,三个工程:

hello-remoting-interface

hello-remoting-server

hello-remoting-client

hello-remoting-interface

定义接口和使用到的实体

hello remotin interface project

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.riwcwt</groupId>
	<artifactId>hello-remoting-interface</artifactId>
	<packaging>jar</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>hello-httpinvoker-interface</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>3.2.10.RELEASE</spring.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</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-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.7</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.3.5</version>
		</dependency>
	</dependencies>
</project>

UserService.java

package com.riwcwt.remoting.service;

import java.util.List;

import com.riwcwt.remoting.entity.Role;
import com.riwcwt.remoting.entity.User;

public interface UserService
{
	public List<User> getAllUsers();

	public List<Role> getRolesByUser(User user);
}
hello-remoting-server

服务提供方

hello remoting server project

web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Archetype Created Web Application</display-name>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/*-context.xml</param-value>
	</context-param>

	<!-- 防止发生java.beans.Introspector内存泄露,应将它配置在ContextLoaderListener的前面 -->
	<listener>
		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener </listener-class>
	</listener>

	<!-- 设置WEB应用字符集,也是通过过滤器完成的 -->
	<filter>
		<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- Spring MVC 的Servlet,它将加载WEB-INF/mvc-dispatcher.xml 的 配置文件, 以启动Spring 
		MVC模块 -->
	<servlet>
		<servlet-name>mvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath*:spring/mvc-dispatcher.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>mvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>/index.jsp</welcome-file>
	</welcome-file-list>

</web-app>

UserServiceImpl.java

package com.riwcwt.remoting.service;

import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.riwcwt.remoting.entity.Role;
import com.riwcwt.remoting.entity.User;

@Service(value = "userService")
public class UserServiceImpl implements UserService
{

	private static Logger logger = Logger.getLogger(UserServiceImpl.class);

	@Override
	public List<User> getAllUsers()
	{
		logger.info("invoke the first one");
		List<User> users = new LinkedList<User>();
		for (int i = 0; i < 2; i++)
		{
			User user = new User();
			user.setUsername("username " + i);
			user.setDescription("description " + i);

			List<Role> roles = new LinkedList<Role>();

			Role admin = new Role();
			admin.setRoleName("amin");
			Role manager = new Role();
			manager.setRoleName("manager");

			roles.add(admin);
			roles.add(manager);

			user.setRoles(roles);

			users.add(user);
		}
		return users;
	}

	@Override
	public List<Role> getRolesByUser(User user)
	{
		logger.info("invoke the second one");
		List<Role> roles = new LinkedList<Role>();
		Role admin = new Role();
		admin.setRoleName("amin");
		Role manager = new Role();
		manager.setRoleName("manager");
		roles.add(admin);
		roles.add(manager);
		return roles;
	}

}

mvc-dispatcher.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:aop="http://www.springframework.org/schema/aop"
	xmlns:lang="http://www.springframework.org/schema/lang" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
		 http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/lang
         http://www.springframework.org/schema/lang/spring-lang.xsd
         http://www.springframework.org/schema/context 
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/mvc   
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">
	
	<!-- 设置使用注解的类所在的jar包 -->
	<context:component-scan base-package="com.riwcwt.remoting.service"></context:component-scan>

	<bean name="/user-service"
		class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
		<property name="service" ref="userService" />
		<property name="serviceInterface" value="com.riwcwt.remoting.service.UserService" />
	</bean>

</beans>
hello-remoting-client

客户端调用服务

application-context.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd      
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd    
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd  
	http://www.springframework.org/schema/jee
	http://www.springframework.org/schema/jee/spring-jee.xsd       
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx.xsd   
	http://www.springframework.org/schema/jdbc
	http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
	http://www.springframework.org/schema/data/jpa
	http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

	<!-- 导入属性配置文件 -->
	<context:property-placeholder location="classpath*:remoting.properties" />

	<bean id="userService"
		class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
		<property name="serviceUrl"
			value="http://${remoting.host}:${remoting.port}/${remoting.context}/user-service">
		</property>
		<property name="serviceInterface" value="com.riwcwt.remoting.service.UserService">
		</property>
		<!-- 修改默认的HTTP请求链接方式,提升连接效率 -->
		<property name="httpInvokerRequestExecutor">
			<bean
				class="org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor">
			</bean>
		</property>
	</bean>

</beans>

测试用例代码

package com.riwcwt.remoting.service;

import java.util.List;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.riwcwt.remoting.entity.Role;
import com.riwcwt.remoting.entity.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring/application-context.xml")
public class UserServiceTest
{
	@Resource(name = "userService")
	private UserService userService = null;

	@Test
	public void testGetAllUsersByHttpInvoker() throws InterruptedException
	{
		List<User> users = this.userService.getAllUsers();
		for (User user : users)
		{
			System.out.println(user.getUsername() + " " + user.getDescription());
			for (Role role : user.getRoles())
			{
				System.out.println(role.getRoleName());
			}
		}

	}

	@Test
	public void anotherTest()
	{
		for (int i = 0; i < 5; i++)
		{
			User user = new User();
			user.setUsername("test");
			List<Role> roles = this.userService.getRolesByUser(user);
			for (Role role : roles)
			{
				System.out.println(role.getRoleName());
			}
		}
	}
}

server和client工程都依赖于interface工程,这样就方便于开发。通过上面的例子,可以看出spring httpinvoker是很方便于做远程调用的,其实spring对于rmi、hessian、burlap也提供了几乎和上面配置一样的调用,只是serviceexpoter和factoorybean不同,这里就不再一一做示例。

转载于:https://my.oschina.net/liting/blog/535277

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值