Open JerryChaox opened 6 years ago
你能给个最小化的复现例子吗?比如你的服务配置,调用的数据什么的?
$client = new Yar_Client("http://localhost:8003/api/merchant"); $result = $client->getMerchant(1);
@yar(“api/merchant”) class MerchantService { public Merchant getMerchant(int MerchantId); }
暴露 demoYar:8003 public Merchant getMerchant(int merchantId) { 数据库查询 }
class Merchant { int id; String name; //有中文的时候出现unpack error }
数据示例 id:1 name:”阿斯顿”
a:3:{s:1:"r";O:8:"Merchant":11:{s:2:"id";i:1;s:4:"name";s:3:"asd";s:20:"authenticationNumber";N;s:4:"rate";d:0.2;s:7:"address";s:3:"阿斯顿";s:5:"phone";s:11:"18588557892";s:20:"authenticationStatus";i:1;s:10:"createTime";N;s:10:"updateTime";N;s:6:"chanel";N;s:8:"storeSet";a:0:{}}s:1:"s";s:1:"0";s:1:"i";i:0;}
把中文的字符的长度扩大1倍后,仍然会出现unpack error
PHPUnserializer unserializer = new PHPUnserializer(new String(data, 0, data.length, "ISO-8859-1")); PherializePackager中decode方法解码后的数据包字符串 a:3:{s:1:"i";i:731930421;s:1:"m";s:11:"addMerchant";s:1:"p";a:1:{i:0;a:5:{s:4:"name";s:9:"é¿æ¯é¡¿";s:4:"rate";s:3:"0.2";s:7:"address";s:33:"å京å¸è¾åºä¸ååºé¿æ¯é¡¿";s:5:"phone";s:11:"18588557892";s:20:"authenticationStatus";i:1;}}}
name的值为 阿斯顿 address的值为 北京市市辖区东城区
解包和压包时字符串的处理明显不一样
修改代码为下可解决中文问题 Serializer.java
private void serializeString(final String string, final StringBuffer buffer)
{
String tempString = string;
try {
tempString = new String(string.getBytes("UTF-8"),"ISO-8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int length = tempString.length();
buffer.append("s:");
buffer.append(length);
buffer.append(":\"");
buffer.append(tempString);
buffer.append("\";");
}
PherializePackager.java
public <E> byte[] encode(E value) throws IOException {
return Pherialize.serialize(value).getBytes("ISO-8859-1");
}
非常感谢反馈,PHPserializer是使用的第三方jar包,我们尽快评估一下如何修复这个问题。 推荐使用json或msgpack方式进行序列化
请问yar协议下如何指定序列化方式
yar协议需要client调用端指定序列化方式,server端自适应。
php侧可以通过yarclient配置
$client = new Yar_Client("http://10.236.62.73:8003/openapi/yarserver/test");
#$client->SetOpt(YAR_OPT_PACKAGER, "JSON");
#$client->SetOpt(YAR_OPT_PACKAGER, "PHP");
$client->SetOpt(YAR_OPT_PACKAGER, "MSGPACK");
$client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, 2000);
#$client->SetOpt(YAR_OPT_TIMEOUT, 2000);
如果是java client,如下设置:
HttpYarClient yarClient = new HttpYarClient();
yarClient.setPackageName("JSON");
// yarClient.setPackageName("MSGPACK");
感谢,请问服务端序列化的方式目前只有一种吗
yar协议支持三种序列化方式,PHP、JSON、MSGPACk,server端都已经可以支持。server端根据client发送的协议中的对应字段自动选择对应的序列化方式。 不过目前PHP的序列化并没有比较理想的第三方java扩展包,微博内部使用的是JSON和MSGPACK这两种方式。
@JerryChaox 推荐使用 Motan 最新的跨语言解决方案 Motan2 + Simple 序列化
yar协议碰到中文之后,在php端出现unpack error