Dropwizard和协议缓冲区的示例 [英] Dropwizard and Protocol Buffers by example

查看:170
本文介绍了Dropwizard和协议缓冲区的示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意:尽管此问题专门提到了Dropwizard,但我相信任何具有Jersey/JAX-RS经验的人都应该能够回答此问题,就像我想象的那样,Dropwizard只是遵循引擎盖/JAX-RS的惯例.

Please note: Although this question specifically mentions Dropwizard, I believe anyone with Jersey/JAX-RS experience should be able to answer this question, as I would imagine Dropwizard is just following Jersey/JAX-RS conventions under the hood.

我有一个 Dropwizard 服务,该服务使用JSON进行改写/编写,效果很好.

I have a Dropwizard service that reds/writes in JSON and works beautifully.

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

I would like to now switch it to read/write binary data (to minimize network bandidth). I see there is the Dropwizard-Protobuf lib but I have a few concerns about implementing binary serialization in Dropwizard.

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

First off, here's the important stuff from my current (JSON-centric) code:

// 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 /fizz端点期望一个JSON请求实体,该实体包含类型为int的名为id的元素.它返回与提供的id相匹配的Fizz响应实体.

So as you can see, the GET /fizz endpoint expect a JSON request entity that contains an element called id of type int. It returns a Fizz response entity that matches the provided id.

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

I want to switch this from JSON to binary via Google Protocol Buffers.

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

According to the Dropwizard-Protobuf docs, this is as simple as just adding this to my FizzService#run(...) method:

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

问题是,目前我的整个应用程序都已连接到JSON序列化/反序列化.我的Fizz类上的@JsonProperty注释对Dropwizard有意义. FizzResource上的@Produces(MediaType.APPLICATION_JSON)批注也起着至关重要的作用.我担心让我的Dropwizard应用程序读/写protobuf生成的二进制文件并不像文档中发布的1-liner那样容易.

The problem is that currently my whole app is wired to serialize/deserialize to/from JSON. The @JsonProperty annotations on my Fizz class have meaning to Dropwizard. The @Produces(MediaType.APPLICATION_JSON) annotation on the FizzResource also plays a critical role. I'm worried that making my Dropwizard app read/write protobuf-generated binary is not as easy as the 1-liner posted in the docs.

我还没有嫁给这个图书馆.如果任何人有任何在Dropwizard应用程序中设置REST端点以接受/接收由protobuf生成的二进制文件的经验,我所关心的就是一个有效,有效的解决方案.想法?

I'm not married to this library. If anyone has any experience setting up REST endpoints in a Dropwizard app to accept/receive protobuf-generated binary, all I care about is a working, efficient solution. Ideas?

推荐答案

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

You're right, it's not as easy as the one liner. You need to have protobuf generate code for it to work. Check out the Protocol Buffers Documentation. You first need to have a proto file that you compile with the protobuf compiler, which generates the code for you. This generated code is what you use to build your domain/model objects. The protobuf provider from Dropwizard works off this compiled code. Whether or not you use the Dropwizard provider, you well still need to use the generated code. See the section "How do I start" in the above link.

在拥有生成的代码之后,然后在您的资源方法中,生成的类/类型就是您需要返回的内容,以便提供程序能够对其进行序列化.您还需要具有@Produces("application/x-protobuf")

After you have the generated code, then in your resource method, the generated class/type is what you will need to return for the provider to be able to serialize it. You will also need to have @Produces("application/x-protobuf") or @Produces(ProtocolBufferMediaType.APPLICATION_PROTOBUF) on your resource method or resource class, so Jersey knows how to find the provider for the media type.

您可以同时支持application/jsonapplication/x-protobuf,因为在@Produces中可以有一种以上的媒体类型.只需使用语法@Produces({ .. , .. }).

You can support both application/json and application/x-protobuf, as you can have more that one media type in the @Produces. Just use the syntax @Produces({ .. , .. }).

那还不是全部.由于您将需要返回两种不同的类型,即用于JSON的简单POJO或用于Protobuf的生成的类型,因此您将需要在资源方法中检查标头

That's not all though. Since you will need to return two different types, i.e your simple POJO for JSON, or the generated type for Protobuf, you will either need to check for the header in the resource method

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

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

Or you can have two different method, one for each type

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

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

无论客户端作为其Accept标头发送的内容,即要发送的类型.例如Accept: application/jsonAccept: application/x-protobuf

Whatever the client sends as its Accept header, that is the type that will be sent out. For example Accept: application/json or Accept: application/x-protobuf

另请参见:

这篇关于Dropwizard和协议缓冲区的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆