`
truelove12358
  • 浏览: 77533 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Hessian 原理分析、代码示例

 
阅读更多

Hessian 原理分析


一.远程通讯协议的基本原理

网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协议,网络 IO ,主要有 bio 、 nio 、 aio 三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。

二.应用级协议Binary-RPC

Binary-RPC 是一种和 RMI 类似的远程调用的协议,它和 RMI 的不同之处在于它以标准的二进制格式来定义请求的信息 ( 请求的对象、方法、参数等 ) ,这样的好处是什么呢,就是在跨语言通讯的时候也可以使用。

来看下 Binary -RPC 协议的一次远程通信过程:

1 、客户端发起请求,按照 Binary -RPC 协议将请求信息进行填充;

2 、填充完毕后将二进制格式文件转化为流,通过传输协议进行传输;

3 、接收到在接收到流后转换为二进制格式文件,按照 Binary -RPC 协议获取请求的信息并进行处理;

4 、处理完毕后将结果按照 Binary -RPC 协议写入二进制格式文件中并返回。

问题总结:

1 、传输的标准格式是?

标准格式的二进制文件。

2 、怎么样将请求转化为传输的流?

将二进制格式文件转化为流。

3 、怎么接收和处理流?

通过监听的端口获取到请求的流,转化为二进制文件,根据协议获取请求的信息,进行处理并将结果写入 XML 中返回。

4 、传输协议是?

Http 。

三.Hessian——一种实现远程通讯的library

Hessian 是由 caucho 提供的一个基于 binary-RPC 实现的远程通讯 library 。

1 、是基于什么协议实现的?

基于 Binary-RPC 协议实现。

2 、怎么发起请求?

需通过 Hessian 本身提供的 API 来发起请求。

3 、怎么将请求转化为符合协议的格式的?

Hessian 通过其自定义的串行化机制将请求信息进行序列化,产生二进制流。

4 、使用什么传输协议传输?

Hessian 基于 Http 协议进行传输。

5 、响应端基于什么机制来接收请求?

响应端根据 Hessian 提供的 API 来接收请求。

6 、怎么将流还原为传输格式的?

Hessian 根据其私有的串行化机制来将请求信息进行反序列化,传递给使用者时已是相应的请求信息对象了。

7 、处理完毕后怎么回应?

处理完毕后直接返回, hessian 将结果对象进行序列化,传输至调用端。

四.Hessian源码分析

以 hessian 和 spring dm server 整合环境为例。

  1. 1.客户端发起请求

Hessian 的这个远程过程调用,完全使用动态代理来实现的。有客户端可以看出。

除去 spring 对其的封装,客户端主要是通过 HessianProxyFactory 的 create 方法就是创建接口的代理类,该类实现了接口, JDK 的 proxy 类会自动用 InvocationHandler 的实现类(该类在 Hessian 中表现为 HessianProxy )的 invoke 方法体来填充所生成代理类的方法体。

客户端系统启动时:

根据 serviceUrl 和 serviceInterface 创建代理。

HessianProxyFactoryBean 类

HessianClientInterceptor 类

createHessianProxy(HessianProxyFactory proxyFactory)

HessianProxyFactory 类

public Object create(Class api, String urlName)

客户端调用hessian服务时:

HessianProxy类的 invoke(Object proxy, Method method, Object []args)方法

String methodName = method.getName();// 取得方法名

Object value = args[0]; // 取得传入参数

conn = sendRequest(mangleName, args) ; // 通过该方法和服务器端取得连接

httpConn = (HttpURLConnection) conn;

code = httpConn.getResponseCode(); // 发出请求

// 等待服务器端返回相应…………

is = conn.getInputStream();

Object value = in.readObject(method.getReturnType()); // 取得返回值

HessianProxy类的 URLConnection sendRequest(String methodName, Object []args)方法:

URLConnection conn = _factory.openConnection(_url); // 创建 URLConnection

OutputStream os = conn.getOutputStream();

AbstractHessianOutput out = _factory.getHessianOutput(os); // 封装为 hessian 自己的输入输出 API

out.call(methodName, args);

return conn;

  1. 2.服务器端接收请求并处理请求

服务器端截获相应请求交给:

org.springframework.remoting.caucho.HessianServiceExporter

具体处理步骤如下:

a) HessianServiceExporter 类

(HessianExporter) invoke(request.getInputStream(), response.getOutputStream());

b) HessianExporter 类

(Hessian2SkeletonInvoker) this.skeletonInvoker.invoke(inputStream, outputStream);

c) Hessian2SkeletonInvoker 类

将输入输出封转化为转化为 Hessian 特有的 Hessian2Input 和 Hessian2Output

Hessian2Input in = new Hessian2Input(isToUse);

in.setSerializerFactory(this.serializerFactory);

AbstractHessianOutput out = null;

int major = in.read();

int minor = in.read();

out = new Hessian2Output(osToUse);

out = new HessianOutput(osToUse);

out.setSerializerFactory(this.serializerFactory);

(HessianSkeleton) this.skeleton.invoke(in, out);

d) HessianSkeleton 类

读取方法名

String methodName = in.readMethod();

Method method = getMethod(methodName);

读取方法参数

Class []args = method.getParameterTypes();

Object []values = new Object[args.length];

执行相应方法并取得结果

result = method.invoke(service, values);

结果写入到输出流

out.writeObject(result);

总结:由上面源码分析可知,客户端发起请求和服务器端接收处理请求都是通过 hessian 自己的 API 。输入输出流都要封装为 hessian 自己的 Hessian2Input 和 Hessian2Output ,接下来一节我们将去了解 hessian 自己封装的输入输出到底做了些什么!

五.Hessian的序列化和反序列化实现

hessian 源码中 com.caucho.hessian.io 这个包是 hessian 实现序列化与反序列化的核心包。其中 AbstractSerializerFactory , AbstractHessianOutput , AbstractSerializer , AbstractHessianInput , AbstractDeserializer 是 hessian 实现序列化和反序列化的核心结构代码。

  1. AbstractSerializerFactory ,它有 2 个抽象方法:

根据类来决定用哪种序列化工具类

abstract public Serializer getSerializer(Class cl) throws HessianProtocolException;

根据类来决定用哪种反序列化工具类

abstract public Deserializer getDeserializer(Class cl) throws HessianProtocolException;

  1. SerializerFactory 继承 AbstractSerializerFactory 。

在 SerializerFactory 有很多静态 map 用来存放类与序列化和反序列化工具类的映射,这样如果已经用过的序列化工具就可以直接拿出来用,不必再重新实例化工具类。

在 SerializerFactory 中,实现了抽象类的 getSerializer 方法,根据不同的需要被序列化的类来获得不同的序列化工具,一共有 17 种序列化工具, hessian 为不同的类型的 java 对象实现了不同的序列化工具,默认的序列化工具是 JavaSerializer 。

在 SerializerFactory 中,也实现了抽象类的 getDeserializer 方法,根据不同的需要被反序列化的类来获得不同的反序列化工具,默认的反序列化工具类是 JavaDeserializer 。

  1. HessianOutput 继承 AbstractHessianOutput 成为序列化输出流的一种实现。

它会实现很多方法,用来做流输出。

需要注意的是方法,它会先调用 serializerFactory 根据类来获得 serializer 序列化工具类

public void writeObject(Object object)

throws IOException

{

if (object == null) {

writeNull();

return;

}

Serializer serializer;

serializer = _serializerFactory.getSerializer(object.getClass());

serializer.writeObject(object, this);

}

  1. 现在我们来看看 AbstractSerializer 。

其 writeObject 是必须在子类实现的方法, AbstractSerializer 有 17 种子类实现, hessian 根据不同的 java 对象类型来实现了不同的序列化工具类,其中默认的是 JavaSerializer 。

而 JavaSerializer 的 writeObject 方法的实现,遍历 java 对象的数据成员,根据数据成员的类型来获得各自的 FieldSerializer ,一共有 6 中默认的 FieldSerializer 。

拿默认的 FieldSerializer 举例,还是调用 AbstractHessianOutput 的子类来 writeObject ,这个时候,肯定能找到相应的 Serializer 来做序列化

同理可以反推出 hessian 的反序列化机制。 SerializerFactory 可以根据需要被反序列化的类来获得反序列化工具类来做反序列化操作。

总结:得益于 hessian 序列号和反序列化的实现机制, hessian 序列化的速度很快,而且序列化后的字节数也较其他技术少。

参考文献:

  1. 《 Java 远程通讯可选技术及原理》http://java.chinaitlab.com/base/740383.html
  2. 《 Hessian-3.2.0 源码》
  3. 《 hessian 序列化实现初探》http://www.javaeye.com/topic/245238
  4. 《 Hessian 2.0 序列化协议规范》

http://blog.csdn.net/xpspace/archive/2007/10/05/1811603.aspx




Hessian RPC示例和基于Http请求的Hessian序列化对象传输


本文主要介绍两个案例,第一个是使用Hessian来实现远程过程调用,第二个是通过Hessian提供的二进制RPC协议进行和Servlet进行数据交互,Hessian本身即是基于Http的RPC实现。

案例一:

1.准备工作

这里建立一个Maven项目,其中包含四个模块,父模块(仅用来聚合其它模块,不做实际使用),服务器端模块,客户端模块,API模块(远程过程接口,供服务器和客户端使用)。目录结构见下图:

wKiom1SwmzSRUDR1AAHOPhvwsXI742.jpg

2.添加Hessian的依赖

由于客户端和服务器都要依赖Hessian的包,这里可以添加到父模块的pom.xml中去。

<dependency>
			<groupId>com.caucho</groupId>
			<artifactId>hessian</artifactId>
			<version>4.0.38</version>
		</dependency>

关于其它的具体依赖配置,这里不做多余展示,本文末尾附有完整的下载地址。

3.在hessian-api模块定义过程接口

package secondriver.hessian.api;

import java.io.InputStream;
import java.util.List;

import secondriver.hessian.api.bean.Person;

public interface HelloHessian {

	public String sayHello();

	public String sayHello(String name);

	public List<Person> getPersons();

	public Person getPersonById(int id);

	public boolean uploadFile(String fileName, InputStream data);

	public byte[] downloadFile(String fileName);
}

上面的接口中定义的六个方法,有重载方法,有获取集合,有获取对象,有上传文件,下载文件等。需要注意的是在Hessian中定义过程接口的方法时输入输出流对象参数应该放置到方法的最后一个参数。另外在实际操作中发现对于流的处理通过远程调用还是会出现一个莫名其妙的问题,加上Hessian缺乏完整的文档(除Hessian的序列号协议)。

关于下载文件这个方法的定义使用了返回byte数组,这将受限与虚拟机的内存或其他因素。网上有说关于文件下载Hessian不支持(未能证实。引申案例二的方式,传输二进制就可以实现下载,不过这将与Hessian的RPC实现无关,而是应用到Hessian的序列号协议),这个可以算是一种策略,So,关于远程文件下载,谁会使用这样的方式呢?!!

4.服务器端实现具体功能

服务器端实现接口

package secondriver.hessian.server.bo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import secondriver.hessian.api.HelloHessian;
import secondriver.hessian.api.bean.Person;

public class HelloHessianImpl implements HelloHessian {

	private static Person[] persons = new Person[5];

	static {
		Random random = new Random();
		for (int i = 0, l = persons.length; i < l; i++) {
			persons[i] = new Person();
			persons[i].setId(i);
			persons[i].setGender(random.nextBoolean());
			persons[i].setName("name-" + i);
			persons[i].setPhone(random.nextLong());
			persons[i].setHeight(random.nextDouble());
			persons[i].setWeight(random.nextFloat());
			persons[i].setAddress(new String[] { "Address" + random.nextInt(),
					"Address" + random.nextInt() });

			Calendar c = Calendar.getInstance();
			c.set(Calendar.DATE, i + 1);
			persons[i].setBrithday(c.getTime());
		}
	}

	@Override
	public String sayHello() {
		return "Hello Hession " + new Date().toString();
	}

	@Override
	public String sayHello(String name) {
		return "Welcome " + name;
	}

	@Override
	public List<Person> getPersons() {
		return Arrays.asList(persons);
	}

	@Override
	public Person getPersonById(int id) {
		for (Person p : persons) {
			if (p.getId() == id) {
				return p;
			}
		}
		return null;
	}

	@Override
	public boolean uploadFile(String fileName, InputStream data) {
		List<String> temp;
		try {
			temp = IOUtils.readLines(data);
			String filePath = System.getProperty("user.dir") + "/temp/"
					+ fileName;
			FileUtils.writeLines(new File(filePath), temp);
			System.out.println("Upload file to " + filePath);
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public byte[] downloadFile(String fileName) {
		String filePath = System.getProperty("user.dir") + "/temp/" + fileName;
		InputStream data = null;
		try {
			data = new FileInputStream(filePath);
			int size = data.available();
			byte[] buffer = new byte[size];
			IOUtils.read(data, buffer);
			return buffer;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			IOUtils.closeQuietly(data);
		}
	}
}

5.服务器端配置远程服务地址

Hessian是Remote On Http工具,服务端是典型的Java Web应用,我们需要在web.xml中配置服务的请求地址。

<servlet>
		<servlet-name>HelloHessian</servlet-name>
		<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class><!-- RPC HessianServlet处理类 -->
		<init-param>
			<param-name>home-class</param-name><!-- 远程服务实现类 -->
			<param-value>secondriver.hessian.server.bo.HelloHessianImpl</param-value>
		</init-param>
		<init-param>
			<param-name>home-api</param-name><!-- 远程服务接口 -->
			<param-value>secondriver.hessian.api.HelloHessian</param-value>
		</init-param>
	</servlet>

6.客户端调用远程对象方法

package secondriver.hessian.client;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.List;

import org.apache.commons.io.IOUtils;

import secondriver.hessian.api.HelloHessian;
import secondriver.hessian.api.bean.Person;

import com.caucho.hessian.client.HessianProxyFactory;

/**
 * Hessian RPC
 */
public class HelloHessianClient {

	public static String urlName = "http://localhost:8080/hessian-server/HelloHessian";

	public static void main(String[] args) throws MalformedURLException {

		HessianProxyFactory factory = new HessianProxyFactory();
		// 开启方法重载
		factory.setOverloadEnabled(true);

		HelloHessian helloHession = (HelloHessian) factory.create(
				HelloHessian.class, urlName);

		// 调用方法
		System.out.println("call sayHello():" + helloHession.sayHello());
		System.out.println("call sayHello(\"Tom\"):"
				+ helloHession.sayHello("Tom"));
		System.out.println("call getPersons():");

		// 调用方法获取集合对象
		List<Person> persons = helloHession.getPersons();
		if (null != persons && persons.size() > 0) {
			for (Person p : persons) {
				System.out.println(p.toString());
			}
		} else {
			System.out.println("No person.");
		}

		// 通过参数调用方法获取对象
		int id = 2;
		System.out.println(String.format("call getPersonById(%d)", id));
		Person person = helloHession.getPersonById(id);
		if (null != person) {
			System.out.println(person.toString());
		} else {
			System.out.println("Id is " + id + " person not exist.");
		}

		// 上传文件
		String fileName = "upload.txt";
		String filePath = System.getProperty("user.dir") + "/temp/" + fileName;
		InputStream data = null;
		try {
			data = new BufferedInputStream(new FileInputStream(filePath));
			if (helloHession.uploadFile(fileName, data)) {
				System.out.println("Upload file " + filePath + " succeed.");
			} else {
				System.out.println("Upload file " + filePath + " failed.");
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(data);
		}

		// 下载文件
		fileName = "download.txt";
		filePath = System.getProperty("user.dir") + "/temp/" + fileName;
		try {

			byte[] temp = helloHession.downloadFile(fileName);
			if (null != temp) {
				FileWriter output = new FileWriter(filePath);
				IOUtils.write(temp, output, "UTF-8");
				System.out.println("Download file " + filePath + " succeed.");
				output.close();
			} else {
				System.out.println("Download file " + filePath + " failed.");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

通过客户端调用可以看出,远程方法的具体实现对于客户端来说是透明的。

7.运行程序

7.1启动服务器

7.2运行客户端程序

客户端请求远程服务对象方法调用结果:

call sayHello():Hello Hession Sat Jan 10 12:31:21 CST 2015
call sayHello("Tom"):Welcome Tom
call getPersons():
Person [id=0, gender=true, name=name-0, brithday=Thu Jan 01 12:31:21 CST 2015, height=0.04756537639163749, weight=0.24559122, phone=1359341198036930408, address=[Address2145973789, Address486043733]]
....省略
call getPersonById(2)
Person [id=2, gender=false, name=name-2, brithday=Sat Jan 03 12:31:21 CST 2015, height=0.07169451440704722, weight=0.8515671, phone=2732762596557481818, address=[Address8744397, Address-1690316438]]
Upload file F:\__eclipse\tomsworkspace\hessian-L-parent\hessian-client/temp/upload.txt succeed.
Download file F:\__eclipse\tomsworkspace\hessian-L-parent\hessian-client/temp/download.txt succeed.

案例二:

1. 客户端通过Hessian序列号协议序列化对象,通过Http Post方式提交到服务器端,然后通过反序列化服务器端响应数据。

package secondriver.hessian.data;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Date;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import secondriver.hessian.api.bean.Person;

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

public class Test3 {

	public static String urlName = "http://localhost:8080/hessian-server/PostDataServlet";

	public static void main(String[] args) throws Throwable {

		// 序列化
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		Hessian2Output h2o = new Hessian2Output(os);

		h2o.startMessage();
		h2o.writeObject(getPerson());
		h2o.writeString("I am client.");
		h2o.completeMessage();
		h2o.close();

		byte[] buffer = os.toByteArray();
		os.close();

		ByteArrayEntity byteArrayEntity = new ByteArrayEntity(buffer,
				ContentType.create("x-application/hessian", "UTF-8"));
		
		CloseableHttpClient client = HttpClients.createDefault();
		HttpPost post = new HttpPost(urlName);
		post.setEntity(byteArrayEntity);
		CloseableHttpResponse response = client.execute(post);

		System.out.println("response status:\n"
				+ response.getStatusLine().getStatusCode());
		HttpEntity body = response.getEntity();
		InputStream is = body.getContent();
		Hessian2Input h2i = new Hessian2Input(is);
		h2i.startMessage();

		Person person = (Person) h2i.readObject();
		System.out.println("response:\n" + person.toString());
		System.out.println(h2i.readString());

		h2i.completeMessage();
		h2i.close();
		is.close();
	}

	public static Person getPerson() {
		Person person = new Person();
		person.setAddress(new String[] { "Beijing", "TaiWan", "GuangZhou" });
		person.setBrithday(new Date());
		person.setGender(false);
		person.setHeight(168.5D);
		person.setId(300);
		person.setName("Jack");
		person.setPhone(188888888);
		person.setWeight(55.2F);
		return person;
	}
}

2.服务器端通过Hessian序列化协议反序列化对象,通过HttpServletResponse对请求进行响应,响应数据是Hessian序列化的二进制结果。

package secondriver.hessian.server.servlet;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import secondriver.hessian.api.bean.Person;

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

public class PostDataServlet extends HttpServlet {

	private static final long serialVersionUID = -4461061053732328507L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 处理请求
		ServletInputStream sis = req.getInputStream();
		Hessian2Input h2i = new Hessian2Input(sis);

		h2i.startMessage();
		Person person = (Person) h2i.readObject();
		System.out.println("receive:\n" + person.toString());
		System.out.println(h2i.readString());
		h2i.completeMessage();
		h2i.close();
		sis.close();

		// 发送响应
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("x-application/hessian");

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		Hessian2Output h2o = new Hessian2Output(bos);

		h2o.startMessage();
		h2o.writeObject(getPerson());
		h2o.writeString("I am server.");
		h2o.completeMessage();
		h2o.close();

		ServletOutputStream sos = resp.getOutputStream();
		sos.write(bos.toByteArray());
		sos.flush();
		bos.close();
		sos.close();

	}

	public static Person getPerson() {
		Person person = new Person();
		person.setAddress(new String[] { "ShangHai", "ShenZhen", "ChengDu" });
		person.setBrithday(new Date());
		person.setGender(true);
		person.setHeight(178.5D);
		person.setId(301);
		person.setName("Tom");
		person.setPhone(188218888);
		person.setWeight(55.2F);
		return person;
	}
}

3.在web.xml中配置PostDataServlet,此处略去具体配置信息,可以参考上面HelloHessian Servlet配置。

4.运行程序

4.1启动服务器

4.2运行客户端程序Test3.

运行结果:

服务器端输出:

[INFO] Restart completed at Sat Jan 10 12:34:51 CST 2015
receive:
Person [id=300, gender=false, name=Jack, brithday=Sat Jan 10 12:35:03 CST 2015, height=168.5, weight=55.2, phone=188888888, address=[Beijing, TaiWan, GuangZhou]]
I am client.

客户端输出:

response status:
200
response:
Person [id=301, gender=true, name=Tom, brithday=Sat Jan 10 12:35:03 CST 2015, height=178.5, weight=55.2, phone=188218888, address=[ShangHai, ShenZhen, ChengDu]]
I am server.

分析输出结果可见Hessian序列化对象通过Http的方式传输,并成功反序列化。

关于Hessian序列号协议可以参见:http://hessian.caucho.com/doc/hessian-serialization.html

写在最后:Hessian的相关资料网上还是比较少,而且例子不尽相同,而且官方文档错误之处清晰可见(仔细阅读方可一览无余),本文从Hessian的RPC使用和Hessian序列化和反序列化对象两个方面提供了示例,完整示例下载地址可见本文附件:HessionRPC示例(Eclipse Luna版工程,需要Mavn支持),另外带有源码的Hessian的API文档下载地址:http://down.51cto.com/data/1973896

一次不太愉快的Hessian体验使得对RPC的理解更加深刻,无论何种框架,对象的序列化和反序列化,数据的传输协议都是实现RPC的工作重点。

分享到:
评论

相关推荐

    hessian-demo示例

    首先,让我们深入了解Hessian的工作原理。Hessian协议基于HTTP,但采用了二进制编码,从而减少了网络传输的数据量,提高了通信效率。它支持基本类型、对象、数组以及XML和JSON等数据格式的序列化和反序列化。在Java...

    Hessian 学习 例子 实例

    至于"工具",有一些工具可以帮助开发者测试和调试Hessian服务,例如,Hessian Proxy工具允许你通过HTTP代理的方式交互Hessian服务,以便观察和分析传输的二进制数据。 总的来说,Hessian是一个值得学习的技术,尤其...

    Hessian源代码

    这个压缩包文件“hession_1”包含了Hessian的源代码以及相关的示例,这将有助于我们深入理解其内部工作原理。 Hessian协议的主要特点包括: 1. **二进制格式**:与基于文本的HTTP协议不同,Hessian使用二进制格式...

    hessian

    在【标签】中,"源码"可能指的是查看或分析Hessian协议的底层实现,这对于理解其工作原理和优化性能非常有帮助。"工具"可能指的是使用Hessian相关的开发工具或框架,例如HessianProxyFactory、HessianServlet等。 ...

    Hessian协议格式

    在示例代码中,我们将通过 Hessian protocol 调用这四个方法,并截取并分析请求报文和应答报文的格式。 2.1 Hessian 报文结构应用示例背景说明 在示例代码中,我们使用 Java 语言编写了一个简单的示例,用于形象地...

    Hessian应用

    虽然提供的部分内容没有给出具体的User类代码,但我们可以根据Hessian的一般使用场景来推测可能的User类设计。假设User类如下所示: ```java public class User { private String name; private int age; // ...

    自己写了个Hessian

    通过分析这些测试代码,我们可以更深入地了解Hessian的工作原理,以及如何在不同的场景下使用它。 总之,"自己写了个Hessian" 是一个关于实现Hessian协议的个人项目,涉及到对象序列化、HTTP通信、RPC服务等多个IT...

    hessian php与java通讯demo源码

    Hessian是一种二进制协议,它允许在不同的编程语言之间进行高效的远程方法调用(RPC)。...通过分析和实践这些示例代码,你可以更好地掌握Hessian的工作原理和使用方式,为你的跨语言项目打下坚实的基础。

    二进制Web服务Hessian刘骥讲座--(附源码)

    7. **压缩包资源**:Hessian.rar文件可能包含了更多关于Hessian的代码示例、配置文件或者额外的讲解资料。解压后,开发者可以进一步探索和学习Hessian的细节。 通过这个讲座和附带的源码,你可以系统地学习如何利用...

    Hessian笔记

    【标签】:“源码”标签暗示笔记中可能包含了Hessian的源代码分析,帮助读者理解其内部机制,如何处理序列化、反序列化,以及如何实现远程调用的细节。“工具”标签则可能意味着笔记中介绍了一些辅助工具,用于测试...

    Hessian HelloWorld篇

    通过名为"HessianTest"的压缩包文件,用户可能找到了一个包含服务端和客户端代码的示例,可以运行并体验Hessian的工作方式。这个文件可能包含了Java源代码、配置文件,甚至可能有README文档说明如何编译和运行这些...

    CXF+RMI+HESSIAN

    4. 源码分析能力,理解并修改提供的示例代码以满足特定需求。 5. 集成开发环境(IDE)和构建工具的使用,如Maven或Gradle,来管理和构建项目。 通过深入学习和实践这些知识点,开发者可以有效地构建出跨网络的高效...

    nacos-hessian-rce.pdf

    本篇文章将针对 `nacos-hessian-rce.md` 文件中提及的一个远程代码执行(Remote Code Execution, RCE)漏洞进行详细分析。该文档由 Y4er.com 在 2023 年 6 月 8 日撰写。此漏洞主要涉及 Nacos 的 7848 端口使用 ...

    Frangi-filter-python版本的Hessian Frangi滤波.7z

    在压缩包中的文件“Frangi-filter-python版本的Hessian Frangi滤波”可能包含了以上提到的Python脚本和相关的辅助文件,如测试图像或示例代码,供用户理解和应用Frangi滤波器。 总之,Hessian Frangi滤波器是一种...

    最小二乘法java示例

    通过理解以上知识点并结合提供的代码示例,初学者可以更好地掌握最小二乘法的原理和实现方法,从而在实际项目中应用这一强大的工具。同时,理解并熟练运用最小二乘法也能为后续学习更复杂的优化算法,如岭回归、...

    MATLAB角点检测代码

    这个MATLAB代码示例对于学习角点检测算法和理解其内部工作原理非常有帮助。通过阅读和理解这段代码,可以加深对图像处理和计算机视觉技术的理解,并为进一步的图像分析和识别任务打下基础。同时,这也是一个很好的...

    MATLAB优化算法案例分析与应用(进阶篇)代码与ppt

    通过代码示例,学习者可以深入了解每个优化算法的工作原理和使用方法,提升编程技能和问题解决能力。 总的来说,这个资源为进阶MATLAB优化算法的学习者提供了理论知识与实践操作相结合的学习材料,有助于深入理解...

    拟牛顿算法

    根据题目中的Matlab程序代码示例,我们可以详细分析其核心部分。 ##### 函数定义 `quasi_Newton(f,x0,error)` - **参数解释**: - `f`:目标函数,需要求梯度。 - `x0`:初始点。 - `error`:允许的误差范围。 ...

    16个OpenCV特征提取与检测示例源代码.rar

    8. 源代码分析:压缩包中的源代码将展示如何在实际编程中应用这些算法,包括关键点检测、描述符计算、匹配过程以及可视化结果。通过逐行阅读和运行代码,开发者可以更好地理解OpenCV库的用法,加深对特征提取与检测...

    surf学习中的文章和代码的汇总

    4. **实践项目**:“surf_study”这个压缩包可能包含了各种SURF应用的示例代码和文章,是实践和理解SURF的好材料。通过分析这些代码,你可以学习如何检测关键点、提取描述符并进行匹配。 在学习过程中,理解SURF的...

Global site tag (gtag.js) - Google Analytics