参考:Thrift 连接 Java 与 Python,附 Java 通用工厂方法
上面这篇文章的例子是使用java client调用python server中的helloString方法来打印client传输过去的字符串
thrift文件,hello.thrift
service Hello { string helloString(1:string word) }
Server端
生成Python server端代码
thrift --gen py hello.thrift
python server端代码,其中包括生成的hello文件夹中的代码,以及server代码
from thrift.protocol import TBinaryProtocol from thrift.server import TServer from thrift.transport import TSocket from thrift.transport import TTransport from hello import Hello class HelloHandler: def __init__(self): pass def helloString(self, word): ret = "hello Thrift! Received: " + word return ret # handler processer类 handler = HelloHandler() processor = Hello.Processor(handler) transport = TSocket.TServerSocket("127.0.0.1", 8989) # 传输方式,使用buffer tfactory = TTransport.TBufferedTransportFactory() # 传输的数据类型:二进制 pfactory = TBinaryProtocol.TBinaryProtocolFactory() # 创建一个thrift 服务~ server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) print("Starting thrift server in python...") server.serve() print("done!")
Client端
生成java client代码
thrift --gen java hello.thrift
pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>thrift-example</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.10.0</version> </dependency> </dependencies> </project>
java client的代码
package com.example.tutorial; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class ThriftFactory { private ThriftFactory() { } private static final Logger LOG = LoggerFactory.getLogger(ThriftFactory.class); private static TProtocol protocol; private static TTransport transport; /** * 获取二进制 protocol * * @return 二进制 protocol */ public static TProtocol getTProtocol() { // 单例获取 protocol if (protocol == null) { protocol = new TBinaryProtocol(getTTransport()); } return protocol; } /** * 获取传输对象 * * @return 传输对象 */ public static TTransport getTTransport() { // 单例获取 transport if (transport == null) { // 应改成从配置文件读取 String ip = "127.0.0.1"; Integer port = 8989; transport = new TSocket(ip, port); } return transport; } /** * 获取客户端实例 * * @param clazz 客户端类 * @param <T> 泛型 * @return 客户端实例 */ public static <T> T getClient(Class<T> clazz) { T instance = null; try { //获取有参构造器 Constructor c = clazz.getConstructor(TProtocol.class); // 实例化客户端,需要传入 protocol instance = (T) c.newInstance(getTProtocol()); } catch (Exception e) { LOG.error("", e); throw new RuntimeException(e.getMessage()); } return instance; } /** * 发起请求 * * @param clazz 客户端类 * @param methodName 方法名,客户端中不能有重载的方法 * @param param 方法参数 * @param <T> 泛型 * @return 方法返回值 */ public static <T> Object doRequest(Class<T> clazz, String methodName, Object... param) { Object result = null; try { // 获取客户端实例 T instance = getClient(clazz); Method[] methods = clazz.getMethods(); for (Method method : methods) { // 获取指定的方法 if (method.getName().equals(methodName)) { open(); result = method.invoke(instance, param); close(); break; } } } catch (Exception e) { LOG.error("", e); throw new RuntimeException(e.getMessage()); } return result; } /** * 打开传输 */ public static void open() { try { getTTransport().open(); } catch (TTransportException e) { LOG.error("", e); throw new RuntimeException(e.getMessage()); } } /** * 关闭传输 */ public static void close() { getTTransport().close(); } }
client主函数
package com.example.tutorial; public class ThriftExample { public static void main(String[] args) { String msg = (String) ThriftFactory.doRequest(com.example.tutorial.Hello.Client.class, "helloString", "测试"); System.out.println(msg); } }
运行python server
运行java client,调用了python的helloString方法