去年2009-07-13在百度空間寫的一篇hessian的使用總結,今天把它轉過來
公司因業務需求準備開放一些API介面讓代理商使用,周末抽了些時間瞭解了一下這方面的技術後,決定採用caucho.com的Hessian實現(hessian使用方便又高效)
測試環境
- Window XP
- JDK 1.6
- Resin3.1.9
- Spring2.0.8
- hessian-3.0.20.jar(這個版本要與spring的對應,不要一味的追求最新版,我因為這個,不知是好還是壞的毛病吃了N多苦頭)
- HessianPHP-1.0.5-RC2
- Apache2.2
- PHP5.3.0
剛開始跑Java伺服器端和客服端的測試都很順利,但是當使用php5.3做為用戶端訪問Java時出現了好幾個問題
Php代碼
- include_once
'../dist/Hessian.php'
;
- include_once
'../dist/HessianClient.php'
;
-
- Hessian :: mapRemoteType('com.hisupplier.showroom.webservice.QueryParams'
,
'QueryParams'
);
- Hessian :: mapRemoteType('com.hisupplier.showroom.webservice.ListResult'
,
'ListResult'
);
- Hessian :: mapRemoteType('com.hisupplier.showroom.entity.Product'
,
'Product'
);
- Hessian :: mapRemoteType('com.hisupplier.commons.page.Page'
,
'Page'
);
-
- try {
- $params
=
new
QueryParams(114);
-
- $url
=
"http://guiyou.jiaming.com/webService"
;
- $proxy
=
new
HessianClient(
$url
);
- echo
"<br>"
;
- print_r($proxy
->hello(
$params
));
- echo
"<br>"
;
- print_r($proxy
->getProduct(
$params
));
- echo
"<br>"
;
- print_r($proxy
->getList(
$params
));
//要命的問題出在這裡
- } catch (HttpError $ex
) {
- ...
- }
include_once '../dist/Hessian.php';include_once '../dist/HessianClient.php';Hessian :: mapRemoteType('com.hisupplier.showroom.webservice.QueryParams', 'QueryParams');Hessian :: mapRemoteType('com.hisupplier.showroom.webservice.ListResult', 'ListResult');Hessian :: mapRemoteType('com.hisupplier.showroom.entity.Product', 'Product');Hessian :: mapRemoteType('com.hisupplier.commons.page.Page', 'Page');try { $params = new QueryParams(114); $url = "http://guiyou.jiaming.com/webService"; $proxy = new HessianClient($url); echo "<br>"; print_r($proxy->hello($params)); echo "<br>"; print_r($proxy->getProduct($params)); echo "<br>"; print_r($proxy->getList($params)); //要命的問題出在這裡} catch (HttpError $ex) { ...}
Java代碼
- public
interface
ShowroomAPI {
- String hello(QueryParams params);
- ListResult<Product> getList(QueryParams params);
- Product getProduct(QueryParams params);
- }
public interface ShowroomAPI { String hello(QueryParams params); ListResult<Product> getList(QueryParams params); Product getProduct(QueryParams params);}
第1個問題
因為php5.2.x版本後內建了DateTime類,和 HessianPHP 中的發生衝突
解決:
改檔案DateTime.php 為 HessianDateTime.php,類DateTime 為 HessianDateTime
第2個問題
PHP Warning: date(): It is not safe to rely on the system's timezone
settings. You are *required* to use the date.timezone setting or the
date_default_timezone_set() function. In case you used any of those
methods and you are still getting this warning, you most likely
misspelled the timezone identifier. We selected 'UTC' for '8.0/no DST'
instead in G://php//HessianPHP//dist//Hessian.php on line 74
解決:
將date() 方法都改為 date_default_timezone_set()
第3個問題
Php代碼
- Exception: Hessian Parser, Malformed reply: expected r Code: 2 exception
'HessianError'
with message
'Hessian Parser, Malformed reply: expected r'
in E:/workspace/php-test/dist/Protocol.php:339 Stack trace:
- #0 E:/workspace/php-test/dist/HessianClient.php(215): HessianParser->parseReply()
- #1 E:/workspace/php-test/dist/Filter.php(159): HessianProxy->executeCall('getList'
, Array)
- #2 E:/workspace/php-test/dist/Filter.php(73): ProxyFilter->execute(Object(HessianProxy), Object(FilterChain))
- #3 E:/workspace/php-test/dist/Filter.php(191): FilterChain->doFilter(Object(HessianProxy))
- #4 E:/workspace/php-test/dist/Filter.php(73): PHPErrorReportingFilter->execute(Object(HessianProxy), Object(FilterChain))
- #5 E:/workspace/php-test/dist/HessianClient.php(182): FilterChain->doFilter(Object(HessianProxy))
- #6 E:/workspace/php-test/dist/HessianClient5.php(94): HessianProxy->call('getList'
, Array)
- #7 [internal function
]: HessianClient->__call(
'getList'
, Array)
- #8 E:/workspace/php-test/tests/test.php(23): HessianClient->getList(Object(QueryParams))
- #9 {main}
Exception: Hessian Parser, Malformed reply: expected r Code: 2 exception 'HessianError' with message 'Hessian Parser, Malformed reply: expected r' in E:/workspace/php-test/dist/Protocol.php:339 Stack trace: #0 E:/workspace/php-test/dist/HessianClient.php(215): HessianParser->parseReply() #1 E:/workspace/php-test/dist/Filter.php(159): HessianProxy->executeCall('getList', Array) #2 E:/workspace/php-test/dist/Filter.php(73): ProxyFilter->execute(Object(HessianProxy), Object(FilterChain)) #3 E:/workspace/php-test/dist/Filter.php(191): FilterChain->doFilter(Object(HessianProxy)) #4 E:/workspace/php-test/dist/Filter.php(73): PHPErrorReportingFilter->execute(Object(HessianProxy), Object(FilterChain)) #5 E:/workspace/php-test/dist/HessianClient.php(182): FilterChain->doFilter(Object(HessianProxy)) #6 E:/workspace/php-test/dist/HessianClient5.php(94): HessianProxy->call('getList', Array) #7 [internal function]: HessianClient->__call('getList', Array) #8 E:/workspace/php-test/tests/test.php(23): HessianClient->getList(Object(QueryParams)) #9 {main}
google, baidu了半天也沒找到相關的文章,後來把apache和php分別降到2.0和5.1還是不行,最後快放棄了試了一下yahoo,哦!my god佛祖保佑阿門,讓我找了一了篇文章
引用
Chunked http responses cause a protocol parse error
Http.php is written to perform an HTTP POST using HTTP/1.1 which means that
the Hessian client must support a HTTP header of "Transfer-Encoding:
chunked".
Protocol::parseReply() is written as follows:
if($this->read(1) != 'r') {
return new HessianError('Hessian Parser, Malformed reply: expected
r',HESSIAN_PARSER_ERROR,0,$this->stream);
}
which will fail because the first line of a chunked response will contain
the chunk length. Protocol::parseReply() needs to be written to support
chunking.
At the moment the workaround I have is to set HTTP/1.0 in Http::POST.
解決:
把Http.php中的1.1改為1.0
在Http.php第200行: $out = "POST $this->url HTTP/1.1/r/n";