【问题标题】:MediaType for ProtoBufProtoBuf 的媒体类型
【发布时间】:2020-06-30 14:33:06
【问题描述】:

我需要从我创建的客户端将 protobuf 数据发送到我的端点。下面是客户端和 JAXRS 端点的代码。

--client
Client genClient = ClientBuilder.newClient();
WebTarget target2 = genClient.target("http://localhost:8080/ClientJAXRS/rest/Hello").path("/proto");
 String inputproto = String.format("\n" +  "syntax = \"proto3\";\n" + 
                "message Struct1 {\n" + 
                " string   s1Att1 = 1;\n" + 
                " int32    s1Att2 = 2;\n" + 
                " int32    s1Att3 = 3;\n" + 
                " Struct2  s1Att4 = 4;\n" + 
                " message Struct2 {\n" + 
                " repeated string s2Att1 = 1;\n" + 
                "  }\n" + 
                 + " ");
Response res =  target2.request("application/x-protobuf").put(Entity.text(inputproto));

--endpoint
@PUT
@Path("/proto")
@Consumes("application/x-protobuf")
//@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getInfo(String text){



  return    Response.ok(text.getBytes(),MediaType.APPLICATION_OCTET_STREAM).status(200).build();
}

我得到的输出是 Unsupported MediaType。

context=ClientResponse{method=PUT, uri=http://localhost:8080/ClientJAXRS/rest/Hello/proto, status=415, reason=Unsupported Media Type}}

帮助我了解 proto 的 MIME TYPE 或发送的 proto 格式。

编辑 2:

我在data.proto中为protobuf单独做了一个文件

syntax = "proto3";
 option java_outer_classname = "DataProtos";
 option java_package = "com.client.JAXClient";
 message Album {
     optional string title = 1;
     repeated string artist = 2;
     repeated int32 release_year = 3;
     required string song_title = 4;
 }

使用 protoc -I 代码在 java 中为其生成代码并生成 Album 类。

为它实现了 MessagebodyWriter 和 MessageBodyReader,如下所示

@Provider
@Produces("application/x-protobuf")
@Consumes("application/x-protobuf")
public class ProtoMessageBodyWriter implements MessageBodyWriter<Album>,MessageBodyReader<Album> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // TODO Auto-generated method stub
        return type == Album.class ;
    }

    @Override
    public void writeTo(Album t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders, OutputStream out)
            throws IOException, WebApplicationException {
            Writer writer = new PrintWriter(out);
            t.writeTo(out);

    }

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // TODO Auto-generated method stub
        return type == Album.class ;
    }

    @Override
    public Album readFrom(Class<Album> type, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, String> httpHeaders, InputStream in)
            throws IOException, WebApplicationException {
            return Album.parseFrom(in);
    }

}

为 protobuf 添加了 2 个端点,如下所示

@GET
@Path("/proto-data")
@Consumes("application/x-protobuf")
 public Response getInfo(Album inpAlbum){
                   StringBuilder sbuilder = new  StringBuilder("Input album");
                   sbuilder.append("ID: ").append(inpAlbum.getReleaseYear()).append("\n");
                   sbuilder.append("Name: ").append(inpAlbum.getArtist()).append("\n");
                    return Response.created(null).entity(sbuilder.toString()).build();

}

我正在尝试使用

从客户端访问这些端点
Response response =null;
Client client =null;
client = ClientBuilder.newClient();
WebTarget target2 = client.target("http://localhost:8081/ClientJAXRS/rest/Hello").path("/proto-data");
response= target2.request().get();
System.out.println(response);

但反应是

ClientJAXRS/rest/Hello/proto-data, status=500, reason=Internal Server Error}}
text/html;charset=utf-

【问题讨论】:

  • 您需要创建一个提供程序来处理该数据类型。看看this post
  • 您基本上只是生成一些文本并将其发送给您的客户。这不是 protobuf 数据。你需要做一个转变。在尝试建立客户端-服务器通信之前,您需要处理 protobuf 基础知识。我没有太多帮助,因为我不知道 protobuf,但这看起来很简单:developers.google.com/protocol-buffers“MediaType”不是你的问题。
  • 1) 您需要了解@Produces@Consumes 之间的区别。 2) 这些注释的值需要匹配提供者的方法。您使用 a/x-protobuf 而提供者使用 a/protobuf 的方法。
  • 此外,当您发出客户端 GET 请求时,请始终设置 Accept 标头,并且在您发出 POST/PUT 请求时始终为您发送的数据类型设置 Content-Type 标头。

标签: java jax-rs protocol-buffers prototype mime-types


【解决方案1】:

你可以使用 application/x-protobuf

OkHttp 请求正文示例:

final RequestBody requestBody = RequestBody.create(MediaType.parse("application/x-protobuf"), builder.build().toByteArray());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2014-10-15
    相关资源
    最近更新 更多