可以从现有的java / scala接口和数据类型生成.thrift文件吗?

时间:2014-09-03 16:25:31

标签: java scala thrift thrift-protocol

是否有一种简单的方法可以获取现有的Java / scala数据类型和API接口并生成相应的.thrift文件?让Thrift生成服务器数据结构是过度侵入的,因为它会产生后果:

  • 我无法注释我的数据结构(例如,XML,JSON,hibernate持久性......)。
  • 此模式与其他想要拥有或需要修改源文件的序列化框架冲突。

结果,似乎thrift强迫自己成为我的服务器的独有持久性格式 - 除非,即我创建围绕Thrift的数据编组包装器或其他处理这些数据结构的持久性格式(休眠,杰克逊,scala BeanProperty,......)。然而,这违背了自动化数据编组工具(例如节俭)的目的,直接导致容易出错的世界,即必须保持相同但独立的接口和数据结构(=浪费有才华的工程师时间和能量)。

我对Thrift自动生成客户端代码感到非常满意。但是,我(强烈)认为我需要自由编辑我的服务器在API中处理的数据结构。

3 个答案:

答案 0 :(得分:5)

您可以使用Swift

长话短说;注释您的类和接口(Thrift用语中的结构和服务)。然后,您可以运行Swift的客户端/服务器代码,也可以使用swift2thrift生成器生成等效的IDL,并使用Thrift编译器生成客户端(后者是我推荐用于您所描述的内容)。

一旦完成创建可以在具有普通TProtocol / TTransport对象的TServlet中使用的TProcessor,在servlet的init()中执行类似的操作:

protected void addProcessor(String name, Object svc) {
    ThriftCodecManager codecManager = new ThriftCodecManager(
        new CompilerThriftCodecFactory(false)
    );
    List<ThriftEventHandler> eventList = Collections.emptyList();
    ThriftServiceProcessor proc = new ThriftServiceProcessor(codecManager, eventList, svc);
    this.processors.put(name, proc);
    this.multiplex.registerProcessor(name, NiftyProcessorAdapters.processorToTProcessor(proc));
}

此示例中的Multiplex实例变量是来自TMultiplexedProcessor的{​​{1}}的实例。

然后在doPost()中执行此操作:

libthrift.jar

仅供参考 - TJSONProtocol在版本0.14之前不适用于Swift版本,因此,如果您需要使用该版本,则需要从源代码构建。

另外...... Swift强制将您的结构标记为@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { getServletContext().log("entering doPost()"); TTransport inTransport = null; TTransport outTransport = null; try { InputStream in = request.getInputStream(); OutputStream out = response.getOutputStream(); TTransport transport = new TIOStreamTransport(in, out); inTransport = transport; outTransport = transport; TProtocol inProtocol = getInProtocolFactory().getProtocol(inTransport); TProtocol outProtocol = getOutProtocolFactory().getProtocol(outTransport); if (multiplex.process(inProtocol, outProtocol)) { out.flush(); } else { throw new ServletException("multiplex.process() returned false"); } } catch (TException te) { throw new ServletException(te); } finally { if (inTransport != null) { inTransport.close(); } if (outTransport != null) { outTransport.close(); } } } ... JPA规范称实体不能final ...无论如何都可以使用Eclipselink但是YMMV < / p>

答案 1 :(得分:3)

因为你提到了Java:对于我们的一些项目,我确实实现了一个基于Xtext的解决方案,该解决方案从项目特定的DSL生成源代码和Thrift IDL文件。由于Xtext / Xtend基于Java,如果该解决方案能够满足您的需求,至少值得一看。但是,我有一种轻微的感觉,认为你的情况可能有点过分。

  

因此,它看起来像是节俭强迫自己成为我服务器的独有持久性格式[...]

这不是Thrifts错误,它可以是任何格式。

  

但是,我(强烈)认为我需要自由编辑我的服务器在API中处理的数据结构。

我完全同意。特别是在这种情况下,建议将序列化与内部数据结构分开,并将序列化视为实际情况:只需一种方法来操作数据 1)。如果你有多种序列化格式,你总会以类似的方式多次实现很多东西。这种效果或多或少是不可避免的,使我们有机会以任何最佳方式进行该项目。

简单的序列化策略适用于一种格式。使用两种/三种格式变得很麻烦,最后变成一种具有三种以上格式的真正PITA。 2)与往常一样,可维护和可扩展的解决方案是以增加一些复杂性为代价的。 3)

你知道,尽管你可以选择其中一种格式作为最喜欢的主数据格式&#34;,但从技术上讲,你不必这样做。


(1)令人惊讶的编程初学者教程和书籍的百分比未能正确地指出这一点。 (2)这正是我在开头提到的通过DSL解决的用例。 (3)是的,我知道YAGNI的意思。我知道如何估计风险的期望值。

答案 2 :(得分:0)

没有。 Thrift只应该用于客户端和服务器之间的消息,而不是用于内部服务器的持久性:例如,您将如何查询它?