通过REST发送协议缓冲区

5
我正在尝试使用REST实现客户端/服务器的协议缓冲区。但我还有点困惑,我是否需要以字节格式发送协议缓冲区请求?也就是说,在我的客户端代码中,我需要将对象序列化为字节数组吗?例如:protoRequest.build.toByteArray()。在服务器端,我需要...
   @POST
   @Consumes("application/octet-stream")
   public byte[] processProtoRequest(byte[] protoRequest) {
   ProtoRequest.Builder request = ProtoRequest.newBuilder();
   request.mergeFrom(protoRequest)
}

这样做是正确的吗?

谢谢

David

3个回答

1

我写了一个逐步教程,介绍如何在Web服务中使用Jersey作为客户端JAX-RS实现来生成/消费协议缓冲流。希望对你有所帮助。 :)

服务器端:

@GET
@Path("/{galaxy}")
@Consumes(MediaType.TEXT_HTML)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getInfo(@PathParam("galaxy") String galaxyName){

    if(StringUtils.equalsIgnoreCase("MilkyWay", StringUtils.remove(galaxyName, ' '))){

        // The following method would call the DTO Galaxy builders.
        Galaxy milkyWay = MilkyWayFactory.createGalaxy();

        // This is the important line for you where where the generated toByteArray() method takes responsibility of serializing the instance into a Protobuf format stream
        return Response.ok(milkyWay.toByteArray(),MediaType.APPLICATION_OCTET_STREAM).status(200).build();
    }

    return Response.status(Status.NOT_FOUND).build();
}

客户端:

String serverContext = "learning-protobuf3-ws-service";
String servicePath = "ws/universe/milkyway";
String serviceHost = "localhost";
Integer servicePort = 8080;

javax.ws.rs.client.Client client = javax.ws.rs.client.ClientBuilder.newClient();

javax.ws.rs.client.WebTarget target = client.target("http://"+serviceHost+":"+servicePort+"/"+serverContext)
                                            .path(servicePath);


InputStream galaxyByteString = target.request(MediaType.TEXT_HTML)
        .header("accept",MediaType.APPLICATION_OCTET_STREAM)
        .get(InputStream.class);

Galaxy galaxy = Galaxy.parseFrom(IOUtils.toByteArray(galaxyByteString));

1

您可以使用输入流来实现此目的。服务器端代码将如下所示:

@POST
public Response processProtoRequest(@Context HttpServletRequest req) {
          ProtoRequest protoRequestObj = ProtoRequest.parseFrom(req.getInputStream());
          ///process  protoRequestObj and convert into byte arry and send to clinet
            return  Response.ok(protoRequestObj.toByteArray(),
                        MediaType.APPLICATION_OCTET_STREAM).status(200).build();

}

客户端将会长成这样:

   ProtoRequest protoRequestObj = ProtoRequest.newBuilder(). //protocol buffer object
          setSessionId(id).
          setName("l070020").
          build();

       DefaultHttpClinet httpClinet = new DefaultHttpClinet();
       HttpPost request = new HttpPost("http://localhost:8080/maven.work/service/mainServices/protoRequest");
    request.addHeader("accept","application/octet-stream");
    request.setEntity(protoRequestObj.toByteArray());  
    HttpResponse response = httpClient.execute(request);

1
你的博客链接完全没有回答所提出的问题,而且你没有透露这是你自己的博客文章。我已经删除了这些链接。 - Andrew Barber
我的博客包含通过Web服务发送和接收数据到Google协议缓冲区的基本设置详细信息。我对此问题进行了两天的研究,然后找到了解决方案并将其放入了我的博客中。这个问题与我的博客内容类似,我所需的更改以解决这个问题,我已经实现并可以自行检查。 - Amir Qayyum Khan
1
问题是“这是我的代码;这样做对吗?”你没有说“是”或“否”,而且你的博客文章甚至没有试图回答这个问题。它可能是关于“类似”的主题,但像那样链接到你的博客是不合适的。你在个人资料中有你的博客网址 - 那里人们可以看到它并访问你的博客。Stack Overflow不在这里帮助你宣传你的博客。 - Andrew Barber

0
您可以使用base64对SerializeToString的结果进行编码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接