sme*_*eeb 3 jax-rs jersey protocol-buffers binary-serialization dropwizard
请注意:尽管这个问题特别提到了Dropwizard,但我相信任何具有Jersey / JAX-RS经验的人都应该能够回答这个问题,因为我认为Dropwizard只是遵循了Jersey / 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)
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,GET /fizz端点期望JSON请求实体包含一个名为idtype 的元素int。它返回Fizz与提供的相匹配的响应实体id。
我想通过Google Protocol Buffers将其从JSON切换为二进制。
根据Dropwizard-Protobuf文档,这就像将其添加到我的FizzService#run(...)方法中一样简单:
environment.jersey().register(new ProtocolBufferMessageBodyProvider())
Run Code Online (Sandbox Code Playgroud)
问题是,当前我的整个应用程序都已连接到JSON /从JSON反序列化。@JsonProperty我Fizz班上的注释对Dropwizard有意义。上的@Produces(MediaType.APPLICATION_JSON)注释FizzResource也起着关键作用。我担心让我的Dropwizard应用程序读/写protobuf生成的二进制文件并不像文档中发布的1-liner那样容易。
我没有嫁给这个图书馆。如果任何人有任何在Dropwizard应用程序中设置REST端点以接受/接收由protobuf生成的二进制文件的经验,我所关心的就是一个有效,有效的解决方案。有想法吗?
没错,这并不像一支班轮那么容易。您需要使protobuf生成代码才能正常工作。查看协议缓冲区文档。首先,您需要具有一个protobuf编译器编译的proto文件,该文件会为您生成代码。此生成的代码是用于构建域/模型对象的代码。Dropwizard的protobuf提供程序可以处理此编译代码。无论您是否使用Dropwizard提供程序,您都仍然需要使用生成的代码。请参阅以上链接中的“如何开始”部分。
获得生成的代码之后,然后在您的资源方法中,将需要返回生成的类/类型,以使提供程序能够对其进行序列化。您还需要在资源方法或资源类上使用@Produces("application/x-protobuf")或@Produces(ProtocolBufferMediaType.APPLICATION_PROTOBUF)在其上,因此Jersey知道如何找到媒体类型的提供程序。
您可以同时支持application/json和application/x-protobuf,因为您可以在中添加多种媒体类型@Produces。只需使用语法@Produces({ .. , .. })。
那还不是全部。由于您将需要返回两种不同的类型,即用于JSON的简单POJO或用于Protobuf的生成的类型,因此您将需要在resource方法中检查标头
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
或者您可以有两种不同的方法,每种类型一种
@Produces("application/json")
public Response getFooJson() {
return Response.ok(new Foo());
}
@Produces("application/x-protobuf")
public Response getFooProto() {
return Response.ok(new ProtoBufFoo());
}
Run Code Online (Sandbox Code Playgroud)
客户端发送的任何内容作为其Accept标头,即要发送的类型。例如Accept: application/json或Accept: application/x-protobuf
也可以看看:
| 归档时间: |
|
| 查看次数: |
1714 次 |
| 最近记录: |