使用技术:thrift的rpc服务
问题提出:在java和.net交互的时候,默认值导致数据修改问题。
基本数据类型在服务端传输前没有设置isset值,传输到客户端还是出现isset=true的现象。
解决方案:将所有非必须变量添加修饰符optional,这样thrift在序列化的时候发现修饰符为optional并且
isset=false的值时,就会忽略。
下面的问题测试demo:
idl定义文件(BorrowPerson.thrift):
namespace java littlehow.thrift.demo.optional
#person结构,其中身高是可选的
struct Person
{
1:i64 id,
2:string name,
3:i32 age,
4:optional i16 height,
5:optional Work work
}
#工作信息,工作年限是可选的,工资有可选参数,并且有默认值
struct Work
{
1:i32 workid,
2:optional i16 workage,
3:optional string salary = "2500.00"
}
service BorrowPerson
{
Person borrowPerson(1:i64 personId)
}
public long id; // required
public String name; // required
public int age; // required
public short height; // optional
public Work work; // optional
public int workid; // required
public short workage; // optional
public String salary; // optional
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
public static class Factory implements org.apache.thrift.TServiceClientFactory {
public Factory() {}
public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
return new Client(prot);
}
public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
return new Client(iprot, oprot);
}
}
public Client(org.apache.thrift.protocol.TProtocol prot)
{
super(prot, prot);
}
public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
super(iprot, oprot);
}
public Person borrowPerson(long personId) throws TException
{
send_borrowPerson(personId);
return recv_borrowPerson();
}
public void send_borrowPerson(long personId) throws TException
{
borrowPerson_args args = new borrowPerson_args();
args.setPersonId(personId);
sendBase("borrowPerson", args);
}
public Person recv_borrowPerson() throws TException
{
borrowPerson_result result = new borrowPerson_result();
receiveBase(result, "borrowPerson");
if (result.isSetSuccess()) {
return result.success;
}
throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "borrowPerson failed: unknown result");
}
}
package littlehow.thrift.demo.call.optional;
import littlehow.thrift.demo.optional.BorrowPerson;
import littlehow.thrift.demo.optional.Person;
import littlehow.thrift.demo.optional.Work;
import org.apache.thrift.TException;
import java.util.HashMap;
import java.util.Map;
/**
* BorrowPerson
*
* @author littlehow
* @time 2016-06-27 10:18
*/
public class BorrowPersonImpl implements BorrowPerson.Iface{
private static Map persons = new HashMap();
static {
//所有信息齐全
Person person = new Person();
person.setId(1);
person.setName("littlehow");
person.setAge(18);
person.setHeight((short) 140);
Work work = new Work();
work.setSalary("500.00");
work.setWorkage((short) 8);
work.setWorkid(1);
person.setWork(work);
persons.put(Long.valueOf(1), person);
//所有信息不全
person = new Person();
person.setId(2);
person.setName("不全");
work = new Work();
work.setWorkid(2);
person.setWork(work);
persons.put(Long.valueOf(2), person);
}
/**
* 借人
* @param personId
* @return
* @throws TException
*/
public Person borrowPerson(long personId) throws TException {
if (personId > 2 || personId < 1) return null;
return persons.get(personId);
}
}
package littlehow.thrift.demo.call.optional;
import littlehow.thrift.demo.AppendService;
import littlehow.thrift.demo.call.AppendServiceImpl;
import littlehow.thrift.demo.optional.BorrowPerson;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
/**
* Created by littlehow on 2016/6/27 0024.
*/
public class Server {
public final static int port = 7456;
public void start() {
try {
/** BorrowPerson */
TProcessor processor = new BorrowPerson.Processor(new BorrowPersonImpl());
/** 设置监听端口 */
TServerTransport transport = new TServerSocket(port);
/** 采用TCompactProtocol传输协议,服务端和客户端协议使用必须一致
* 可选的协议有:TBinaryProtocol/TJSONProtocol/TSimpleJSONProtocol/TTupleProtocol
* 其中TTupleProtocol是TCompactProtocol的子类,可以根据自己的业务选择对应的协议
*/
TProtocolFactory pf = new TCompactProtocol.Factory();
TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(transport).protocolFactory(pf).processor(processor));
System.out.println("server started ,port is " + port);
server.serve();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server().start();
}
}
package littlehow.thrift.demo.call.optional;
import littlehow.thrift.demo.AppendService;
import littlehow.thrift.demo.call.Server;
import littlehow.thrift.demo.optional.BorrowPerson;
import littlehow.thrift.demo.optional.Person;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
/**
* Created by littlehow on 2016/6/27 0024.
*/
public class Client {
public final String address = "localhost";
public void run() {
try {
TTransport transport = new TSocket(address, Server.port);
transport.open();
TProtocol protocol = new TCompactProtocol(transport);
BorrowPerson.Client client = new BorrowPerson.Client(protocol);
System.out.println(System.currentTimeMillis());
//信息齐全
Person person1 = client.borrowPerson(1);
//Person(id:1, name:littlehow, age:18, height:140, work:Work(workid:1, workage:8, salary:500.00))
System.out.println(person1);
//信息不全
Person person2 = client.borrowPerson(2);
//Person(id:2, name:不全, age:0, work:Work(workid:2, salary:2500.00))
System.out.println(person2);
System.out.println("height的设置情况:"+person2.isSetHeight());//false
System.out.println("age的设置情况:"+person2.isSetAge());//true
System.out.println("work.workage的设置情况:" + person2.getWork().isSetWorkage());//false
System.out.println(System.currentTimeMillis());
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Client().run();
}
}
Person(id:2, name:不全, age:0, work:Work(workid:2, salary:2500.00))