上周五做大流程調(diào)試的時(shí)候,線下test環(huán)境QA發(fā)現(xiàn)andriod端一訪問就crash的問題。QA在群里@all妨托,crash已經(jīng)阻塞測(cè)試,于是我就去排查劳淆。Andrioa端同學(xué)說crash的原因是因?yàn)楹蠖藗鬟^來的字段不符合約定。原本約定的rightlabels字段是一維數(shù)組:
"rightlabels":[]
傳來過的確實(shí)二維數(shù)組:
"rightlabels":[[]]
這個(gè)rightlabels是我組裝傳過去的千埃,沒錯(cuò)憔儿。但我不會(huì)組裝二維的list,怎么就出現(xiàn)了二維的list呢放可?最后發(fā)現(xiàn)我寫的java代碼在異常情況下會(huì)傳:
"rightlabels":[{}]
一個(gè)一維的list里面放了一個(gè)空對(duì)象過去谒臼。即使這樣也不應(yīng)該出現(xiàn)list里面套list啊。從日志來看耀里,確實(shí)是我這邊傳了"rightlabels":[{}]
過去導(dǎo)致的crash蜈缤,但不解的是為什么會(huì)變成二維度的list。聯(lián)系調(diào)用方冯挎,他們說自己對(duì)這個(gè)字段只做了透?jìng)鞯赘纾蛔鋈魏味畏庋b什么的,我的服務(wù)調(diào)用方是PHP編寫的房官,我感覺可能是一個(gè)跨語言解析上的錯(cuò)誤趾徽。
為了復(fù)現(xiàn)這個(gè)情況,我本地搭建了thrift環(huán)境翰守,php編寫client端孵奶,java編寫server端 (注:下面的代碼不是工程的全部,是部分主要代碼)蜡峰。
Java Server端:
package com.meituan.thrift.demo;
import org.apache.thrift.TException;
public class HelloWorldImpl implements HelloWorldService.Iface{
public HelloWorldImpl() {
}
public String sayHello(String username) throws TException {
System.out.println(username);
return "{\"rightlabels\":[{}]}";
}
}
package com.meituan.thrift.demo;
import com.sun.tools.javac.util.Pair;
import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import java.io.IOException;
public class HelloServer {
public final static int SERVER_PORT = 7099;
private static String SERVER_IP = "127.0.0.1";
public void startServer() {
try{
System.out.println("HelloWorld Server Start ...");
TServerSocket serverSocket = new TServerSocket(SERVER_PORT);
TServer.Args args = new TServer.Args(serverSocket);
TProcessor processor = new HelloWorldService.Processor(new HelloWorldImpl());
TBinaryProtocol.Factory portFactory = new TBinaryProtocol.Factory(true,true);
args.processor(processor);
args.protocolFactory(portFactory);
TServer server = new TSimpleServer(args);
server.serve();
} catch(Exception e) {
System.out.println("Server Start Error...");
e.printStackTrace();
}
}
public static void main(String[] args) {
HelloServer server = new HelloServer();
server.startServer();
}
}
Php Client端:
<?php
require_once __DIR__.'/thrift/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php';
use Thrift\ClassLoader\ThriftClassLoader;
$GEN_DIR = realpath(dirname(__FILE__)).'/gen-php';
$loader = new ThriftClassLoader();
$loader->registerNamespace('Thrift', __DIR__ . '/thrift/lib/php/lib');
$loader->registerDefinition('shared', $GEN_DIR);
$loader->registerDefinition('com', $GEN_DIR);
$loader->register();
try {
$socket = new Thrift\Transport\TSocket('localhost', 7099);
$transport = new Thrift\Transport\TBufferedTransport($socket, 1024, 1024);
$protocol = new Thrift\Protocol\TBinaryProtocolAccelerated($transport);
$client = new com\meituan\thrift\demo\HelloWorldServiceClient($protocol);
$transport->open();
$result = $client->sayHello("TaoMin HelloWorld ");
$resultObj = json_decode($result, true);
if ( isset($resultObj['rightlabels']) ) {
var_dump($resultObj);
}
var_dump(json_encode($resultObj));
} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
Java傳過去的是:"{\"rightlabels\":[{}]}"
了袁。最后發(fā)現(xiàn),是因?yàn)閜hp先json_decode傳過來的json湿颅,然后再json_encode载绿,這個(gè)過程中,Java傳來的空對(duì)象被php解析成了空數(shù)組油航,然后再encode就變成了圖上紅框看到的那樣了崭庸。
一句話總結(jié):跨語言配合需謹(jǐn)慎....
end ~