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

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

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

结果,它看起来像thrift强制自己成为我的服务器的独有持久性格式 – 除非,我创建一个围绕Thrift的数据编组包装器或其他处理这些数据结构的持久性格式(hibernate, Jackson,scala BeanProperty,…)。 然而,这违背了自动化数据编组工具(如节俭)的目的,直接导致容易出错的世界,即必须保持相同但独立的接口和数据结构(=浪费有才华的工程师时间和能量)。

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

你可以使用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 eventList = Collections.emptyList(); ThriftServiceProcessor proc = new ThriftServiceProcessor(codecManager, eventList, svc); this.processors.put(name, proc); this.multiplex.registerProcessor(name, NiftyProcessorAdapters.processorToTProcessor(proc)); } 

此示例中的Multiplex实例变量是来自libthrift.jarTMultiplexedProcessor的实例。

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

 @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(); } } } 

仅供参考 – TJSONProtocol不适用于版本0.14之前的Swift版本,所以此时如果需要使用它,则需要从源代码构建。

另外……斯威夫特强迫你的结构被标记为final … JPA规范说实体不能是final …似乎无论如何都可以使用Eclipselink但是YMMV

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

结果,它看起来像节俭强制自己成为我的服务器的独有持久性格式[…]

这不是Thrifts的错,它可能是任何格式。

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

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

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

你看,尽管你可以选择其中一种格式作为“最喜欢的主数据格式”,但从技术上讲你不必这样做。


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

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