java RPC系列之二 HTTPINVOKER

java RPC系列之二  HTTPINVOKER

一、java RPC简单的汇总

  java的RPC得到技术,基本包含以下几个,分别是:RMI(远程方法调用) 、Caucho的Hessian 和 Burlap 、Spring的基于HTTP的远程服务、以及使用JAX-RPC和JAX-WS的Web服务。本文主要介绍spring的httpinvoker的基本的配置实现。

二、Springhttpinvoker的配置实现

基本步骤:

      1.定义好服务端需要提供的接口方法(客户端调用的接口);

      2.定义好服务端的实现代码;

      3.使用spring配置服务端,发布服务到制定端口;

      4.使用spring配置客户端的代理bean;

      5.定义好服务端和客户端调用的测试代码。

三、Springhttpinvoker的配置实现的代码如下:

   1.定义好ISayHello接口类,服务端和客户端都需要的接口类。

package com.lilin.maven.maven_intf;

/**
 * @author lilin
 *
 */
public interface ISayHello {
    /**
     * 测试接口接口方法
     */
    void sayHello(String name);

}

2.定义好服务端的实际实现代码SayHelloService。

package com.lilin.maven.maven_intf;

/**
 * @author lilin
 *
 */
public class SayHelloService implements ISayHello {

    @Override
    public void sayHello(String name) {
        System.out.println("hello:" + name);
    }

}

3.使用spring的配置spring的httpinvoker服务,配置web.xml中的servlet,配置rmi-server.xml文件,将配置的service的bean发布为HTTP服务。

servlet配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>SpringRMI</display-name>
    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:/remote-servlet.xml</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

rmi-server的配置:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="sayHello" class="com.lilin.maven.maven_intf.SayHelloService" />
    <bean name="/sayHello"
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="sayHello" />
        <property name="serviceInterface" value="com.lilin.maven.maven_intf.ISayHello" />
    </bean>
</beans>

4.使用spring配置客户端的代理bean,配置rmi-client.xml,把远程的服务方法配置为bean,可以方便注入。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="sayHello"
        class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="serviceUrl">
            <value>http://localhost:8080/maven-web-in/sayHello</value>
        </property>
        <property name="serviceInterface">
            <value>com.lilin.maven.maven_intf.ISayHello</value>
        </property>
    </bean>

</beans>

 5.定义好服务端和客户端调用的测试代码,首先启动服务端,发布HTTP服务,然后启动测试端代码通过HTTP调用远程服务。

服务端:启动server后,可以看到如下信息:

信息: Mapped URL path [/sayHello] onto handler ‘/sayHello‘
2016-3-29 0:38:51 org.springframework.web.servlet.FrameworkServlet initServletBean
信息: FrameworkServlet ‘Spring MVC Dispatcher Servlet‘: initialization completed in 1670 ms
2016-3-29 0:38:51 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["http-bio-8080"]
2016-3-29 0:38:51 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
2016-3-29 0:38:51 org.apache.catalina.startup.Catalina start
信息: Server startup in 5547 ms则表示当前的发布服务成功!

  客户端:获取client配置的bean,直接调用远程服务方法,可以得到正确结果如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lilin.maven.maven_intf.ISayHello;

/**
 * 客户端调用类
 *
 * @author King
 *
 */
public class Client {
    // 读取配置文件
    static ApplicationContext context = new ClassPathXmlApplicationContext(
            "remote-client-local.xml");

    public static void main(String[] args) {
        new Client().sayHello();
    }

    public void sayHello() {
        ISayHello sayHello = (ISayHello) context.getBean("sayHello");
        sayHello.sayHello("李林");
    }

}

到此简单的spring的httpinvoker的远程服务调用,基于spring的配置就全部结束了,值得注意的是:

spring的httpinvoker的使用场景:考虑网络限制,并且希望使用基于xml或者专有的java序列化机制时候哦,访问/发布基于spring的服务。

参见的是spring in action 第三版

时间: 2024-10-09 21:07:20

java RPC系列之二 HTTPINVOKER的相关文章

Java 集合系列之二:List基本操作

1. Java List 1. Java List重要观点 Java List接口是Java Collections Framework的成员. List允许您添加重复元素. List允许您拥有'null'元素. List接口在Java 8中有许多默认方法,例如replaceAll,sort和spliterator. 列表索引从0开始,就像数组一样. List支持泛型(类型的参数化),我们应尽可能使用它.将Generics与List一起使用将在运行时避免ClassCastException. 2

深入理解java虚拟机系列(二):垃圾收集器与内存分配策略

第一篇,点这里  深入理解java虚拟机系列(一):java内存区域与内存溢出异常 先直接上结构图,笔记下一次补上,结构图如下:

java se系列(十二)集合

1.     集合 1.1. 什么是集合 存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式. 集合的出现就是为了持有对象.集合中可以存储任意类型的对象, 而且长度可变.在程序中有可能无法预先知道需要多少个对象, 那么用数组来装对象的话, 长度不好定义, 而集合解决了这样的问题. 1.2. 集合和数组的区别 数组和集合类都是容器 数组长度是固定的,集合长度是可变的.数组中可以存储基本数据类型,集合只能存储对象数组中存储

Java基础系列之(二) - 线程

一.线程的实现方式 1.继承Thread 2.实现Runnable接口 二.线程的状态 1.New(新生线程) 当你new一个Thread,newThread(r),这时处于线程的新生状态,此时程序还没有真正的运行. 2.Runnable(可运行的) 当启动start()方法时,此时线程处于可运行状态,不一定运行之中,这取决与线程是否得到CPU的运行时间片.事实上,一个线程并不是一直处于运行状态,偶尔需要被中断,让其他线程有运行的机会. 3.Blocked(被阻塞) 当发生以下情况被阻塞 -线程

JAVA NIO系列(二) Channel解读

Channel就是一个通道,用于传输数据,两端分别是缓冲区和实体(文件或者套接字),通道的特点(也是NIO的特点):通道中的数据总是要先读到一个缓冲区,或者总是要从一个缓冲区中读入. Channel的分类 1) FileChannel:从文件中读写数据 2) SocketChannel:通过TCP协议读写网络中的数据 3) ServerSocketChannel:在服务器端可以监听新进来的TCP连接,像WEB服务器那样,对每一个新进来的请求创建一个SocketChannel 4) Datagra

java学习系列之二---字符串(char.String.StringBuilder以及StringBuffer)

一.String 1.String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的.String类是被final修饰 2.String str="hello world"和String str=new String("hello world")的区别 public class Main {              public static void main(String[] args) {         String s

Java 集合系列(二)—— ArrayList

ArrayList ArrayList 是通过一个数组来实现的,因此它是在连续的存储位置存放对象的引用,只不过它比 Array 更智能,能够根据集合长度进行自动扩容. 假设让我们来实现一个简单的能够自动扩容的数组,我们最容易想到的点就是: add()的时候需要判断当前数组size+1是否等于此时定义的数组大小: 若小于直接添加即可:否则,需要先扩容再进行添加. 实际上,ArrayList的内部实现原理也是这样子,我们可以来研究分析一下ArrayList的源码 add(E e) 源码分析 1 /*

java多线程系列(二)

对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解能让知识更加简单易懂. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线程系列(三)之等待通知机制 java多线程系列(四)之ReentrantLock的使用 线程安全 线程安全就是多线程访问时,采用了加锁机制,当一个

java多线程系列(三)

等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解能让知识更加简单易懂. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线程系列(三)之等待通知机制 java多线程系列(四)之ReentrantLock的使用 非等待通知 public void run() { try {