使用 Jackson 将 protobuf 转换为 JSON?

     2023-02-26     78

关键词:

【中文标题】使用 Jackson 将 protobuf 转换为 JSON?【英文标题】:Convert a protobuf to JSON using Jackson? 【发布时间】:2019-01-06 09:32:56 【问题描述】:

使用 Jackson 的 ObjectMapper 将 protobuf 转换为 JSON 时出现以下错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Direct self-reference leading to cycle (through reference chain:
MyObjectPb$MyObject["unknownFields"]->
com.google.protobuf.UnknownFieldSet["defaultInstanceForType"])

MyObjectPb 有以下字段:

protected com.google.protobuf.UnknownFieldSet unknownFields

在处理现有代码库时,我有以下限制:

    我无法修改 MyObjectPb 的源代码,所以我无法在 MyObjectPb 中使用 Jackson 的忽略注解。 我也不能使用 Gson 的库来转换对象,因为代码库已经使用 Jackson 进行序列化。不建议添加新的依赖项。

如何告诉 Jackson 忽略(反)序列化 MyObjectPb 中的 UnknownFieldSet 对象?


我尝试了以下方法,但这些方法似乎无法解决问题:

a) 配置 ObjectMapper:

myObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

b) 使用 Jackson Mixin:

@JsonIgnoreType
private abstract class UnknownFieldSetIgnoreMixIn 

myObjectMapper.addMixIn(UnknownFieldSet.class, UnknownFieldSetIgnoreMixIn.class)

【问题讨论】:

mixin 是我的第一个猜测。您可能必须声明一个并行类以供 JSON 使用。 MapStruct 可以帮助在那里来回转换。 @chrylis 请问mixin实现是否合适或者我错过了什么?我会查找 MapStruct,非常感谢。 【参考方案1】:

我使用了JsonFormat类(com.googlecode.protobuf.format.JsonFormat)来转换protobuf:

new JsonFormat().printToString(myObject)

这对我来说非常完美。

【讨论】:

【参考方案2】:

包含已从 com.googlecode.protobuf.format.JsonFormat 更改 到 com.google.protobuf.util.JsonFormat

因此,如果您的 protobuf 依赖项缺少 format 包,请尝试在 util 中查找 JsonFormat

有了这个包含,你应该可以使用

new JsonFormat().printToString(myObject)

正如@amad-person 建议的那样。

【讨论】:

【参考方案3】:

当前(2018 年 10 月)序列化 protobuf 的方法是按以下方式使用 com.google.protobuf.util.JsonFormat

JsonFormat.printer().print(myMessageOrBuilder)

我在我的 protobuf 对象之前使用了 @JsonSerialize(using = MyMessageSerializer.class) 注释并添加了这个类:

public static class MyMessageSerializer extends JsonSerializer<Message> 
    @Override
    public void serialize(Message message, JsonGenerator gen, SerializerProvider serializers) throws IOException 
        gen.writeRawValue(JsonFormat.printer().print(message));
    

这允许 new ObjectMapper().writeValueAsString(wrapperObject) 正确地将我的 protobuf 转换为 JSON。

【讨论】:

gen.writeRawValue 如果 protobuf 对象只是 POJO 类中的一个成员 在 sprinboot webflux 中,这个序列化选项/注释有效。唯一的问题是,每次 proto 对象重新生成后,我们都必须编辑生成的 java 代码。 我试过了,但出现以下异常:No serializer found for class com.google.protobuf.UnknownFieldSet$Parser and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: ru.vtb.mmba.account.AccountProto$BankAccountInfo["unknownFields"] 注解@JsonSerialize(using = ProtobufSerializer.class)好像没用。如果只是将JsonFormat.printer().print(accountInfo) 传递给objectMapper.writeValueAsString,那么它就可以工作。那么为什么@JsonSerialize(using 会被objectMapper.writeValueAsString 忽略呢?【参考方案4】:

您应该使用 com.google.protobuf.util.JsonFormat 包中的以下类:

JsonFormat.printer().print()

【讨论】:

【参考方案5】:

我只是有这个问题,并使用下面的代码从 Message 对象创建 JSON:

JsonFormat.printer().print(getMessageCockroachDB)

【讨论】:

【参考方案6】:

这里有一个杰克逊的 protobuf 库:https://github.com/FasterXML/jackson-dataformats-binary

虽然关于如何使用它的文档很少!有一些关于如何使用它进行读/写的示例:https://github.com/FasterXML/jackson-dataformats-binary/blob/2.14/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/ReadSimpleTest.java#L66

但尚不清楚这将如何放在 GRPC 应用程序中。

【讨论】:

使用jackson将json对象列表转换为hashmap

】使用jackson将json对象列表转换为hashmap【英文标题】:ConvertaListofjsonobjecttohashmapusingjackson【发布时间】:2016-06-1718:00:41【问题描述】:有没有办法使用内置的Jackson功能使用java将json对象列表转换为HashMap说明:我需要解析的Json结... 查看详情

使用 Jackson 将 Java 对象转换为 JSON

】使用Jackson将Java对象转换为JSON【英文标题】:ConvertingJavaobjectstoJSONwithJackson【发布时间】:2013-03-2501:07:46【问题描述】:我希望我的JSON看起来像这样:"information":["timestamp":"xxxx","feature":"xxxx","ean":1234,"data":"xxxx","timestamp":"yyy","feat... 查看详情

如何仅使用 Jackson 将 XML 转换为 JSON?

】如何仅使用Jackson将XML转换为JSON?【英文标题】:HowtoconvertXMLtoJSONusingonlyJackson?【发布时间】:2017-01-2210:06:30【问题描述】:我收到来自服务器的XML响应。但我需要以JSON格式显示。有没有任何方法可以在没有任何第三方API的情... 查看详情

使用jackson将pojo(对象列表)转换为java中的json

我在将简单的JSON转换为POJO对象时遇到了问题。这是我的代码:publicclassProducts{privateintid;privateStringtype;privateStringdescription;privateDoubleprice;privateStringbrand;publicintgetId(){returnid;}publicvoidsetId(intid){thi 查看详情

jackson将java对象转换为json字符串

JackSon可以将java对象转换为JSON字符串,步骤如下:1.导入JackSon的jar包2.创建ObjectMapper对象3.使用ObjectMapper对象的writeValueAsString()方法将java对象转换为JSON对象这里有个例子:publicclassFruit{privateStringname;privateStringid;publicCustomet(Stri 查看详情

使用 Jackson Object Mapper 将 Map 转换为 Java 对象非常慢

】使用JacksonObjectMapper将Map转换为Java对象非常慢【英文标题】:ConvertingMaptoJavaobjectusingJacksonObjectMapperisveryslow【发布时间】:2017-07-2208:50:00【问题描述】:我目前正在尝试使用Jackson数据绑定库从Map创建52个Java对象,目前转换所有5... 查看详情

java-使用jackson将json转换为复杂对象

这可能是重复的问题,但我已经搜索了很多解决方案,但没有运气。我有一个类如下:publicclassRestartMapState{publicRestartMapState(List<MapStepData>vMapStepData,List<AbstractMap.SimpleEntry<String,String>>vResolvedParameters,S 查看详情

使用 Jackson 将 JSON 字符串转换为漂亮的打印 JSON 输出

】使用Jackson将JSON字符串转换为漂亮的打印JSON输出【英文标题】:ConvertJSONStringtoPrettyPrintJSONoutputusingJackson【发布时间】:2013-01-0901:46:17【问题描述】:这是我拥有的JSON字符串:"attributes":["nm":"ACCOUNT","lv":["v":"Id":null,"State":null,"vt":... 查看详情

使用jackson–将字符串转换为jsonnode对象(代码片段)

概述本快速指南的主要目的是如何使用Jackson2来将一个字符串转换为JsonNode对象。JsonNode定义在com.fasterxml.jackson.databind.JsonNode包中。快速转换可以使用下面的代码直接进行转换。转换的方式也比较简单,在定义好ObjectMapper对象... 查看详情

将 json 日期转换为 Jackson 的众多日期之一

】将json日期转换为Jackson的众多日期之一【英文标题】:convertingjsondatetooneofmanyforJackson【发布时间】:2017-05-2020:44:52【问题描述】:我有一个使用jackson的springboot1.3.5应用程序:“com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.5.0”我... 查看详情

将json转换为javaobject,如何使用jackson解析badgerfish约定

使用API​​我收到这样的JSON(现在保存到文件中):[{"LEI":{"$":"549300Q82NZ9NYNMZT63"},"Entity":{"LegalName":{"$":"UnitedNerdsinCollaborationofRandomNerdinessAB"},"LegalAddress":{"Line1":{"$":"BOX155"},"City":{"$":"Alingsa 查看详情

使用 Jackson ObjectMapper 将 Json 的一部分转换为 HashMap

】使用JacksonObjectMapper将Json的一部分转换为HashMap【英文标题】:ConvertapartofJsontoHashMapusingJacksonObjectMapper【发布时间】:2015-07-1801:09:32【问题描述】:我正在尝试以一种方式解组json文件,以便将Json的少数属性映射到我的模型类中... 查看详情

java示例代码_使用Jackson json将K/V的json数组转换为Java HashMap

java示例代码_使用Jackson json将K/V的json数组转换为Java HashMap 查看详情

如何将 protobuf 对象转换为 ByteArray 并在 Swift 中使用 Base64 URL_SAFE 进行编码?

】如何将protobuf对象转换为ByteArray并在Swift中使用Base64URL_SAFE进行编码?【英文标题】:TohowconvertprotobufobjecttoByteArrayandtheencodewithBase64URL_SAFEinSwift?【发布时间】:2019-07-1705:05:23【问题描述】:在Android中,我可以将对象转换为ByteArra... 查看详情

Jackson 无法将空字符串值转换为枚举

】Jackson无法将空字符串值转换为枚举【英文标题】:Jacksoncannotconvertemptystringvaluetoenum【发布时间】:2018-12-2615:46:09【问题描述】:我正在寻找一个使用Jackson(2.8)的便捷解决方案,以在反序列化之前/期间过滤掉指向空字符串值的... 查看详情

Golang:如何将 time.Time 转换为 Protobuf 时间戳?

】Golang:如何将time.Time转换为Protobuf时间戳?【英文标题】:Golang:HowtoConverttime.TimetoaProtobufTimestamp?【发布时间】:2021-12-1711:33:43【问题描述】:我在Golang10-3000:49:07.1236中有一个time.Time变量,需要转换为GoProtobuftimestamp.Timestamp。关... 查看详情

在 Java 中将 protobuf 转换为 bigquery

】在Java中将protobuf转换为bigquery【英文标题】:ConvertingprotobuftobigqueryinJava【发布时间】:2020-11-1900:33:37【问题描述】:我们将protobuf与GCP的pubsub和数据流一起使用。我们使用单个proto文件定义发送到pubsub的数据和bigquery模式。publis... 查看详情

如何使用 Jackson JSON 将 JSON 字符串转换为 Map<String, String>

】如何使用JacksonJSON将JSON字符串转换为Map<String,String>【英文标题】:HowtoconvertaJSONstringtoaMap<String,String>withJacksonJSON【发布时间】:2011-02-0106:35:22【问题描述】:我正在尝试做这样的事情,但它不起作用:Map<String,String&g... 查看详情