hessianphp调用java类_HessianPHP使用注意事项

HessianPHP_v2.0.3.zip, 在php作客户端,java作服务器端时,使用注意事项:

1.需要在php.ini中配置CURL模块:

extension=php_curl.dll

2.php传中文给java, 和java返回中文给php,都有中文乱码问题:

1)php和java文件本身都采用UTF-8编码

2)在php.ini中开启mbstring模块:

extension=php_mbstring.dll

同时配置:

mbstring.internal_encoding = UTF-8

因为:

Hessian2Writer.php文件:

functionwriteStringData($string){

return

HessianUtils::writeUTF8($string);

}

HessianUtils.php文件:

public

static function isInternalUTF8(){

$encoding

= ini_get('mbstring.internal_encoding');

if(!$encoding)

return

false;

return

$encoding == 'UTF-8';

}

3).response返回设置为UTF-8:

header("Content-Type: text/html; charset=UTF-8");

或者,统一改php.ini文件:

mbstring.http_output = UTF-8

;启用字符转换功能output_handler

= mb_output_handler

4)默认配置:

HessianFactory.php

define('HESSIAN_PHP_VERSION',

'2.0');--------->hessian

2.0协议

$this->transports

= array(

'CURL'

=> 'HessianCURLTransport',----------->传输协议

'curl'

=> 'HessianCURLTransport',

'http'

=> 'HessianHttpStreamTransport'

);

3.java返回值问题:

1).java端返回(自定义的)对象,在php端为stdClass

Object,

它具有一个属性 [__type] => org.model.User

2).而对于普通对象,例如java的Date对象,在php就是DateTime对象:

[birthday] =>DateTime

Object(

[date] => 2012-07-27 15:27:31 [timezone_type] => 1 [timezone]

=> +00:00 )

3).java的List, Set, Map,在php就是Array.

List为php的序号数组:

[productList1] => Array (

[0]

=> stdClass Object ( [__type] => org.model.Product [name]

=> 布匹 [price] => 300 )

)

Map为php的名称数组:

[productMap] => Array (

[布匹]

=> stdClass Object ( [__type] => org.model.Product [name]

=> 布匹 [price] => 300 )

)

java的返回值,php端不需要做任何特殊映射,可以直接采用->x->y的方式去取值显示.

4).同一个对象,即放在List中,又放在Map中,返回值中为什么只显示一处有值?

这其实是HessianPHP_v2.0.3.zip的一个bug.

hessian协议中为了减少重复对象的序列化,采用了引用的方式,参见:

Hessian 2.0 序列化协议规范

http://wenku.baidu.com/view/3832199951e79b8968022641.html

经过debug调试,发现:

需要修改Hessian2Parser.php中

function untypedMap($code, $num){

//if(HessianRef::isRef($key))

$key =

&$this->objectlist->reflist[$key->index];

//if(HessianRef::isRef($value))

$value =

&$this->objectlist->reflist[$value->index];

if(HessianRef::isRef($key))

$key =$this->refmap->objectlist[$value->index];

if(HessianRef::isRef($value))

$value =$this->refmap->objectlist[$value->index];

}

同样下面方法也需要修改:

function typedMap($code, $num)

{

...

}

测试结果:

objectstdClass Object ( [__type] => User [name] =>

yangwenchao杨文超 [country] => CHINA [birthday] => DateTime

Object ( [date] => 2012-07-28 09:02:32 [timezone_type] => 1

[timezone] => +00:00 ) [productList1] => Array ( [0]

=>stdClass

Object ( [__type] => Product [name] => 布匹 [price] => 300

))

[productList2] => Array ( ) [productList3] => [productMap]

=> Array ( [布匹一] =>stdClass

Object ( [__type] => Product [name] => 布匹 [price] => 300

)[布匹二]

=>stdClass

Object ( [__type] => Product [name] => 布匹 [price] => 300

))

)

4.php向java传参问题:

5.关于类型映射:

php是无类型的,默认情况下远程的Object都会变成php的stdClass这样的万能对象。持有这样的对象进行访问的时候,关于对象的属性name,

price等信息需要尝试指定。(工作正常)

但是如果把远程Object映射成php本地的自定义的phpObject以后,就可以用一个对象的模子class来框住对象的实体形式,而且编辑器还可以支持语法提示功能。

采用这种方式,在解析返回值时,可以得到便利,在向Java传递对象作为参数时,也可以提供一些便利。

$options=newHessianOptions();$options->typeMap['Person']='*.Person';$options->typeMap['CalendarHandler']='com.caucho.hessian.io.CalendarHandle';$options->parseFilters['@CalendarHandler']=array('CalendarHandler','calendarToDateTime');$options->writeFilters['@Person']=array('CalendarHandler','writePerson');

参见例子:

AdvancedExampleAdvanced

type mapping and filtering

http://code.google.com/p/hessianphp/wiki/AdvancedExample

如果不采用自动映射方式,php向java传参时,只能采用php原生的stdClass来传值:

$person

= new stdClass();

$person->__type

= 'org.model.Person';

//参照java返回值的形式,添加上__type属性,其实无效.

$person->id

= 1;

$person->firstName

= '杨';

$person->lastName

= '文超';

//$person->birthDate

= '';

$user

= $proxy->getUserABC($person);

在java端,总是抛出warning,

显然,java端无视了参数$person->__type的意义:

java.lang.ClassNotFoundException: stdClass

2012-7-28 11:13:22 com.caucho.hessian.io.SerializerFactory

getDeserializer

警告:Hessian/Burlap:

'stdClass' is an unknown class in

WebappClassLoader

context:

/springhessian

delegate:

false

repositories:

/WEB-INF/classes/

----------> Parent Classloader:

org.apache.catalina.loader.StandardClassLoader@1adc30

去掉warning的解决办法:

$options->typeMap['stdClass'] =

'org.model.Person';

$options

= new HessianOptions();

$options->typeMap['stdClass']

=

'org.model.Person';

$url

=

"http://localhost:8080/springhessian/remoting/hessianService";

$proxy

= new HessianClient($url,

$options);

echo

"

";

$person

= new stdClass();

$person->__type

= 'org.model.Person';

$person->id

= 1;

$person->firstName

= '杨';

$person->lastName

= '文超';

//$person->birthDate

= '';

$user

= $proxy->getUserABC($person);

工作正常。

但是这种方法,只能应对一个类型参数,如果有两个类型的参数,如org.model.Person和org.model.Company,就又无法正常工作了,

因为stdClass不知道到底需要映射到哪一个Java类型上。

所以,在php向java传参时,需要在php中自定义若干个与java相对应的类型,配合

$options->typeMap['Person'] =

'org.model.Person';

来一起完成参数类型映射功能。

例如:classPerson{

var$id;var$firstName;var$lastName;var$birthDate;}$p=newPerson();$p->firtName='John';$p->lastName='Sheppard';

$options=newHessianOptions();$options->typeMap['Person']='com.sample.hessian.Person';

$proxy=newHessianClient($url,$options);$result=$proxy->add($p);print_r($result);

另外:

$options->typeMap['Person']='com.sample.hessian.Person';->精确指定,可用于解析返回值,也可用于传参$options->typeMap['Person']='*.Person';------>采用通配,只适用于解析返回值,不能用于传参

6.关于类型自动映射的,回调处理:$options->parseFilters['@CalendarHandler']=array('CalendarHandler','calendarToDateTime');$options->writeFilters['@Person']=array('CalendarHandler','writePerson');对于包装类型,有两种方式处理:一是原生构建层级关系,二是采用回调去除包装一是原生构建层级关系:$p=newPerson();$p->firstName='John';$p->lastName='Sheppard';$p->birthDate=newCalendarHandler(newDateTime('1970-06-14 12:00:00'));...send theobject二是采用回调去除包装

$options->parseFilters['@CalendarHandler']=array('CalendarHandler','calendarToDateTime');$options->writeFilters['@Person']=array('CalendarHandler','writePerson');建议尽量不要有包装类型,如果一定有,采用“原生层级类型”比较容易理解一些。

7.原生传值:

public User getUserList(List list); -------->List ------>对应于php的数字array

public User getUserSet(Set set);-------->Set ------>对应于php的名字arraypublic User getUserMap(Map map);-------->Map------>对应于php的名字array//$parameter = array('杨', '文超'); //数字array//$parameter = array('firstName'=>'杨', 'lastName'=>'文超');//名字array$parameter = array('firstName'=>'杨', 'lastName'=>'文超');//名字array//$user = $proxy->getUserList($parameter);

//$user = $proxy->getUserSet($parameter);

$user = $proxy->getUserMap($parameter);

8.返回值为null

$user = ------->如果java端返回值为null,那么php端为$result = isset($user); ------->结果为false

echo $result; ------>打印后,显示不了false字样

PHP boolean to string with modification & a conditionhttp://stackoverflow.com/questions/3671455/php-boolean-to-string-with-modification-a-condition

echo(is_bool($x)?($x?"true":"false"):$x);Not the easiest to read but gets the job done!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值