Skip to content
forked from caiiiycuk/qhessian

Qt && C++ implementation of the hessian protocol

Notifications You must be signed in to change notification settings

tohn21/qhessian

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 

Repository files navigation

qhessian

Qt && C++ implementation of the hessian protocol

QHessian is based on Qt Framework. That means that you need only qt framework to use all features of hessian. No code generation needed to work with qhessian.

Comparsion of c++ implementations:

Project Code generation Libraries
hessianorb project Yes CURL
hessiancpp project No SSLPP
qhessian No Qt

Preparing a project

  • Get a local copy of the qhessian repository with command

    git clone clone https://github.com/caiiiycuk/qhessian.git
    
  • Add include macro into your source file line

    #include "{$path}/QHessian.h"

Using QHessian

To call a remote method you need to:

  1. Create QHessianMethodCall object
  2. Set the method paramters with operator <<
  3. Invoke method

Example of calling method with signature int substract(int a, int b):

{
  using namespace QHessian::in;
  QHessian::QHessianMethodCall call("substract");
  call << Integer(5) << Integer(4);
  call.invoke(networkManager, url, reciver, SLOT(replySubtractCall()), SLOT(error(int, const QString&)));
}

Where:

  • networkManager - is instance of QNetworkAccessManager
  • url - url to hessian service
  • reciver - is QObject that receives reply or error
  • replyMyMethodCall - will be invoked with server response
  • error(int, const QString&) - will be invoked to process error

To parse server response you need to:

  1. Get an instance of QHessian::QHessianReturnParser
  2. Parse results with operator >>

Example of result parsing:

void replySubtractCall() {
  qint32 result;

  using namespace QHessian::out;

  QHessian::QHessianReturnParser& parser = *(QHessian::QHessianReturnParser*) QObject::sender();
  parser >> Integer(result); // 1
  parser.deleteLater();
}

QHessian::QHessianReturnParser peek method

You should use peek when you don't know what type or property goes next in response stream. For example: service can return untyped object. This object may be a Apple or Banana or anything else. To determine type use peek method:

	if (parser.peek(BeginObject("Apple"))) {
		//can parse Apple type
	} else if (parser.peek(BeginObject("Banana"))) {
		//can parse Banana type
	}

Properties

QHessian types (or properties) are just wrappers for hessian's object serialization types. Properties are divided into two namespaces:

  • QHessian::out - contain properties that wrap responses
  • QHessian::in - contain properties that wrap requests

In both namespaces there are properties:

  • Null: Null represents a null pointer.
  • Boolean: Wraps the boolean data type. Has only two possible values: true and false. Use this data type for simple flags that track true/false conditions
  • Integer: Wraps the int data type. Int is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive).
  • Long: Wraps the long data type. Long is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive).
  • Double: Wraps The double (and float) data type. Double is a double-precision 64-bit IEEE 754 floating point.
  • String: Wraps the UTF8-encoded string.
  • DateTime: Represents a specific instant in time, with millisecond precision.
  • Binary: Wraps the binary data. Typically an array of byte.
  • BeginCollection: This proeprty is a marker for collection start.
  • EndCollection: This property is a marker for collection end.
  • BeginMap: This property is a marker for map begin.
  • HasMoreMap: This property is a marker for available elements in map.
  • EndMap: This property is a marker for end map.
  • BeginObject: This property is a marker for begin object.
  • EndObject: This property is a marker for end object.
  • Ref: This proerpty is a marker for shared and circular object references.

Each propety optionally has 'name', 'value' and 'type' attributes.

Snippets

  • Q.1 How to call void method()
  • Q.2 How to read Null
  • Q.3 How to read Boolean
  • Q.4 How to read Integer
  • Q.5 How to read Long
  • Q.6 How to read Double
  • Q.7 How to read Date
  • Q.8 How to read String
  • Q.9 How to read Binary
  • Q.10 How to read untyped collection
  • Q.11 How to read typed collection
  • Q.12 How to read untyped map
  • Q.13 How to read typed map
  • Q.14 How to read Object
  • Q.15 How to read references
  • Q.16 How to read multi-typed object
  • Q.17 How to write Null
  • Q.18 How to write Boolean
  • Q.19 How to write Integer
  • Q.20 How to write Long
  • Q.21 How to write Double
  • Q.22 How to write Date
  • Q.23 How to write String
  • Q.24 How to write Binary
  • Q.25 How to write untyped collection
  • Q.26 How to write typed collection (String[``])
  • Q.27 How to write untyped map
  • Q.28 How to write typed map (hashtable)
  • Q.29 How to write Object
  • Q.30 How to write references
  • Q.31 How to call int method(int, int)

Q.1

How to call void method()

Java server exampleQHessian client example
  /**
* Does nothing.
*/
public void nullCall();
	void nullCall() {
QHessian::QHessianMethodCall call("nullCall");
call.invoke(networkManager,
serviceUrl,
this,
SLOT(replyCall()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyCall() {
}
};

Q.2

How to read Null

Java server exampleQHessian client example
  public String replyNull()
{
return null;
}
	void replyNullCall() {
QHessian::QHessianMethodCall call("replyNull");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyNull()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyNull() {
QString result;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> String(result);
parser.wasNull(); // == true
parser.deleteLater();
}

Q.3

How to read Boolean

Java server exampleQHessian client example
  public Object replyTrue()
{
return true;
}
	void replyTrueCall() {
QHessian::QHessianMethodCall call("replyTrue");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyTrue()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyTrue() {
bool boolean;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> Boolean(boolean); // true
parser.deleteLater();
}

Q.4

How to read Integer

Java server exampleQHessian client example
  public int replyInt_m0x801()
{
return -0x801;
}
	void replyInt_m0x801Call() {
QHessian::QHessianMethodCall call("replyInt_m0x801");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyInt_m0x801()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyLong_m0x801() {
qint32 int;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> Long(int); // -0x801
parser.deleteLater();
}

Q.5

How to read Long

Java server exampleQHessian client example
  public long replyLong_m0x801()
{
return -0x801;
}
	void replyLong_m0x801Call() {
QHessian::QHessianMethodCall call("replyLong_m0x801");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyLong_m0x801()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyLong_m0x801() {
qint64 longInt;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> Long(longInt); // -0x801
parser.deleteLater();
}

Q.6

How to read Double

Java server exampleQHessian client example
  public double replyDouble_3_14159()
{
return 3.14159;
}
	void replyDouble_3_14159Call() {
QHessian::QHessianMethodCall call("replyDouble_3_14159");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyDouble_3_14159()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyDouble_3_14159() {
qreal real;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> Double(real); // 3.14159
parser.deleteLater();
}

Q.7

How to read Date

Java server exampleQHessian client example
  public Date replyDate_1()
{
long time = 894621091000L;

return new Date(time);
}
	void replyDate_1Call() {
QHessian::QHessianMethodCall call("replyDate_1");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyDate_1()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyDate_1() {
QDateTime date;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> DateTime(date); //894621091000LL
parser.deleteLater();
}

Q.8

How to read String

Java server exampleQHessian client example
  /**
* return "Hello, World"
*/
public String hello();
	void helloCall() {
QHessian::QHessianMethodCall call("hello");
call.invoke(networkManager,
serviceUrl,
this,
SLOT(replyHelloCall()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyHelloCall() {
QString hello;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> String(hello);
parser.deleteLater();

// Now hello == "Hello, World"
}

Q.9

How to read Binary

Java server exampleQHessian client example
  public byte[] replyBinary_1()
{
return toBinary("0");
}
	void replyBinary_1Call() {
QHessian::QHessianMethodCall call("replyBinary_1");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyBinary_1()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyBinary_1() {
QByteArray binary;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> Binary(binary);
parser.deleteLater();

//now binary contains '0'

}

Q.10

How to read untyped collection

Java server exampleQHessian client example
  public List<String> replyUntypedFixedList_8() {
List<String> list = new ArrayList<String>();

list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");

return list;
}
	void replyUntypedFixedList_8Call() {
QHessian::QHessianMethodCall call("replyUntypedFixedList_8");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyUntypedFixedList_8()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyUntypedFixedList_8() {
using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();

qint32 collectionSize;

parser >> BeginCollection(collectionSize);

for (int i=0; i<collectionSize; ++i) {
QString value;
parser >> String(value); //1 2 3 4 5 6 7 8
}

parser >> EndCollection();

parser.deleteLater();
}

Q.11

How to read typed collection

Java server exampleQHessian client example
  public Object replyTypedFixedList_8()
{
return new String[] { "1",
"2",
"3",
"4",
"5",
"6",
"7",
"8" };
}
	void replyTypedFixedList_8Call() {
QHessian::QHessianMethodCall call("replyTypedFixedList_8");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyTypedFixedList_8()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyTypedFixedList_8() {
using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();

qint32 collectionSize;
parser >> BeginCollection("", "[string", collectionSize); //[string - type name

for (int i=0; i<collectionSize; ++i) {
QString value;
parser >> String(value); // 1 2 3 4 5 6 7 8
}
parser >> EndCollection();
parser.deleteLater();
}

Q.12

How to read untyped map

Java server exampleQHessian client example
  public Object replyUntypedMap_1()
{
HashMap map = new HashMap();
map.put("a", 0);
map.put("b", 1);

return map;
}
	void replyUntypedMap_1Call() {
QHessian::QHessianMethodCall call("replyUntypedMap_1");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyUntypedMap_1()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyUntypedMap_1() {
using namespace QHessian::out;

QString key;
qint32 value;
bool hasMore;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> BeginMap();
while ((parser >> HasMoreMap(hasMore), hasMore)) {
parser >> String(key); // a b
parser >> Integer(value); // 0 1
}
parser >> EndMap();
parser.deleteLater();
}

Q.13

How to read typed map

Java server exampleQHessian client example
  public Object replyTypedMap_1()
{
Map map = new Hashtable();
map.put("a", 0);
map.put("b", 1);

return map;
}
	void replyTypedMap_1Call() {
QHessian::QHessianMethodCall call("replyTypedMap_1");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyTypedMap_1()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyTypedMap_1() {
using namespace QHessian::out;

QString key;
qint32 value;
bool hasMore;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> BeginMap("", "java.util.Hashtable");
while ((parser >> HasMoreMap(hasMore), hasMore)) {
parser >> String(key); // a b
parser >> Integer(value); // 0 1
}
parser >> EndMap();
parser.deleteLater();
}

Q.14

How to read Object

Object class:

package com.caucho.hessian.test;

public class TestObject implements java.io.Serializable {
  private Integer _value;

  public TestObject(Integer value)
  {
    _value = value;
  }

  public Object getValue()
  {
    return _value;
  }
}
Java server exampleQHessian client example
  public Object replyObject_1()
{
return new TestObject(0);
}

void replyObject_1Call() {
QHessian::QHessianMethodCall call("replyObject_1");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyObject_1()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyObject_1() {
using namespace QHessian::out;

qint32 _value;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser
>> BeginObject("", "com.caucho.hessian.test.TestObject")
>> Integer("_value", _value) //_value == 0
>> EndObject();
parser.deleteLater();
}

Q.15

How to read references

From hessian docs:

An integer referring to a previous list, map, or object instance. As each list, map or object is read from the input stream, it is assigned the integer position in the stream, i.e. the first list or map is '0', the next is '1', etc. A later ref can then use the previous object. Writers MAY generate refs. Parsers MUST be able to recognize them.

ref can refer to incompletely-read items. For example, a circular linked-list will refer to the first link before the entire list has been read.

A possible implementation would add each map, list, and object to an array as it is read. The ref will return the corresponding value from the array. To support circular structures, the implementation would store the map, list or object immediately, before filling in the contents.

Each map or list is stored into an array as it is parsed. ref selects one of the stored objects. The first object is numbered '0'.

Object class:

package com.caucho.hessian.test;

import java.io.IOException;
import java.util.*;

/**
 * Cons-cell for testing
 */
public class TestCons implements java.io.Serializable {
  private Object _first;
  private Object _rest;

  public TestCons()
  {
  }

  public TestCons(Object first)
  {
    _first = first;
  }

  public TestCons(Object first, Object rest)
  {
    _first = first;
    _rest = rest;
  }

  public Object getFirst()
  {
    return _first;
  }

  public void setFirst(Object first)
  {
    _first = first;
  }

  public Object getRest()
  {
    return _rest;
  }

  public void setRest(Object rest)
  {
    _rest = rest;
  }

}

Java server exampleQHessian client example
  public Object replyObject_3()
{
TestCons cons = new TestCons();

cons.setFirst("a");
cons.setRest(cons);

return cons;
}
	void replyObject_3Call(){
QHessian::QHessianMethodCall call("replyObject_3");
call.invoke(networkManager,
urlTest2,
this,
SLOT(replyObject_3()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyObject_3(){
using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();

QString first;
qint32 ref;

parser >> BeginObject("", "com.caucho.hessian.test.TestCons");

//
// _first Object is string
//
if (parser.peek(Ref("_first", ref))) { //optional
throw std::runtime_error("unexcepted ref"); //optional
} //optional
parser >> String("_first", first); // first == a

//
// _rest if ref to first (0) object
//
if (!parser.peek(Ref("_rest", ref))) { //ref == 0
throw std::runtime_error("must be ref");
}
parser >> EndObject();

parser.deleteLater();
}

Q.16

How to read multi-typed object

Java classes:

package name.caiiiycuk.test;

/* Fruit (root of hierarchy)*/

public class Fruit implements Serializable {

	private static final long serialVersionUID = 6697223799952319341L;
	
	private final float  weight;
	
	public Fruit(float weight) {
		this.weight = weight;
	}
	
	public float getWeight() {
		return weight;
	}
	
}

/* Fruit -> Apple */

enum AppleColor {
	RED,
	GREEN
}

public class Apple extends Fruit {

	private static final long serialVersionUID = 7908387468053290925L;
	

	private final AppleColor color;

	public Apple(float weight, AppleColor color) {
		super(weight);
		this.color = color;
	}
	
	public AppleColor getColor() {
		return color;
	}
	
}

/* Fruit -> Banana */

enum BananaSize {
	HUGE, LITTLE
}

public class Banana extends Fruit {

	private static final long serialVersionUID = 1180374660481214068L;
	
	private final BananaSize bananaSize;
	
	public Banana(float weight, BananaSize bananaSize) {
		super(weight);
		this.bananaSize = bananaSize;
	}
	
	public BananaSize getBananaSize() {
		return bananaSize;
	}

}

/* Fruit -> Apple -> PlasticApple */

public class PlasticApple extends Apple {

	private static final long serialVersionUID = -8613694398769613071L;
	
	public PlasticApple(float weight, AppleColor color) {
		super(weight, color);
	}

}
Java server exampleQHessian client example
	@Override
public List<Fruit> getFruits() {
List<Fruit> fruitPack = new ArrayList<Fruit>();

fruitPack.add(new Apple(1.0f, AppleColor.RED));
fruitPack.add(new Apple(2.0f, AppleColor.GREEN));
fruitPack.add(new Banana(5.0f, BananaSize.HUGE));
fruitPack.add(new Banana(2.5f, BananaSize.LITTLE));
fruitPack.add(new PlasticApple(0.2f, AppleColor.GREEN));
fruitPack.add(new PlasticApple(0.2f, AppleColor.RED));

return fruitPack;
}
	void fruitCall() {
QHessian::QHessianMethodCall call("getFruits");
call.invoke(networkManager,
fruitUrl,
this,
SLOT(replyFruit()),
SLOT(error(int, const QString&)));
}
/*...*/
void replyFruit() {
qint32 fruitCount;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();

parser >> BeginCollection(fruitCount);

qint32 objectReaded = 0;

for (int i=0; i<fruitCount; i++) {
//
// Check for Apple
//
if (parser.peek(BeginObject("name.caiiiycuk.test.Apple"))) {
qreal weight;
QString color;

parser
>> Double("weight", weight)
//
// Enum object
//
>> BeginObject("color",
"name.caiiiycuk.test.AppleColor")
>> String("name", color)
>> EndObject()
>> EndObject();


//weight == 1, 2;
//color == "RED", "GREEN";
continue;
}

//
// Check For Banana
//
if (parser.peek(BeginObject("name.caiiiycuk.test.Banana"))) {
qreal weight;
QString bananaSize;

parser
>> Double("weight", weight)
>> BeginObject("bananaSize",
"name.caiiiycuk.test.BananaSize")
>> String("name", bananaSize)
>> EndObject()
>> EndObject();

//weight == 5, 2.5f
//bananaSize, == "HUGE", "LITTLE"
continue;
}

//
// Check for PlasticApple
//
if (parser.peek(BeginObject("name.caiiiycuk.test.PlasticApple"))) {
qreal weight;
qint32 colorRef;

parser
>> Double("weight", weight)
//
// REF to enum 4 == RED, 2 == GREEN
// (hardcoded on server just for test)
//
>> Ref("color", colorRef)
>> EndObject();


//weight == 0.2f, 0.2f
//colorRef == 4, 2
continue;
}
}

parser >> EndCollection();
parser.deleteLater();
}

Q.17

How to write Null

Java server exampleQHessian client example
  public void argNull(Object value)
{
}
	void argNullCall() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argNull");
call << Null();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argNull()),
SLOT(error(int, const QString&)));
}

Q.18

How to write Boolean

Java server exampleQHessian client example
  public void argBoolean(Boolean value);
	void argBooleanCall() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argBoolean");
call << Boolean(true);
call.invoke(networkManager,
urlTest2,
this,
SLOT(argBoolean()),
SLOT(error(int, const QString&)));
}

Q.19

How to write Integer

Java server exampleQHessian client example
  public void argInt(Integer value);
	void argIntCall() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argInt");
call << Integer(3145);
call.invoke(networkManager,
urlTest2,
this,
SLOT(argInt()),
SLOT(error(int, const QString&)));
}

Q.20

How to write Long

Java server exampleQHessian client example
  public void argLong(Long value);
	void argLongCall() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argLong");
call << Long(3145);
call.invoke(networkManager,
urlTest2,
this,
SLOT(argLong()),
SLOT(error(int, const QString&)));
}

Q.21

How to write Double

Java server exampleQHessian client example
  public void argDouble(Double value);
	void argLongCall() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argDouble");
call << Double(3.145);
call.invoke(networkManager,
urlTest2,
this,
SLOT(argDouble()),
SLOT(error(int, const QString&)));
}

Q.22

How to write Date

Java server exampleQHessian client example
  public void argDate_1(Date value);
	void argDate_1Call() {
QDateTime date;

TEST_START

using namespace QHessian::in;

date.setMSecsSinceEpoch(894621091000LL);
QHessian::QHessianMethodCall call("argDate_1");
call << DateTime(date);
call.invoke(networkManager,
urlTest2,
this,
SLOT(argDate_1()),
SLOT(error(int, const QString&)));
}

Q.23

How to write String

Java server exampleQHessian client example
  public void argString_31(String value);
	void argString_31Call() {
TEST_START

using namespace QHessian::in;

QHessian::QHessianMethodCall call("argString_31");
call << String("0123456789012345678901234567890");
call.invoke(networkManager,
urlTest2,
this,
SLOT(argString_31()),
SLOT(error(int, const QString&)));
}

Q.24

How to write Binary

Java server exampleQHessian client example
  public void argBinary_16(byte[] v);
	void argBinary_16Call() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argBinary_16");
call << Binary(QString("0123456789012345").toAscii());
call.invoke(networkManager,
urlTest2,
this,
SLOT(argBinary_16()),
SLOT(error(int, const QString&)));
}

Q.25

How to write untyped collection

Java server exampleQHessian client example
public void argUntypedFixedList_7(List v);
	void argUntypedFixedList_7Call() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argUntypedFixedList_7");
call << BeginCollection(7)
<< String("1")
<< String("2")
<< String("3")
<< String("4")
<< String("5")
<< String("6")
<< String("7")
<< EndCollection();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argUntypedFixedList_7()),
SLOT(error(int, const QString&)));
}

Q.26

How to write typed collection (String[``])

Java server exampleQHessian client example
public void argTypedFixedList_7(String[] v);
	void argUntypedFixedList_7Call() {
using namespace QHessian::in;

QHessian::QHessianMethodCall call("argTypedFixedList_7");
call << BeginCollection("", "[string", 7) //[string is your type
<< String("1")
<< String("2")
<< String("3")
<< String("4")
<< String("5")
<< String("6")
<< String("7")
<< EndCollection();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argTypedFixedList_7()),
SLOT(error(int, const QString&)));
}

Q.27

How to write untyped map

Java server exampleQHessian client example
public void argUntypedMap_2(Map<Integer,String> v);
	void argUntypedMap_2Call() {
using namespace QHessian::in;
QHessian::QHessianMethodCall call("argUntypedMap_2");
call << BeginMap()
<< Integer(0) << String("a") // key == 0, value == a
<< Integer(1) << String("b") // key == 1, value == b
<< EndMap();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argUntypedMap_2()),
SLOT(error(int, const QString&)));
}

Q.28

How to write typed map (hashtable)

Java server exampleQHessian client example
public void argUntypedMap_2(Hashtable<Integer,String> v);
	void argUntypedMap_2Call() {
using namespace QHessian::in;
QHessian::QHessianMethodCall call("argTypedMap_2");
call << BeginMap("", "java.util.Hashtable")
<< Integer(0) << String("a") // key == 0, value == a
<< Integer(1) << String("b") // key == 1, value == b
<< EndMap();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argTypedMap_2()),
SLOT(error(int, const QString&)));
}

Q.29

How to write Object

Object class:

package com.caucho.hessian.test;

/**
 * Empty object for short-encoding testing
 */
public class TestObject implements java.io.Serializable {
  private Integer _value;

  public TestObject()
  {
  }

  public TestObject(Object value)
  {
    _value = value;
  }

  public Integer getValue()
  {
    return _value;
  }
}

Java server exampleQHessian client example
public void argObject_1(TestObject v);
	void argObject_1Call() {
using namespace QHessian::in;
QHessian::QHessianMethodCall call("argObject_1");
call << BeginObject("com.caucho.hessian.test.TestObject")
<< Integer("_value", 0)
<< EndObject();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argObject_1()),
SLOT(error(int, const QString&)));
}

Q.30

How to write references

From hessian docs:

An integer referring to a previous list, map, or object instance. As each list, map or object is read from the input stream, it is assigned the integer position in the stream, i.e. the first list or map is '0', the next is '1', etc. A later ref can then use the previous object. Writers MAY generate refs. Parsers MUST be able to recognize them.

ref can refer to incompletely-read items. For example, a circular linked-list will refer to the first link before the entire list has been read.

A possible implementation would add each map, list, and object to an array as it is read. The ref will return the corresponding value from the array. To support circular structures, the implementation would store the map, list or object immediately, before filling in the contents.

Each map or list is stored into an array as it is parsed. ref selects one of the stored objects. The first object is numbered '0'.

Object class:

package com.caucho.hessian.test;

/**
 * Empty object for short-encoding testing
 */
public class TestObject implements java.io.Serializable {
  private Integer _value;

  public TestObject()
  {
  }

  public TestObject(Object value)
  {
    _value = value;
  }

  public Integer getValue()
  {
    return _value;
  }
}
Java server exampleQHessian client example
public void TestObject(List<TestObject> v);
	void argObject_2aCall() {
using namespace QHessian::in;
QHessian::QHessianMethodCall call("argObject_2a");
// first object (index 0)
call << BeginCollection(2)
// secong object (first is list) (index 1)
<< BeginObject("com.caucho.hessian.test.TestObject")
<< Integer("_value", 0)
<< EndObject()
// ref to com.caucho.hessian.test.TestObject
<< Ref(1)
<< EndCollection();
call.invoke(networkManager,
urlTest2,
this,
SLOT(argObject_2a()),
SLOT(error(int, const QString&)));
}

Q.31

How to call int method(int, int)

Java server exampleQHessian client example
  /**
* Subtraction
*/
public int subtract(int a, int b)
{
return a - b;
}
	void subtractCall() {
QHessian::QHessianMethodCall call("subtract"); // a-b

using namespace QHessian::in;

call << Integer(105) // a
<< Integer(100); // b

call.invoke(networkManager,
urlTest1,
this,
SLOT(replySubtractCall()),
SLOT(error(int, const QString&)));
}
/*...*/
void replySubtractCall() {
qint32 result;

using namespace QHessian::out;

QHessian::QHessianReturnParser& parser =
*(QHessian::QHessianReturnParser*) QObject::sender();
parser >> Integer(result);
parser.deleteLater();

//now result == 5
}

Testing

Each QHessian implementation must pass these tests:

Primitive types (Group 1):

  • read/write raw binary data
  • read/write boolean
  • read/write 64-bit millisecond date
  • read/write 64-bit double
  • read/write 32-bit int
  • read/write 64-bit long
  • read/write null
  • read/write UTF8-encoded string

Recursive types (Group 2):

  • read/write lists and arrays
  • read/write maps and dictionaries
  • read/write objects
  • read/write refs for shared and circular object references.

Hessian 2.0 addtitional tests (Group 3):

  • read/write object/list reference maps
  • read/write class definition reference maps
  • read/write type (class name) reference maps

We use standart test implementation form com.caucho.hessian.test:

  • Test.java, service link (after server starts) localhost:8080/test1
  • TestHessian2.java, service link (after server starts) localhost:8080/test2

Test.java includes this tests:

Test name Description Parameters Return value
nullCall Does nothing void void
hello Hello, World void string - Hellow, World
subtract Subtraction int a, int b a-b
echo Echos the object to the server Object Object
fault Throws an application fault void void throws IOException

TestHessian2.java includes this tests:

Test name Description Parameters Return value
methodNull trivial null method call void void
replyNull Result of null void void
replyTrue Boolean true void Object
replyFalse Boolean false void Object
replyInt_0 Result of integer 0 void int
replyInt_1 Result of integer 1 void int
replyInt_47 Result of integer 47 void int
replyInt_m16 Result of integer -16 void int
replyInt_0x30 Result of integer 0x30 void int
replyInt_0x7ff Result of integer x7ff void int
replyInt_m17 Result of integer -17 void int
replyInt_m0x800 Result of integer -0x800 void int
replyInt_0x800 Result of integer 0x800 void int
replyInt_0x3ffff Result of integer 0x3ffff void int
replyInt_m0x801 Result of integer -0x801 void int
replyInt_m0x40000 Result of integer m0x40000 void int
replyInt_0x40000 Result of integer 0x40000 void int
replyInt_0x7fffffff Result of integer 0x7fffffff void int
replyInt_m0x40001 Result of integer m0x40001 void int
replyInt_m0x80000000 Result of integer -0x80000000 void int
replyLong_0 Result of long 0 void long
replyLong_1 Result of long 1 void long
replyLong_15 Result of long 15 void long
replyLong_m8 Result of long -8 void long
replyLong_0x10 Result of long 0x10 void long
replyLong_0x7ff Result of long x7ff void long
replyLong_m9 Result of long -9 void long
replyLong_m0x800 Result of long -0x800 void long
replyLong_0x800 Result of long 0x800 void long
replyLong_0x3ffff Result of long 0x3ffff void long
replyLong_m0x801 Result of long -0x801 void long
replyLong_m0x40000 Result of long m0x40000 void long
replyLong_0x40000 Result of long 0x40000 void long
replyLong_0x7fffffff Result of long 0x7fffffff void long
replyLong_m0x40001 Result of long m0x40001 void long
replyLong_m0x80000000 Result of long -0x80000000 void long
replyLong_0x80000000 Result of long 0x80000000 void long
replyLong_m0x80000001 Result of long -0x80000001 void long
replyDouble_0_0 Result of double 0.0 void double
replyDouble_1_0 Result of double 1.0 void double
replyDouble_2_0 Result of double 2.0 void double
replyDouble_127_0 Result of double 127.0 void double
replyDouble_m128_0 Result of double -128.0 void double
replyDouble_128_0 Result of double 128.0 void double
replyDouble_m129_0 Result of double -129.0 void double
replyDouble_32767_0 Result of double 32767.0 void double
replyDouble_m32768_0 Result of double -32768.0 void double
replyDouble_0_001 Result of double 0.001 void double
replyDouble_m0_001 Result of double -0.001 void double
replyDouble_65_536 Result of double 65.536 void double
replyDouble_3_14159 Result of double 3.14159 void double
replyDate_0 date 0 (01-01-1970 00:00 GMT) void date
replyDate_1 Date by millisecond (05-08-1998 07:51:31.000 GMT) void date
replyDate_2 Date by minute (05-08-1998 07:51:00.000 GMT) void date
replyString_0 A zero-length string void String
replyString_null A null string void String
replyString_1 A one-length string void String
replyString_31 A 31-length string void String
replyString_32 A 32-length string void String
replyString_1023 1023-length string void String
replyString_1024 A 1024-length string void String
replyString_65536 A 65536-length string void String
replyBinary_0 A zero-length binary void Object
replyBinary_null A null string void Object
replyBinary_1 A one-length string void Object
replyBinary_15 A 15-length binary void Object
replyBinary_16 A 16-length binary void Object
replyBinary_1023 A 1023-length binary void Object
replyBinary_1024 A 1024-length binary void Object
replyBinary_65536 A 65536-length binary void Object
replyUntypedFixedList_0 Zero-length untyped list void Object
replyUntypedFixedList_1 1-length untyped list void Object
replyUntypedFixedList_7 7-length untyped list void Object
replyUntypedFixedList_8 8-length untyped list void Object
replyTypedFixedList_0 Zero-length typed list (String array) void Object
replyTypedFixedList_1 1-length typed list (String array) void Object
replyTypedFixedList_7 7-length typed list (String array) void Object
replyTypedFixedList_8 8-length typed list (String array) void Object
replyUntypedMap_0 zero-length untyped map void Object
replyUntypedMap_1 untyped map with string key void Object
replyUntypedMap_2 untyped map with int key void Object
replyUntypedMap_3 untyped map with list key void Object
replyTypedMap_0 zero-length typed map void Object
replyTypedMap_1 untyped map with string key void Object
replyTypedMap_2 typed map with int key void Object
replyTypedMap_3 typed map with list key void Object
replyObject_0 Returns a single object void Object
replyObject_16 Returns 16 object types void Object
replyObject_1 Simple object with one field void Object
replyObject_2 Simple two objects with one field void Object
replyObject_2a Simple repeated object void Object
replyObject_2b Two object with equals void Object
replyObject_3 Circular object void Object
argNull Null void Object
argTrue Boolean true void Object
argFalse Boolean false void Object
argInt_0 Integer 0 void Object
argInt_1 Integer 1 void Object
argInt_47 integer 47 void Object
argInt_m16 Result of integer -16 void Object
argInt_0x30 Integer 0x30 void Object
argInt_0x7ff Result of integer x7ff void Object
argInt_m17 integer -17 void Object
argInt_m0x800 Integer -0x800 void Object
argInt_0x800 Integer 0x800 void Object
argInt_0x3ffff Integer 0x3ffff void Object
argInt_m0x801 Integer -0x801 void Object
argInt_m0x40000 Integer m0x40000 void Object
argInt_0x40000 integer 0x40000 void Object
argInt_0x7fffffff Integer 0x7fffffff void Object
argInt_m0x40001 Integer m0x40001 void Object
argInt_m0x80000000 Result of integer -0x80000000 void Object
argLong_0 long 0 void Object
argLong_1 long 1 void Object
argLong_15 long 15 void Object
argLong_m8 long -8 void Object
argLong_0x10 long 0x10 void Object
argLong_0x7ff long x7ff void Object
argLong_m9 long -9 void Object
argLong_m0x800 long -0x800 void Object
argLong_0x800 long 0x800 void Object
argLong_0x3ffff long 0x3ffff void Object
argLong_m0x801 long -0x801 void Object
argLong_m0x40000 long m0x40000 void Object
argLong_0x40000 long 0x40000 void Object
argLong_0x7fffffff long 0x7fffffff void Object
argLong_m0x40001 long m0x40001 void Object
argLong_m0x80000000 long -0x80000000 void Object
argLong_0x80000000 Result of long 0x80000000 void Object
argLong_m0x80000001 Result of long -0x80000001 void Object
argDouble_0_0 double 0.0 void Object
argDouble_1_0 double 1.0 void Object
argDouble_2_0 double 2.0 void Object
argDouble_127_0 double 127.0 void Object
argDouble_m128_0 double -128.0 void Object
argDouble_128_0 double 128.0 void Object
argDouble_m129_0 double -129.0 void Object
argDouble_32767_0 double 32767.0 void Object
argDouble_m32768_0 Double -32768.0 void Object
argDouble_0_001 double 0.001 void Object
argDouble_m0_001 double -0.001 void Object
argDouble_65_536 double 65.536 void Object
argDouble_3_14159 Result of double 3.14159 void Object
argDate_0 date 0 (01-01-1970 00:00 GMT) void Object
argDate_1 Date by millisecond (05-08-1998 07:51 GMT) void Object
argDate_2 Date by minute (05-08-1998 07:51 GMT) void Object
argString_0 A zero-length string void Object
argString_1 A one-length string void Object
argString_31 A 31-length string void Object
argString_32 A 32-length string void Object
argString_1023 A 1023-length string void Object
argString_1024 A 1024-length string void Object
argString_65536 A 65536-length string void Object
argBinary_0 A zero-length binary void Object
argBinary_1 A one-length string void Object
argBinary_15 A 15-length binary void Object
argBinary_16 A 16-length binary void Object
argBinary_1023 A 1023-length binary void Object
argBinary_1024 A 1024-length binary void Object
argBinary_65536 A 65536-length binary void Object
argUntypedFixedList_0 Zero-length untyped list void Object
argUntypedFixedList_1 1-length untyped list void Object
argUntypedFixedList_7 7-length untyped list void Object
argUntypedFixedList_8 8-length untyped list void Object
argTypedFixedList_0 Zero-length typed list (String array) void Object
argTypedFixedList_1 1-length typed list (String array) void Object
argTypedFixedList_7 7-length typed list (String array) void Object
argTypedFixedList_8 8-length typed list (String array) void Object
argUntypedMap_0 zero-length untyped map void Object
argUntypedMap_1 untyped map with string key void Object
argUntypedMap_2 untyped map with int key void Object
argUntypedMap_3 untyped map with list key void Object
argTypedMap_0 zero-length typed map void Object
argTypedMap_1 untyped map with string key void Object
argTypedMap_2 typed map with int key void Object
argTypedMap_3 typed map with list key void Object
argObject_0 Returns a single object void Object
argObject_16 Returns 16 object types void Object
argObject_1 Simple object with one field void Object
argObject_2 Simple two objects with one field void Object
argObject_2a Simple repeated object void Object
argObject_2b Two object with equals void Object
argObject_3 Circular object void Object

About

Qt && C++ implementation of the hessian protocol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 63.5%
  • Java 36.2%
  • Other 0.3%