thrift:swift 命令行生成 IDL文件及Client java代码过程

swift是一个用于创建thrift 序列化类型和服务的java工具库,使用swfit可以生成非常简洁的java代码。并且更重要的是可以通过java代码生成接口描述文件(Thrift interface description language,IDL). 多数情况下,服务端的应用都是java写的。使用swift提供的工具,可以直接生成IDL,再用IDL生成其他语言的client端代码 (java,cpp,python…)

下面的TestService.java定义了一个简单的服务接口,本文以实例的例子说明将这个服务接口生成thrift client端代码的过程: TestService.java

package net.gdface.facelog;
import com.facebook.swift.service.ThriftMethod;
import com.facebook.swift.service.ThriftService;
@ThriftService
public interface TestService {
    @ThriftMethod
    public void setBean(TestBean bean);
    @ThriftMethod
    public TestBean getBean() throws ServiceRuntime;
}

TestBean.java

package net.gdface.facelog;
import com.facebook.swift.codec.ThriftField;
import com.facebook.swift.codec.ThriftStruct;

@ThriftStruct
public final class TestBean{
    private Integer id;
    public TestBean() {
    }
    @ThriftField(1)
    public Integer getId() {
        return id;
    }
    @ThriftField()
    public void setId(Integer id) {
        this.id = id;
    }
}

下载Swift2Thrift Code Generator

我们首先要从TestService.java生成 IDL文件。这需要用到swift提供的工具:Swift2Thrift Code Generator 为了便于在命令行执行,要下载包含所有依赖库的standalone版本

url地址下载

maven仓库 0.14.2 standalone版本下载地址 : http://central.maven.org/maven2/com/facebook/swift/swift2thrift-generator-cli/0.14.2/swift2thrift-generator-cli-0.14.2-standalone.jar

maven命令下载

执行maven命令下载swift2thrift-generator-cli-0.14.2-standalone.jar到lib文件夹下 (‘^’是windows shell下的分行符, linux shell下请将 ‘^’ 换成 ‘\’)

mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get ^
  -DremoteRepositories=central::default::http://repo1.maven.apache.org/maven2 ^
  -Dartifact=com.facebook.swift:swift2thrift-generator-cli:0.14.2:jar:standalone ^
  -Ddest=lib/swift2thrift-generator-cli-0.14.2-standalone.jar

这里-Dartifact参数中的 0.14.2是指定swift的版本号,如果换成RELEASE,则下载当前最高版本。 但是swift 0.14.2以后的版本都是java1.8编译的。而我用的java是1.7,所以这里必须指定版本号。 -Ddest指定保存jar包的路径,如果不指定,则下载到maven本地仓库中。 -DremoteRepositories 指定远程仓库,可省略此参数

[INFO] Scanning for projects… [INFO] [INFO] ———————————————————————— [INFO] Building facelog-main 1.0-SNAPSHOT [INFO] ———————————————————————— [INFO] [INFO] — maven-dependency-plugin:2.8:get (default-cli) @ facelog-main — [INFO] Resolving com.facebook.swift:swift2thrift-generator-cli:jar:standalone:0. 14.2 with transitive dependencies Downloading: http://maven.aliyun.com/nexus/content/groups/public/com/facebook/sw ift/swift2thrift-generator-cli/0.14.2/swift2thrift-generator-cli-0.14.2.pom Downloaded: http://maven.aliyun.com/nexus/content/groups/public/com/facebook/swi ft/swift2thrift-generator-cli/0.14.2/swift2thrift-generator-cli-0.14.2.pom (2.8 kB at 5.3 kB/s) Downloading: http://maven.aliyun.com/nexus/content/groups/public/com/facebook/sw ift/swift2thrift-generator-cli/0.14.2/swift2thrift-generator-cli-0.14.2-standalo ne.jar Downloaded: http://maven.aliyun.com/nexus/content/groups/public/com/facebook/swi ft/swift2thrift-generator-cli/0.14.2/swift2thrift-generator-cli-0.14.2-standalon e.jar (11 MB at 616 kB/s) [WARNING] destination/dest parameter is deprecated: it will disappear in future version. [INFO] Copying J:\maven_repository\com\facebook\swift\swift2thrift-generator-cli \0.14.2\swift2thrift-generator-cli-0.14.2-standalone.jar to J:\facelog\facelog-m ain\lib\swift2thrift-generator-cli-0.14.2-standalone.jar [WARNING] Notice transitive dependencies won’t be copied. [INFO] ———————————————————————— [INFO] BUILD SUCCESS [INFO] ———————————————————————— [INFO] Total time: 20.526 s [INFO] Finished at: 2017-10-11T15:58:03+08:00 [INFO] Final Memory: 15M/436M [INFO] ————————————————————————

生成 IDL文件

命令行执行如下命令生成IDL文件 TestService.thrift

java -cp lib\swift2thrift-generator-cli-0.14.2-standalone.jar;target\test-classes ^
    com.facebook.swift.generator.swift2thrift.Main ^
    -package net.gdface.facelog ^
    TestService  ^
    -namespace py gdface.thrift -namespace java com.gdface -namespace cpp gdface ^
    -out TestService.thrift ^
    -recursive

生成的TestService.thrift,文件中不仅有TestService的定义还有涉及的类型TestBean的定义:

namespace java.swift net.gdface.facelog
namespace py gdface.thrift
namespace java com.gdface
namespace cpp gdface
struct TestBean {
  1:  i32 id;
}

service TestService {
  TestBean getBean();
  void setBean(1:  TestBean arg0);
}

关于Swift2Thrift Code Generator的大部分的命令行参数说明参见Swift2Thrift Code Generator 但是 -recursive 这个参数,官方网站并没有说明,只有执行java -jar lib\swift2thrift-generator-cli-0.14.2-standalone.jar时才会显示:

J:\facelog\facelog-main>java -jar lib\swift2thrift-generator-cli-0.14.2-standalo
ne.jar
Usage: Swift2ThriftGenerator [options] <Swift-class-name...>
  Options:
    -allow_multiple_packages
       Allow input classes to reside in different packages. The value of this
       flag defines the generated java.swift namespace. Note that Swift classes
       generated from the resultant Thrift file will all reside in one Java pack
age
    -package, -default_package
       Default package for unqualified classes
       Default: <empty string>
    -map
       Map of external type or service to include file
    -namespace
       Namespace for a particular language to include
    -out
       Thrift IDL output file, defaults to stdout
    -recursive
       Generate all types transitively reachable from the specified types and
       services       
       Default: false
    -v, -verbose
       Show verbose messages
       Default: false

-recursive是指定递归生成所有service接口中涉及的数据类型的IDL定义。这个参数很重要。 比如本例中TestService.java中还涉及到TestBean.java类,如果没有这个参数,还需要单独为TestBean.java再执行一次Swift2ThriftGenerator生成 IDL,并且要在生成TestService.java的IDL时还要用-map告诉程序TestBean的IDL文件的位置,如果service接口中有多个自定的类型的时候,代码维护就非常麻烦。 有了这个参数,只要对service接口类型执行一次Swift2ThriftGenerator就可以生成完整的IDL定义文件。

下载Swift Code Generator Tool

有了前面生成的IDL文件( TestService.thrift)。就可以用swift提供的另一个工具:Swift Code Generator Tool来生成Client代码了.

Swift Code Generator Tool的下载方式与Swift2Thrift Code Generator差不多:

url下载

maven仓库 0.14.2 standalone版本下载地址 : http://central.maven.org/maven2/com/facebook/swift/swift-generator-cli/0.14.2/swift-generator-cli-0.14.2-standalone.jar

maven命令下载

执行maven命令下载swift-generator-cli-0.14.2-standalone.jar到lib文件夹下

mvn org.apache.maven.plugins:maven-dependency-plugin:2.8:get ^
  -Dartifact=com.facebook.swift:swift-generator-cli:0.14.2:jar:standalone ^
  -Ddest=lib/swift-generator-cli-0.14.2-standalone.jar

生成Client代码

java -jar lib\swift-generator-cli-0.14.2-standalone.jar ^
    TestService.thrift ^
    -generate_beans ^
    -override_package net.gdface.facelog.client ^
    -out client/java

-override_package 参数用于指定生成代码的包名,可不指定,则默认使用thrift文件中定义的package -out 指定代码生成文件夹 -generate_beans 指定将数据对象生成标准Java Bean

生成的service端接口代码 TestService.java

package net.gdface.facelog.client;

import com.facebook.swift.codec.*;
import com.facebook.swift.codec.ThriftField.Requiredness;
import com.facebook.swift.service.*;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.*;
import java.util.*;

@ThriftService("TestService")
public interface TestService
{
    @ThriftService("TestService")
    public interface Async
    {
        @ThriftMethod(value = "getBean")
        ListenableFuture<TestBean> getBean();

        @ThriftMethod(value = "setBean")
        ListenableFuture<Void> setBean(
            @ThriftField(value=1, name="arg0", requiredness=Requiredness.NONE) final TestBean arg0
        );
    }
    @ThriftMethod(value = "getBean")
    TestBean getBean();


    @ThriftMethod(value = "setBean")
    void setBean(
        @ThriftField(value=1, name="arg0", requiredness=Requiredness.NONE) final TestBean arg0
    );

}

生成的TestBean.java代码

package net.gdface.facelog.client;

import com.facebook.swift.codec.*;
import com.facebook.swift.codec.ThriftField.Requiredness;
import java.util.*;

import static com.google.common.base.Objects.toStringHelper;

@ThriftStruct("TestBean")
public final class TestBean
{
    public TestBean() {
    }

    private int id;

    @ThriftField(value=1, name="id", requiredness=Requiredness.NONE)
    public int getId() { return id; }

    @ThriftField
    public void setId(final int id) { this.id = id; }

    @Override
    public String toString()
    {
        return toStringHelper(this)
            .add("id", id)
            .toString();
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术小黑屋

Android代码规范利器: Checkstyle

程序代码向来都不仅仅是用来运行的,写的一手好代码,易读,可维护应该是每个程序员所追求的。

611
来自专栏Seebug漏洞平台

libSSH 认证绕过漏洞(CVE-2018-10933)分析

最近出了一个libSSH认证绕过漏洞,刚开始时候看的感觉这洞可能挺厉害的,然后很快github上面就有PoC了,msf上很快也添加了exp,但是在使用的过程中发...

642
来自专栏owent

开源项目得一些小维护

其实我那几个特别是工具类得开源项目一致都有维护和更新,但是每次更新得量和要点并不怎么突出所以一致也没写点什么。但是偶尔吗也会碰到一些稍微值得记录的东西,但是又不...

943
来自专栏龙首琴剑庐

Zookeeper ACL权限配置及zkclient示例

zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机...

4535
来自专栏SAP最佳业务实践

SAP最佳业务实践:FI–现金管理(160)-4 F110创建演示数据-清算供应商发票

2.3.4 通过 F110 付款运行清算供应商发票 要执行该活动,使用此文档中的主数据运行应付帐款:自动付款 (158) 业务情景。 字段名称用户操作和值注释...

3385
来自专栏刺客博客

PHP利用phpexcel导入Excel表到Mysql数据库

2743
来自专栏杨建荣的学习笔记

曲折的10g,11g中EM的安装配置过程(r4笔记第98天)

今天在本地搭了一套oracle环境,首先安装数据库的时候顺带了EM,结果安装好之后想修改监听器的端口,把原本15521的端口换成别的,结果在目录中修改了几个参数...

2623
来自专栏黑白安全

超简单实现php谷歌验证

前几天才得知有google身份验证器这种好玩的东西,这是一个类似QQ令牌的离线验证码,不需要联网。只需要时区同步和SecretKey一致即可计算出离线验证码,简...

833
来自专栏鬼谷君

Salt-API安装配置及使用

982
来自专栏青枫的专栏

Notepad2替代系统自带的记事本

事情是这样的,平时我经常把一些文字复制到记事本中编辑好了再复制到目标位置,可以在系统自带的记事本中替换删除一些内容,记事本小巧,占用很少的资源,我很喜欢;但今天...

682

扫码关注云+社区