具体使用请参考,这里主要看一下源码如何实现,以及和其他rpc框架的区别。
源码:
服务端配置:在spring-web包的org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter,该类继承了RemoteExporter,它内部两个属性service和serviceInterface,分别是远程服务接口和该服务的实现类,它主要提供HTTP协议封装和java对象序列化功能。
Spring的HttpInvokerServiceExporter(继承了HttpRequestHandler接口,可被适配器适配为HTTP请求处理器)是与Spring的MVC结合在一起的,它本质上是Spring MVC的一个Controller(所以要另外定义一个SimpleUrlHandlerMapping进行url映射),客户端发来的远程调用HTTP请求有Spring MVC的中央控制器DispatcherServlet转发到指定URL的HttpInvokerServiceExporter上。
<beans> <bean id="userService" class="com.service.impl.UserServiceImpl" /> <!-- 基于Url映射方式,这个配置,就是把userService接口,提供给远程调用 --> <bean id="httpService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> <property name="service" ref="userService"/> <property name="serviceInterface" value="com.service.UserService"/> </bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/test">httpService</prop> </props> </property> </bean>
客户端配置:在通过从工厂的getbean("httpTestService")方式,通过接口调用。
<bean id="httpTestService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> <property name="serviceUrl"> <value>http://localhost:8080/SpringHttp_Server/test</value> </property> <!-- 在客户端定义,或者抽出来当做公用定义接口 --> <property name="serviceInterface"> <value>com.service.UserService</value> </property> </bean>
1、在调用时,会通过HttpInvokerProxyFactoryBean作为一个ioc容器,对远程客户端封装。当通过getObject方法向Spring IoC容器索取远程调用对象时,触发afterPropertiesSet回调方法,创建远程调用的代理对象,最后将该远程调用代理对象返回。在创建远程调用代理对象时,使用其父类HttpInvokerClientInterceptor作为远程调用代理对象的拦截器,该拦截器将拦截对代理对象的方法调用。下面我们分析HttpInvokerClientInterceptor代理拦截器对代理对象的方法拦截处理。
2、当客户端通过HTTP请求调用远程调用代理的方法时,将会触发HttpInvokerClientInterceptor拦截器的invoke方法对当前的请求进行封装处理,将客户端的java对象序列化传输到服务器端,在远程服务器端执行完请求之后,又将处理结果java对象序列化返回给客户端。
3、拦截器将客户端对远程调用的HTTP请求封装成了MethodInvocation对象,拦截器的在调用远程调用的代理对象时,又将方法调用封装成了RemoteInvocation远程调用,RemoteInvocation数据对象中封装了调用的具体信息,如方法名、方法参数以及参数类型等。
真正执行远程调用的是HTTP调用请求执行器SimpleHttpInvokerRequestExecutor,下面我们继续分析SimpleHttpInvokerRequestExecutor远程调用的具体过程。
4、SimpleHttpInvokerRequestExecutor封装了基于HTTP协议的远程调用过程,HTTP调用请求执行器的处理逻辑是:首先,打开指定URL的HTTP连接,设置连接属性。其次,将封装请求的RemoteInvocation对象序列化到请求体中,请HTTP请求发送到服务器端。最后,从服务器端的HTTP响应中读取输入流,并将响应结果转换成RemoteInvocationResult。
将远程调用的HTTP响应转换为RemoteInvocationResult是由AbstractHttpInvokerRequestExecutor的readRemoteInvocationResult方法实现,下面我们将分析其将HTTP响应结果转换成RemoteInvocationResult的实现。
public class SimpleHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor { //HTTP调用请求执行器真正进行远程调用的方法,该方法有其父类//AbstractHttpInvokerRequestExecutor的executeRequest方法调用 protected RemoteInvocationResult doExecuteRequest( HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws IOException, ClassNotFoundException { //打开一个标准的J2SE HttpURLConnection HttpURLConnection con = openConnection(config); //准备连接 prepareConnection(con, baos.size()); //远程调用被封装成了RemoteInvocation对象,它通过序列化被写到对应的//HttpURLConnection中 writeRequestBody(config, con, baos); //获取远程调用的结果,校验返回的结果 validateResponse(config, con); InputStream responseBody = readResponseBody(config, con); //将远程调用结果转换成RemoteInvocationResult返回 return readRemoteInvocationResult(responseBody, config.getCodebaseUrl()); } //打开一个HttpURLConnection protected HttpURLConnection openConnection(HttpInvokerClientConfiguration config) throws IOException { //getServiceUrl()方法获取配置的远程调用URL,打开一个URL连接 URLConnection con = new URL(config.getServiceUrl()).openConnection(); if (!(con instanceof HttpURLConnection)) { throw new IOException("Service URL [" + config.getServiceUrl() + "] is not an HTTP URL"); } return (HttpURLConnection) con; } //准备HTTP请求连接 protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException { con.setDoOutput(true); //HTTP调用器只支持POST请求方法 con.setRequestMethod(HTTP_METHOD_POST); //设置HTTP请求头内容类型,设置为:application/x-java-serialized-object con.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, getContentType()); //设置HTTP请求头内容长度 con.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, Integer.toString(contentLength)); LocaleContext locale = LocaleContextHolder.getLocaleContext(); //设置HTTP请求的Locale if (locale != null) { con.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale.getLocale())); } //设置HTTP请求压缩方式 if (isAcceptGzipEncoding()) { con.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP); } } //把序列化对象输出到HTTP请求体中 protected void writeRequestBody( HttpInvokerClientConfiguration config, HttpURLConnection con, ByteArrayOutputStream baos) throws IOException { baos.writeTo(con.getOutputStream()); } //校验远程调用的HTTP响应 protected void validateResponse(HttpInvokerClientConfiguration config, HttpURLConnection con) throws IOException { //如果HTTP响应状态码大于等于300,则证明调用发生错误 if (con.getResponseCode() >= 300) { throw new IOException( "Did not receive successful HTTP response: status code = " + con.getResponseCode() + ", status message = [" + con.getResponseMessage() + "]"); } } //提取远程调用结果的HTTP响应信息 protected InputStream readResponseBody(HttpInvokerClientConfiguration config, HttpURLConnection con) throws IOException { //如果响应信息是Gzip压缩的,则需要先解压 if (isGzipResponse(con)) { return new GZIPInputStream(con.getInputStream()); } //正常的HTTP响应 else { return con.getInputStream(); } } //是否是Gzip格式压缩 protected boolean isGzipResponse(HttpURLConnection con) { //获取HTTP响应头信息中的压缩方式 String encodingHeader = con.getHeaderField(HTTP_HEADER_CONTENT_ENCODING); return (encodingHeader != null && encodingHeader.toLowerCase().indexOf(ENCODING_GZIP) != -1); } }
5、AbstractHttpInvokerRequestExecutor中处理远程调用结果,并HTTP响应转换成RemoteInvocationResult的主要方法如下:
//从HTTP响应中读取远程调用结果入口方法 protected RemoteInvocationResult readRemoteInvocationResult(InputStream is, String codebaseUrl) throws IOException, ClassNotFoundException { //根据给定的输入流和类创建对象输入流 ObjectInputStream ois = createObjectInputStream(decorateInputStream(is), codebaseUrl); try { //从对象输入流中读取远程调用结果 return doReadRemoteInvocationResult(ois); } finally { ois.close(); } } //从对象输入流中读取远程调用结果 protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois) throws IOException, ClassNotFoundException { //获取对象输入流中的对象 Object obj = ois.readObject(); if (!(obj instanceof RemoteInvocationResult)) { throw new RemoteException("Deserialized object needs to be assignable to type [" + RemoteInvocationResult.class.getName() + "]: " + obj); } //将获取到的对象封装为RemoteInvocationResult return (RemoteInvocationResult) obj; }
相关推荐
**Spring HttpInvoker的封装** 在Java企业级应用开发中,Spring框架因其强大的功能和灵活性而被广泛应用。HttpInvoker是Spring框架的一部分,它提供了一种基于HTTP协议的远程调用机制,使得不同网络环境中的Java...
Spring HttpInvoker,是一套基于Maven+Spring+SpringMVC+MyBatis框架,还包含了Invoker的客户端及服务器端的demo实例
公司内部讲义,比较了SOA,RMI和Spring HttpInvoker。并介绍了Spring HttpInvoker的基本使用方法。
org.springframework.remoting.httpinvoker最基本的实现例子,这是3个eclipse的JavaEE工程,全部导入即可,能运行。 初学可以轻松了解Spring HttpInvoker 的结构和使用。
<bean id="serviceExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> ``` 这里,`ServiceImpl`是你实现`ServiceInterface`的具体类,`HttpInvokerServiceExporter`将...
在分布式系统中,远程服务调用是常见的需求,Spring框架提供了多种远程服务支持,其中包括HttpInvoker。HttpInvoker是Spring框架的一部分,它允许开发者使用HTTP协议进行远程方法调用,而不需要额外的类库。与...
Spring httpInvoker使用标准java序列化机制,通过Http暴露业务服务。如果你的参数和返回值是比较复杂的,通过httpInvoker有巨大的优势。 1. 远程访问流程 1) 服务端定义服务接口 2) 服务端实现服务接口 3) 暴露服务...
同时,使用`@HttpInvokerService`注解暴露该服务,指定远程访问的URL。 3. 配置服务消费方:在服务消费方,使用`@HttpInvokerProxyFactoryBean`来创建服务代理,指定服务的URL和接口类型。这样,消费方就可以像调用...
NULL 博文链接:https://lggege.iteye.com/blog/369151
Spring HTTP Invoker是spring框架中的一个远程调用模型,执行基于HTTP的远程调用,也就是说,可以通过防火墙,并使用java的序列化机制在网络间传递对象。客户端可以很轻松的像调用本地对象一样调用远程服务器上的...
Java Spring 2.5 Remote Invoke HTTP Invoker 是一个基于HTTP协议的远程调用框架,它允许Spring应用通过HTTP协议来调用远程服务。这个技术在分布式系统中非常有用,因为它可以轻松地跨越网络边界,实现服务间的通信...
3. **配置HTTP Invoker**:在服务端配置Spring,启用HTTP Invoker的支持,将接口绑定到特定的URL路径上,以便客户端可以访问。 4. **客户端构建请求**:在客户端,我们需要创建一个HTTP Invoker的代理对象,该对象...
在IT行业中,Thrift和Spring Http Invoker是两种常见的服务通信框架。Thrift是由Facebook开源的一种高性能、跨语言的服务框架,而Spring Http Invoker是Spring框架的一部分,用于实现基于HTTP的远程方法调用。这篇...
在分布式系统中,远程调用是一个常见需求,Spring为此提供了一种轻量级的解决方案——HttpInvoker。本文将详细讲解如何利用Spring的HttpInvoker进行远程方法调用。 首先,我们需要理解什么是Spring HttpInvoker。...
**Http Invoker:接口测试工具详解** Http Invoker是一款用于接口测试的工具,它允许开发者对Web服务进行调用和测试,验证API的功能和性能。虽然在某些用户看来,Http Invoker可能并不是最易用或者功能最全面的工具...
Spring HTTP Invoker是Spring框架提供的一个远程调用模型,它允许通过HTTP进行远程调用,这意味着可以在防火墙环境下实现服务间的通信。与传统的远程过程调用(RPC)不同,Spring HTTP Invoker简化了客户端和服务端...
Java Spring 1.2 远程调用HTTP Invoker是一个基于HTTP协议的远程服务调用框架,它是Spring框架的一部分,允许应用通过HTTP协议进行服务间的通信。这种通信方式相对于RMI(Remote Method Invocation)等其他远程调用...
基于Spring的HttpInvoker实现改写服务器端调用: HttpInvoker.invoker 方法,设置InvokerProcess处理客户端调用: ProxyFactory.proxy 方法,生成接口的代理对象,直接调用方法客户端和服务器端的接口和实体类要...
`Http Invoker`是Spring框架提供的一种基于HTTP协议的RPC实现,主要用于Java应用程序之间进行服务调用。本文将深入探讨如何使用Http Invoker实现RCP客户端与后台的交互,以及相关知识点。 1. **Http Invoker的基本...
HttpInvoker主要面向Spring应用程序,易于集成,但相比Hessian,其数据传输效率较低,因为HTTP协议本身较重,且Java序列化也相对消耗资源。 XFire(后来被Apache CXF吸收)是一款基于XML的Web服务框架,它支持多种...