天天看点

hessian学习         hessian入门example    hessian简介 hessian例子的一些延伸

        在webservice学习中提到了hessian,二者核心的不同数据传输模式,一个是xml,一个是二进制,今天对hessian学习做个回顾

         hessian的学习官网(hessian)

         hessian入门example

新建一个maven的web项目 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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>stu</groupId>
		<artifactId>stu</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>hessian</artifactId>
	<packaging>war</packaging>
	<dependencies>
		<!-- https://mvnrepository.com/artifact/com.caucho/hessian -->
		<dependency>
			<groupId>com.caucho</groupId>
			<artifactId>hessian</artifactId>
			<version>4.0.38</version>
		</dependency>
		
<!-- 		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency> -->
	</dependencies>
</project>
           

web.xml

<web-app>
  <servlet>
   <servlet-name>hello</servlet-name>
   <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
   <!--api实现类-->
    <init-param>
      <param-name>home-class</param-name>
      <param-value>server.BasicService</param-value>
    </init-param>
    <!--api-->
    <init-param>
      <param-name>home-api</param-name>
      <param-value>server.BasicAPI</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <url-pattern>/hello</url-pattern>
    <servlet-name>hello</servlet-name>
  </servlet-mapping>
</web-app>
           

BasicAPI

package server;

public interface BasicAPI {
	public String hello();
}
           

BasicService

package server;

public class BasicService implements BasicAPI{
	private String _greeting = "Hello, world";

	  public void setGreeting(String greeting)
	  {
	    _greeting = greeting;
	  }

	  public String hello()
	  {
	    return _greeting;
	  }
	}
           

client

package client;

import com.caucho.hessian.client.HessianProxyFactory;

import server.BasicAPI;

public class HessianClient {
public static void main(String[] args) throws Exception {
	//server定义Servlet
	String url = "http://localhost:8080/hello";
	
	//代理工厂
	HessianProxyFactory factory = new HessianProxyFactory();
	//创建代理对象
	BasicAPI basic = (BasicAPI) factory.create(BasicAPI.class, url);
	//运用代理对象访问
	System.out.println("hello(): " + basic.hello());
}
}
           

         启动web项目(我是用的eclipse内嵌的jetty插件,我启动项目时去掉了项目名前缀)          运行client,打印 hello(): Hello, world   入门案例ok!

    hessian简介

      Hessian是基于Binary-RPC协议实现的,是一种二进制数据格式,所以可以跨不同的语言平台,所以不管是Java,还是.NET都可以使用。hessian实现了不同语言可以远程调用(涉及到rpc,rpc蛮有意思,后续专门讲讲rpc),这方面也有很多其他的实现方式(效率上大致RMI > Httpinvoker >= Hessian>>Burlap>> WebService),RMI 与Httpinvoker (spring搞的一套的远程调用)局限于java,Hessian基于二进制,Burlap与WebService基于xml,Hessian与Burlap都是Caucho Technology提供的,Burlap相对于WebService结构更简单,但是通用性没有WebService那么广泛.        hessian基本原理( hessian基本原理):

  • 客户端发起请求,按照 Binary -RPC 协议将请求信息进行填充;
  • 填充完毕后将二进制格式文件转化为流,通过传输协议进行传输;
  • 接收到在接收到流后转换为二进制格式文件,按照 Binary -RPC 协议获取请求的信息并进行处理;
  • 处理完毕后将结果按照 Binary -RPC 协议写入二进制格式文件中并返回。

 hessian例子的一些延伸

1.返回值:

        上述basicService中返回的是一个String,实际上,任何一个可序列化类型都可以

2.hessian序列化工具类-    

package hessianUtil;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;

public class HessianSerialization {
	public static void main(String[] args) throws Exception {
		//功能看起来跟ObjectOutputStream 与ObjectInputStream 十分相似
		OutputStream os = new FileOutputStream("C:\\Users\\admin\\Desktop\\temp\\student.xml");
		  
		Hessian2Output out = new Hessian2Output(os);
		out.writeObject(new Student("hello"));
		out.writeObject(new Student("world"));
		out.flush();
		os.close();
		
		System.out.println("write over");

		InputStream is = new FileInputStream("C:\\Users\\admin\\Desktop\\temp\\student.xml");
		Hessian2Input in = new Hessian2Input(is);
		
		Student s1 = (Student) in.readObject(Student.class);
		Student s2 = (Student) in.readObject(Student.class);
		System.out.println(s1.getName());
		System.out.println(s2.getName());
		is.close();
	}

}
           

2.数据流传递     数据量比较大时,传递流比传递binary更有效率,在入门的example基础上继续编写

server

package server;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class BasicService implements BasicAPI {
	private String _greeting = "Hello, world";

	public void setGreeting(String greeting) {
		_greeting = greeting;
	}

	public String hello() {
		return _greeting;
	}

	@Override
	public void upload(String filename, InputStream data) {
		try {
			byte[] buff = new byte[1024];
			data.read(buff);
			System.out.println("upload success! filename:" + filename + ";   name:" + new String(buff));
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (data != null) {
				try {
					data.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	@Override
	public InputStream download() {
		return new ByteArrayInputStream("hello world".getBytes());
	}
}
           

client

package client;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import com.caucho.hessian.client.HessianProxyFactory;

import server.BasicAPI;

public class HessianClient {
public static void main(String[] args) throws Exception {
	//server定义Servlet
	String url = "http://localhost:8080/hello";
	
	//代理工厂
	HessianProxyFactory factory = new HessianProxyFactory();
	//创建代理对象
	BasicAPI basic = (BasicAPI) factory.create(BasicAPI.class, url);
	
	//运用代理对象访问
	System.out.println("hello(): " + basic.hello());
	
	//上传
	basic.upload("myfile", new ByteArrayInputStream("hello world".getBytes()));
	
	//下载
	InputStream is = basic.download();
	byte[] buff = new byte[1024];
	is.read(buff);
	System.out.println(new String(buff));
	is.close();
}
}
           

3.hessian的debug日志        官网上所讲的debug日志的配置是针对在resin容器的运行的项目(hessian作为resin体系中的一部分...),此处仅做简单介绍        安装resin环境( resin下载,不要下载pro,那个要花钱),下载zip解压        resin作为一个web容器(其启动方式跟tomcat十分相似),作为开发者,一般有两者启动启动方式,命令行(start.bat启动)或使用开发工具带插件启动.        以eclipse插件启动为例,安装插件( eclipse-resin install),新建server  

hessian学习         hessian入门example    hessian简介 hessian例子的一些延伸

          新建完成,会生成一个server工程(tomcate类似,建立server的时候,会copy一份启动的必要的config文件,开发调试只要修改此server即可)

hessian学习         hessian入门example    hessian简介 hessian例子的一些延伸

                为实现日志效果,简单设置下          注释resin.xml中的 (去除一些不必要的信息干扰)

<!-- Logging configuration for the JDK logging API -->
 <!--  <log-handler format=" {${thread}} ${log.message}" level="all" name="" path="stdout:" timestamp="[%y-%m-%d %H:%M:%S.%s]"/> -->
           

          cluster-default.xml中设置log内容

<host-default>
	<access-log path="log/access.log"
		format='%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"'
		rollover-period="1W" />
	<log name="" level="finest" path="stdout:" timestamp="[%Y-%m-%d %H:%M:%S]"
		format=" ${log.message}" />
           

          后面的log是我加上去的,只展示了时间与日志信息 stdout-控制台打印          对入门example稍作修改

public String hello(String hello) {
		return _greeting+hello;
	}
           

        启动客户端访问

public static void main(String[] args) throws Exception {
	//server定义Servlet
	String url = "http://localhost:8080/hessian/hello";
	
	//代理工厂
	HessianProxyFactory factory = new HessianProxyFactory();
/*	Object create = factory.create(url);
	System.out.println(create.getClass());*/
	//创建代理对象
	BasicAPI basic = (BasicAPI) factory.create(BasicAPI.class, url);
	
	//运用代理对象访问
	System.out.println("hello(): " + basic.hello("哈哈"));
           

       打印内容

[2017-08-08 16:43:23] call 2.0
[2017-08-08 16:43:23]   method "hello"
[2017-08-08 16:43:23]   "哈哈"
[2017-08-08 16:43:23] Hessian 2.0
[2017-08-08 16:43:23] Reply
[2017-08-08 16:43:23] Http[app-0, 3] HTTP/1.1 200 OK
[2017-08-08 16:43:23] Http[app-0, 3] Content-Type: x-application/hessian; charset=null
[2017-08-08 16:43:23] Http[app-0, 3] Transfer-Encoding: chunked
[2017-08-08 16:43:23] Http[app-0, 3] write-set-offset(172)
[2017-08-08 16:43:23] Http[app-0, 3] write-next-buffer(23)
[2017-08-08 16:43:23] Http[app-0, 3] flush()
[2017-08-08 16:43:23]   "Hello, world哈哈"
[2017-08-08 16:43:23] Http[app-0, 3] write-chunk-tail(7)
[2017-08-08 16:43:23] Http[app-0, 3] finish/keepalive
           

         resin的log体系可以匹配log4j,有时间单独说一说( resin log)