spring开发远程访问web服务

spring为各种远程访问技术的集成提供了整合类,spring支持的远程技术有以下这些:
1.远程方法调用(RMI)。通过使用RmiProxyFactoryBean和RmiServiceExporter,spring同时支持传统rmi(使用java.rmo.Remote接口和java.rmi.RemoteException)和通过RMI调用器实现的透明远程调用(支持任何java接口)
2.spring的HTTP调用器。spring提供了一种允许通过HTTP进行串行化的特殊远程调用策略,他支持任意java接口(就像rmi调用器)。相应的支持类是HttpInvokerProxyFactoryBean和HttpInvokerServiceExporter。
3.Hessian。通过HessianProxyFactoryBean和HessianServiceExporter,可以使用Caucho提供的基于HTTP轻量级二进制协议来透明的暴露服务。
4.Burlap。Burlap是caucho基于XML用来替代Hessian的项目。spring提供了诸如BurlapProxyFactoryBean和BurlapServiceExporter的支持类。
5.JAX RPC。
6.JAX-WS。
7.JMS,通过JmsInvokerServiceExporter和JmsInvokerProxyFactoryBean使用JMS作为底层协议提供远程服务。
框架

优点

缺点
rmi

全面支持java对象串行化。因此,你能够通过网络发送复杂数据类型。

rmi仅是一种java到java型远程方案。如果你拥有任何非java客户端的话,那么你无法使用它。另外,你还无法通过http协议存取对象,除非你有专门的“通道”实现rmi通讯。注意,它需要一个rmi编译器(为了生成代理和框架)和一个外部注册表(用于查询服务)。
hessian/burlap

跨防火墙工作良好

它们使用一种专利对象串行化机制。其中,burlap仅支持java客户端。它们能够串行化hibernate对象,但是对集合对象执行“惰式”加载。
http invoker

基于http的java到java remoting;通过http实现java串行化;容易建立。

服务器和客户端应用程序都需要使用spring。
仅是一种java方案。
ejb

支持remoting j2ee服务,应用程序安全以及事务处理

ejb是一种重量级技术。它要求使用一个j2ee容器。
web服务

平台和语言独立

要付出soap操作所带来的开销,并且要求使用一个web服务引擎。
下面是做一个基于HTTP调用器的demo。
首先web.xml中需要配置spring的监听和mvc的dispatcher
引用

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

<!--spring 启动配置 -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<!-- 配置spring service 发布服务远程访问 -->
<servlet>
<servlet-name>remoteService</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:remote/service-exporter.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>remoteService</servlet-name>
<url-pattern>/remote/*</url-pattern>
</servlet-mapping>



然后,你可以写一个接口类和一个实现类。
引用

public interface IUserRemoteService {

public abstract String hello(String name);

}

@Service("userRemoteService")
public class UserRemoteService implements IUserRemoteService {

/* (non-Javadoc)
* @see com.huawei.iread.portal.service.remote.server.IUserRemoteService#hello(java.lang.String)
*/
public String hello(String name){
return "hello:"+name;
}

}
注意,我这里使用了spring的注解,至于注解的用法,不再详细介绍。

然后要做的就是发布服务。
引用
<bean name="/userRemoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="userRemoteService" />
<property name="serviceInterface" value="com.huawei.bportal.portal.service.remote.server.IUserRemoteService"></property>
</bean>



然后是客户端的配置
随意写一个接口,名称可以自定义,如果服务的发布使用了复杂类型的java对象,可以将服务的java对象和接口打成jar包引入到client项目中,如果是简单的字符串类型调用返回,就不必了。这是我客户端的接口,方法名和服务端的方法名保持了一致。
引用
public interface MyTestRemoteService {

String hello(String name);


}

这是xml配置
引用

<bean name="testRemoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="${spring.httpInvoker.uri}/userRemoteService" />
<property name="serviceInterface" value="com.huawei.bportal.portal.service.remote.client.MyTestRemoteService"></property>
<!-- 若用默认可不定义此属性 -->
    <property name="httpInvokerRequestExecutor" ref="httpInvokerRequestExecutor"></property>
</bean>
<!--  单线程
    <bean  id="httpInvokerRequestExecutor" class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor"> 
        <property  name="httpClient"> 
            <bean  class="org.apache.commons.httpclient.HttpClient"> 
                <property   name="connectionTimeout"  value="2000" /> 
                <property  name="timeout"  value="5000" /> 
            </bean> 
        </property> 
    </bean>-->
   
    <bean  id="httpInvokerRequestExecutor" class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor"> 
        <property name="httpClient" ref="httpclient" />
    </bean>
    <!--  HttpClient 启用Apache HttpClient 通信
        默认实现,服务器平均10s左右才能响应一个请求。
        多线程实现,服务器平均20ms左右响应一个请求。 --> 
     <bean id="httpclient" class="org.apache.commons.httpclient.HttpClient">   
        <constructor-arg>   
            <ref bean="connectionManager"/>   
        </constructor-arg>    
    </bean> 
   
     <!-- http管理参数配置 --> 
    <bean id="connectionManager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">   
        <property name="params" ref="connectionManagerParams"/>   
    </bean>  
     
    <!-- httpclient线程池 -->   
    <bean id="connectionManagerParams" class="org.apache.commons.httpclient.params.HttpConnectionManagerParams"> 
        <!-- 设置 连接超时时间(毫秒),默认为0不使用 -->   
        <property name="connectionTimeout" value="5000"/>  
        <!-- 设置 读取数据超时(毫秒),默认为0不使用 -->  
        <property name="soTimeout" value="10000"/>   
        <!-- 设置默认的连接数量最大允许对一个给定的主机配置 --> 
        <property name="maxTotalConnections" value="30"/> 
        <!-- 允许的最大连接数 -->   
        <property name="defaultMaxConnectionsPerHost" value="20"/>   
    </bean>

其中${spring.httpInvoker.uri}是服务端的地址,ip加端口号。

下面的调用的方法
引用
//注入来自server端的接口
@Autowired @Qualifier("testRemoteService")
private MyTestRemoteService remoteService;

public String showUser() {
logger.info("测试spring-rmi:"+remoteService.hello("aaaa"));
return SUCCESS;
}
返回hello aaaa就基本成功了完成了

猜你喜欢

转载自charsli.iteye.com/blog/1718262