当前位置: 首页 > 知识库问答 >
问题:

Dropwizard和协议缓冲区示例

寿亦
2023-03-14

请注意:虽然这个问题特别提到了Dropwizard,但我相信任何有泽西/JAX-RS经验的人都应该能够回答这个问题,因为我可以想象Dropwizard只是在幕后遵循泽西/JAX-RS约定。

我有一个Dropwizard服务,它用JSON编写,工作非常出色。

现在我想将其切换为读/写二进制数据(以最小化网络带宽)。我看到了Dropwizard Protobuf库,但我对在Dropwizard中实现二进制序列化有一些担忧。

首先,以下是我当前的(以JSON为中心的)代码中的重要内容:

// Groovy pseudo-code

// Domain entity/POJO
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
class Fizz {
    @JsonProperty
    String name

    @JsonProperty
    boolean isBuzz    
}

// The Dropwizard app entry point
class FizzService extends Application<FizzConfiguration> {
    @Override
    void run(FizzConfiguration fizzCfg, Environment env) throws Exception {
        // ... lots of stuff

        env.jersey().register(new FizzService())
    }
}

// JAX-RS resource with a sample GET endpoint
@Path(value = "/fizz")
@Produces(MediaType.APPLICATION_JSON)
class FizzResource {
    @GET
    @Path("/{id}")
    Fizz getFizzById(@PathParam("id") int id) {
        // Look up a 'Fizz' in a DB and return it.
        lookupFizzinDB(id)
    }
}

如您所见,GET/fizzendpoint需要一个JSON请求实体,该实体包含一个类型为int的名为id的元素。它返回一个与提供的id匹配的响应实体。

我想通过Google协议缓冲区将其从JSON切换到二进制。

根据Dropwizard-Schembuf文档,这就像将其添加到我的FizzService#run(...)方法一样简单:

environment.jersey().register(new ProtocolBufferMessageBodyProvider())

问题是目前我的整个应用程序都连接到序列化/反序列化到/从JSON。我的Fizz类上的@JsonProperty注释对Dropwizard有意义。@Produces(MediaType.APPLICATION_JSON)FizzResources上的注释也起着关键作用。我担心让我的Dropwizard应用程序读取/写入原型生成的二进制文件并不像文档中发布的1-line那么容易。

我没有嫁给这个库。如果有人有在Dropwizard应用程序中设置RESTendpoint以接受/接收原型生成的二进制文件的经验,我所关心的只是一个有效的解决方案。想法?

共有1个答案

徐博雅
2023-03-14

你说得对,这可不像一行那么简单。您需要让protobuf生成代码才能工作。查看协议缓冲区文档。首先需要有一个proto文件,用protobuf编译器编译,它会为您生成代码。生成的代码是用于构建域/模型对象的代码。Dropwizard的protobuf提供程序使用此编译代码。无论您是否使用Dropwizard提供程序,您仍然需要使用生成的代码。请参阅上述链接中的“如何开始”部分。

生成代码后,在资源方法中,生成的类/类型是您需要返回的,以便提供程序能够序列化它。您还需要在资源方法或资源类上有@products(“application/x-protobuf”)@products(ProtocolBufferMediaType.application\u protobuf),以便Jersey知道如何找到媒体类型的提供程序。

您可以同时支持应用程序/json和应用程序/x-protobuf,因为您可以在生产的介质中使用多种介质类型。只需使用语法products({….,…})

但这还不是全部。由于您需要返回两种不同的类型,即JSON的简单POJO,或原型buf的生成类型,因此您需要检查资源方法中的标头

@Produces({"application/json", "application/x-protobuf"})
public Response getFoo(@Context HttpHeaders headers) {
    List<MediaType> accepts = headers.getAcceptableMediaTypes();
    if (accepts.contains(MediaType.APPLICATION_JSON_TYPE) {
        return Response.ok(new Foo());
    } else if (accepts.contains(ProtocolBufferMediaType.APPLICATION_PROTOBUF_TYPE) {
        return Reponse.ok(new ProtoBufFoo());
    } else {
        // default
        return Response.ok(new Foo());
    }
}

或者您可以有两种不同的方法,每种类型一种

@Produces("application/json")
public Response getFooJson() {
    return Response.ok(new Foo());
}

@Produces("application/x-protobuf")
public Response getFooProto() {
    return Response.ok(new ProtoBufFoo());
}

无论客户机作为其接受头发送什么,都是将要发送的类型。例如,接受:应用程序/json或接受:应用程序/x-protobuf

另请参见:

  • 将Google proto缓冲区与Jersey/JAX-RS相结合
 类似资料:
  • 问题内容: 我正在使用gSoap将旧式C 系统重构为SOA。我们遇到了一些性能问题(非常大的XML),因此我的领导要我看一下协议缓冲区。我做到了,它看起来非常酷(我们需要C 和Java支持)。但是协议缓冲区是仅用于序列化的解决方案,现在我需要将其发送到Java前端。从C ++和Java角度来看,我应该使用什么来通过HTTP(只是内部网络)发送那些序列化的内容? PS。另一个人试图加速我们的gSoa

  • 我在客户机-服务器体系结构中使用协议缓冲区作为有线数据格式。域对象(JavaBeans)将经历以下生命周期。 用于客户端业务逻辑 转换为协议格式 传送到服务器 转换回域对象 用于服务器端业务逻辑 “协议缓冲器和O-O设计”部分在协议留档中建议在适当的域模型内包装生成的类。 我想找出最好的办法。 例如,我有一个简单的原型定义。 这就是域模型的定义方式。如您所见,数据完全存储在proto builde

  • 两者都是序列化库,由谷歌开发人员开发。他们之间有什么大的区别吗?将使用协议缓冲区的代码转换为使用FlatBuffers需要大量工作吗?

  • 我们接近100人。proto文件,其中每个文件可以定义大约10个IDL结构(如服务或消息)。 有没有一种方法可以可视化它们,包括引用(从一个文件到另一个文件)。例如类似于UML类图。 可能有可配置的可视化Java /C。 引用自https://developers.google.com/protocol-buffers/docs/overview 协议缓冲区现在是谷歌的通用数据语言——在撰写本文时

  • 试图使用Ionic 4中的协议缓冲区进行编码 我已经下载了协议并用它来生成一堆_pb.js文件,每个. proto文件一个。很好。 首先关注原型示例。这是示例代码: 我做了一些更改以匹配我的文件。更改proto文件的名称。但是我的proto文件中没有包名称。所以我只是使用了消息名称。首先这是我的. proto文件的开头: 下面是我修改后的代码: 这似乎不起作用。我的控制台显示: 我相信我已经成功地

  • 问题内容: 我grep其他主题,但他们没有帮助我=(。在我的工作服务器上,我没有sudo特权,因此我使用 ./configure –prefix = / home /用户名/本地 然后,我用“ person”示例创建源文件,并使用protoc成功地对其进行编译。 我没有pkg-info =(。我尝试用 g ++ -I / home /用户名/本地/ include -L / home /用户名/本