天道酬勤,学无止境

Map List<String> with Mapstruct from Java POJO to Protobuf (proto3)

I'm trying to map some POJOs from Java to Protobuf (proto3). Some of them contain Lists. While mapping lists with POJOs (for example List) is no problem, I'm getting a UnsupportedOperationException.

Example with List<Product> (this works corrctly):

ProductProtobuf.Builder map(Product product);

@Mapping(target = "productsList", source = "products")
ResponseProtobuf.Builder map(Response response);

Example with List<String> (this doesn't work):

@Mapping(target = "usersList", source = "users")
ResponseProtobuf.Builder map(Response response);

Additionally, I have some Mapper for builder:

public ResponseProtobuf.Builder responseBuilder() {
    return ResponseProtobuf.newBuilder();
}

public ProductProtobuf build(ProductProtobuf.Builder builder) {
    return builder.build();
}

评论

The problem is that MapStruct will use getProductsList().addAll(). In order to avoid this you should use CollectionMappingStrategy.ADDER_PREFERRED collectionMappingStrategy. Have a look at the UserMapper from the mapstruct-protobuf3 in the mapstruct examples repo.

In a nutshell you need to add:

@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
    nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)

to your mapper.

One information regarding your builder, in case you are using 1.3.0.Beta1 you won't need it as there is out of the box support for that in MapStruct now.

NB: There was a bug in MapStruct that was not working correctly with ProtocolStringList. This bug has been fixed in 1.3.0.Beta1. If you try with this version it should work (in case your productList is a String)

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • SpringBoot + GoogleProtobuf
    SpringBoot + GoogleProtobuf 项目地址: protobuf-simple :https://github.com/Cyanss/protobuf-simple 一、环境配置   protobuf-java版本的选择需要对应到C++等其他端的版本以及Maven中protobuf-java版本。这里选择3.4.0版本进行演示及测试。 电脑系统: Windows 10 x64 bit protobuf GitHub: https://github.com/protocolbuffers/protobuf protobuf 源码下载: protobuf-java-3.4.0.zip https://github.com/protocolbuffers/protobuf/releases/download/v3.4.0/protobuf-java-3.4.0.zip protoc 编译器下载: protoc-3.4.0-win32.zip https://github.com/protocolbuffers/protobuf/releases/download/v3.4.0/protoc-3.4.0-win32.zip 注:protoc编译器3.4.0版本只有32位安装包。 protobuf-java 依赖: <dependency> <groupId>com
  • 必须为现有的 proto 包括 Map 创建 java pojo(have to create java pojo for the existing proto includes Map)
    问题 我曾尝试将 proto 转换为 java pojo 。 但得到了错误 [Stderr] Order.proto:12:18:应为“必需”、“可选”或“重复”。 [Stderr] Order.proto:12:21:预期的字段名称。 optional int32 orderID = 1; optional int32 quantity = 2; map<string,string> map_field = 4; repeated string product = 3; 请帮助我需要更改的内容。 我在谷歌 protobuf 开发者网站 https://developers.google.com/protocol-buffers/docs/proto#maps 上搜索它说地图字段不能重复、可选或必需 请帮我解决这个问题。 回答1 Maps 是 protobuf 3.0(又名“proto3”)中的一个新特性,它仍处于 alpha 阶段。 您可能使用的是 2.x,在这种情况下没有映射。 最好的办法是使用重复字段: repeated MyMap map_field = 4; message MyMap { optional string key = 1; optional string value = 2; }
  • Protobuf3:如何描述重复字符串的映射?(Protobuf3: How to describe map of repeated string?)
    问题 关于地图类型的官方文档说: map<key_type, value_type> map_field = N; ...其中 key_type 可以是任何整数或字符串类型(因此,除了浮点类型和字节之外的任何标量类型)。 value_type 可以是任何类型。 我想定义一个map<string, repeated string>字段,但它在我的libprotoc 3.0.0上似乎是非法的,它抱怨Expected ">" 。 所以我想知道是否有任何方法可以将重复的字符串放入地图中。 一个可能的解决方法可能是: message ListOfString { repeated string value = 1; } // Then define: map<string, ListOfString> mapToRepeatedString = 1; 但是这里的ListOfString看起来是多余的。 回答1 我有同样的需求,并得到了同样的错误。 我不相信这是可能的。 这是语言规范中的相关 BNF 定义。 https://developers.google.com/protocol-buffers/docs/reference/proto3-spec messageType = [ "." ] { ident "." } messageName mapField = "map" "<"
  • 重新开始---sgg-netty----8
    总结: 1.channelHandlerContext 2.channelOption 3.EvevtLoopGroup和NioEventLoopGroup 4.Unpooled是netty提供的自带指针不用flip,readIndex和writeIndex -----------------------------------------72--------------------------------------------- -----------------------------------------73--------------------------------------------- 问题对象是如何编解码的呢? Protobuf 目前很多公司是tcp+Protobuf替换http+json -----------------------------------------74--------------------------------------------- 代码: 第一步:引入jar包,写.protoc文件 可以看下官网的protobuf的类型 syntax = "proto3"; //版本 option java_outer_classname = "StudentPOJO";//生成的外部类名,同时也是文件名 //protobuf
  • 使用 MapStruct 进行转换时防止循环引用(Prevent Cyclic references when converting with MapStruct)
    问题 今天我开始使用 MapStruct 为我的项目创建模型到 DTO 转换器,我想知道它是否会自动处理循环引用,但事实证明它没有。 这是我用来测试它的转换器: package it.cdc.snp.services.rest.giudizio; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; import org.springframework.stereotype.Component; import it.cdc.snp.dto.entita.Avvisinotifica; import it.cdc.snp.dto.entita.Corrispondenza; import it.cdc.snp.model.notifica.AvvisoDiNotificaModel; import it.cdc.snp.model.notifica.NotificaModel; import it.cdc.snp.model.procedimento.ProcedimentoModel; @Component @Mapper(componentModel="spring")
  • 深入 ProtoBuf - 简介Protobuf 使用指南
    简单来讲, ProtoBuf 是结构数据序列化[1] 方法,可简单类比于 XML[2],其具有以下特点: 语言无关、平台无关。即 ProtoBuf 支持 Java、C++、Python 等多种语言,支持多个平台 高效。即比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单 扩展性、兼容性好。你可以更新数据结构,而不影响和破坏原有的旧程序 序列化[1]:将结构数据或对象转换成能够被存储和传输(例如网络传输)的格式,同时应当要保证这个序列化结果在之后(可能在另一个计算环境中)能够被重建回原来的结构数据或对象。 更为详尽的介绍可参阅 维基百科。 类比于 XML[2]:这里主要指在数据通信和数据存储应用场景中序列化方面的类比,但个人认为 XML 作为一种扩展标记语言和 ProtoBuf 还是有着本质区别的。 使用 ProtoBuf 对 ProtoBuf 的基本概念有了一定了解之后,我们来看看具体该如何使用 ProtoBuf。 第一步,创建 .proto 文件,定义数据结构,如下例1所示: // 例1: 在 xxx.proto 文件中定义 Example1 message message Example1 { optional string stringVal = 1; optional bytes bytesVal = 2; message
  • MapStruct:从 java.util.Map 映射到 Bean?(MapStruct: mapping from java.util.Map to Bean?)
    问题 我目前有一个Map<String, String> ,其中包含key = value形式的key = value ,我想将它们“扩展”为一个真实的对象。 是否可以使用 MapStruct 自动执行此操作,我将如何执行此操作? 澄清一下:我手工编写的代码如下所示: public MyEntity mapToEntity(final Map<String, String> parameters) { final MyEntity result = new MyEntity(); result.setNote(parameters.get("note")); result.setDate(convertStringToDate(parameters.get("date"))); result.setCustomer(mapIdToCustomer(parameters.get("customerId"))); // ... return result; } 回答1 方法一 MapStruct 存储库为我们提供了有用的示例,例如从地图映射。 从 java.util.Map 映射 bean 看起来像: @Mapper(uses = MappingUtil.class ) public interface SourceTargetMapper { SourceTargetMapper
  • gRPC快速入门(一)——Protobuf简介
    gRPC快速入门(一)——Protobuf简介 一、Protobuf简介 1、Protobuf简介 Protobuf即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。与XML和JSON格式相比,protobuf更小、更快、更便捷。protobuf是跨语言的,并且自带一个编译器(protoc),只需要用protoc进行编译,就可以编译成Java、Python、C++、C#、Go等多种语言代码,然后可以直接使用,不需要再写其它代码,自带有解析的代码。只需要将要被序列化的结构化数据定义一次(在.proto文件定义),便可以使用特别生成的源代码(使用protobuf提供的生成工具)轻松的使用不同的数据流完成对结构数据的读写操作。甚至可以更新.proto文件中对数据结构的定义而不会破坏依赖旧格式编译出来的程序。GitHub地址:https://github.com/protocolbuffers/protobuf不同语言源码版本下载地址:https://github.com/protocolbuffers/protobuf/releases/latest 2、Protobuf的优缺点 Protobuf的优点如下:A、性能号,效率高序列化后字节占用空间比XML少3-10倍,序列化的时间效率比XML快20
  • Protobuf 的 proto3 与 proto2 的区别
    转自:https://solicomo.com/network-dev/protobuf-proto3-vs-proto2.html 这是一篇学习笔记。在粗略的看了 Protobuf 的文档中关于 proto2 和 proto3 的说明后,记录下了几点 proto3 区别于 proto2 的地方。 总的来说,proto3 比 proto2 支持更多语言但 更简洁。去掉了一些复杂的语法和特性,更强调约定而弱化语法。如果是首次使用 Protobuf ,建议使用 proto3 。 在第一行非空白非注释行,必须写: syntax = “proto3”; 字段规则移除了 “required”,并把 “optional” 改名为 “singular”1; 在 proto2 中 required 也是不推荐使用的。proto3 直接从语法层面上移除了 required 规则。其实可以做的更彻底,把所有字段规则描述都撤销,原来的 repeated 改为在类型或字段名后加一对中括号。这样是不是更简洁? “repeated”字段默认采用 packed 编码; 在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式。 语言增加 Go、Ruby、JavaNano 支持; 移除了 default 选项; 在 proto2 中,可以使用 default
  • Protobuf学习笔记(一)
    Protobuf(Protocol Buffer)是谷歌开源的性能优异、跨语言、跨平台的序列化库。 一, 发展过程: proto1:2001年,Protobuf首先在Google内部创建,把它称之为 proto1,一直以来在Google的内部使用,其中也不断的演化。 proto2:Protobuf的开发者重写了Protobuf的实现,保留了proto1的大部分设计。开源的proto2不依赖任何的Google的库,代码也相当的清晰。2008年7月7日,Protobuf被公布出来。Protobuf得到了大家的广泛的关注, 逐步地得到了大家的认可,很多项目采用Protobuf进行消息的通讯,还有基于Protobuf的微服务框架GRPC。 proto3:2016年推出了Proto3。 Proto3简化了proto2的开发,提高了开发的效能,但是也带来了版本不兼容的问题。目前Protobuf的稳定版本是3.9.2,于2019年9月23日发布。 二, 序列化和反序列化: 序列化(serialization、marshalling)的过程是指将数据结构或者对象的状态转换成可以存储(比如文件、内存)或者传输的格式(比如网络)。 反序列化(deserialization、unmarshalling)就是反向操作的过程。 XML是一种基于文本的编码方式,易于阅读和理解
  • go -生成pb文件
    在使用 protoc 工具生成 go 代码的时候报出的如下错误: 在syntax = “proto3”; //版本号版本中字段默认为syntax = “proto3”; //版本号 protoc ./test.proto --go_out=./ WARNING: Missing 'go_package' option in "message.proto", please specify it with the full Go package path as a future release of protoc-gen-go will require this be specified. 是因为在 proto3 的语法中缺少了 option go_package。 解决: 在syntax下面添加option信息 option go_package = "student;student"; student 表示生成的go文件的存放地址,会自动生成目录的。 stu表示生成的go文件所属的包名 比如: option go_package = "student;stu"; test.proto syntax = "proto3"; //版本号 option go_package = "student;stu"; message Student{ //消息,对应于Go的结构体 string
  • 使用 Mapstruct 将多个源字段映射到相同类型的目标字段(Map multiple source fields to same type target fields with Mapstruct)
    问题 考虑以下 POJO: public class SchedulePayload { public String name; public String scheduler; public PeriodPayload notificationPeriod; public PeriodPayload schedulePeriod; } private class Lecture { public ZonedDateTime start; public ZonedDateTime end; } public class XmlSchedule { public String scheduleName; public String schedulerName; public DateTime notificationFrom; public DateTime notificationTo; public DateTime scheduleFrom; public DateTime scheduleTo; } public class PeriodPayload { public DateTime start; public DateTime finish; } 使用 MapStruct,我创建了一个映射器,将XmlSchedule映射到SchedulePayload 。 由于“业务”
  • protobuf语法详解
    文章目录 一、包(package)二、选项(option)三、消息类型(message)3.1、常规消息类型3.1.1、字段修饰符3.1.2、字段类型3.1.2.1、标量类型3.1.2.2、枚举类型3.1.2.3、Any类型3.1.2.4、oneof类型3.1.2.5、map类型 3.1.3、默认值说明3.1.4、标识号 3.2、多个消息类型3.3、嵌套消息类型3.4、更新消息类型 四、RPC服务(service)五、其他5.1 导入proto文件(import) 一、包(package)   为.proto文件添加package声明符,可以防止不同 .proto项目间消息类型的命名发生冲突。 package foo.bar; message Open { ... } message Foo { ... foo.bar.Open open = 1; ... } protobuf包类型的解析和C++类似,都是由内而外进行解析。对于C++,产生的类会被包装在C++的命名空间中,如上例中的Open会被封装在 foo::bar空间中。 二、选项(option)   option会影响特定环境下的处理方式,但是不会改变整个文件声明的含义。 option optimize_for = CODE_SIZE; 三、消息类型(message)   message用于定义结构数据,可以包含多种类型字段
  • 初始Netty原理(四)— 序列化
    在开发一些远程过程调用(RPC)的程序时,一般都会涉及到对象的序列化和反序列化的问题(因为TCP或UDP这些低层协议只能传输字节流,所以应用层需要将Java POJO对象序列化为字节流才能传输)。 对象的序列化方式有以下几种方式: JSON:将Java POJO对象转换成JSON结构化的字符串。一般用于Web应用和移动开发,可读性较强,性能较差。XML:与JSON一样,也是序列化为字符串,只是格式不同,可读性强,一般用于异构系统。JDK内置序列化:将Java POJO对象转换成二进制字节数组,可移植性强,性能较差,可读性差。Protobuf:类似JDK内置序列化,Google开源的高性能、易扩展框架,一般用于高性能通信。 一般常用的序列化方式就是JSON(性能要求不太高的Web开发等)和protobuf(高性能应用,比如和Netty一起实现高性能通信)。 JSON JSON序列化框架 使用的比较多的两个开源的处理JSON的类库: FastJson:这是阿里开源的一个高性能的JSON库,采用独创的算法,将JSON转为Java POJO对象的速度非常快,但将复杂的POJO转换成JSON时可能会出错。Gson:这是Google开源的一个非常完善的JSON解析库,可以完成复杂类型的POJO和JSON之间的相互转换。 结合两者的优势,一般策略是:将POJO转为JSON时使用Gson(序列化)
  • MapStruct 可以对 Hibernate 实体类进行深度代理吗(Can MapStruct do a deep deproxy of Hibernate Entity Classes)
    问题 对于想要直接返回实体类的 Web 服务开发人员来说,这是一个常见问题。 即使我需要的所有数据都已加载,仍有许多我不需要的未初始化代理和集合。 我希望他们只返回 null 而不是抛出延迟加载异常。 基本上我只想要 POJO 合同,但是必须清除代理和休眠集合才能获得它(除非休眠中有一些我不知道的新方法)。 我可以使用 MapStruct 来做到这一点吗? 如果需要,有关此的更多详细信息: http://www.mojavelinux.com/blog/archives/2006/06/hibernate_get_out_of_my_pojo/ http://www.gwtproject.org/articles/using_gwt_with_hibernate.html 吉利德是我发现的唯一适用于此的东西,但它已经不复存在了。 回答1 是的,您可以使用 MapStruct 做到这一点。 但是,只有通过明确标记要映射的内容和要忽略的内容。 假设您有以下课程: public class Car { private String name; private int year; //This is lazy loaded private List<Wheel> wheels; //getters and setters omitted for simplicity } public
  • Protobuf3语言指南
    定义一个消息类型 指定字段类型分配标识号指定字段规则添加更多消息类型添加注释保留标识符(Reserved)从.proto文件生成了什么?标量数值类型默认值枚举使用其他消息类型 导入定义使用proto2消息类型嵌套类型更新一个消息类型AnyOneof 使用OneofOneof 特性向后兼容性问题映射(Maps) 向后兼容性问题包(Packages) 包及名称的解析定义服务JSON 映射选项 自定义选项生成你的类 英文原文: Language Guide (proto3) 中文出处: Protobuf语言指南 [译]Protobuf 语法指南 中文出处是proto2的译文,proto3的英文出现后在原来基础上增改了,水平有限,还请指正 这个指南描述了如何使用Protocol buffer 语言去描述你的protocol buffer 数据, 包括 .proto文件符号和如何从.proto文件生成类。包含了proto2版本的protocol buffer语言:对于老版本的proto3 符号,请见Proto2 Language Guide(以及中文译本,抄了很多这里的感谢下老版本的翻译者) 本文是一个参考指南——如果要查看如何使用本文中描述的多个特性的循序渐进的例子,请在教程中查找需要的语言的教程。 定义一个消息类型 先来看一个非常简单的例子。假设你想定义一个“搜索请求”的消息格式
  • 如何在 Hadoop/Spark 中使用 proto3?(How can I use proto3 with Hadoop/Spark?)
    问题 我有几个依赖syntax = "proto3"; .proto 文件syntax = "proto3"; . 我还有一个 Maven 项目,用于构建 Hadoop/Spark 作业(Hadoop 2.7.1 和 Spark 1.5.2)。 我想在 Hadoop/Spark 中生成数据,然后根据我的 proto3 文件对其进行序列化。 使用 libprotoc 3.0.0,我生成 Java 源代码,只要我的 pom.xml 中有以下内容,它就可以在我的 Maven 项目中正常工作: <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.0.0-beta-1</version> </dependency> 现在,当我在部署到集群的作业中使用我的 libprotoc 生成的类时,我遇到了: java.lang.VerifyError : class blah overrides final method mergeUnknownFields.(Lcom/google/protobuf/UnknownFieldSet;)Lcom/google/protobuf/GeneratedMessage$Builder; at java.lang
  • protobuf中坑人的2点
    protobuf中坑人的2点: 1.oneof类型不能通过json反序列化 2.最里层的message没有null值,都会被赋该类型的默认值 1.oneof类型不能通过json反序列化 定义一个这样的protobuf消息: message EnvValue { oneof val { string s = 1; double f = 2; } } 生成的go语言代码对应的结构为: type EnvValue struct { // Types that are valid to be assigned to Val: // *EnvValue_S // *EnvValue_F Val isEnvValue_Val `protobuf_oneof:"val"` XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"` XXX_unrecognized []byte `json:"-" bson:"-"` XXX_sizecache int32 `json:"-" bson:"-"` } 定义一个EnvValue对象envValue: envValue := &pb.EnvValue{ Val: &pb.EnvValue_F{ F: 5, }, } 使用json.Marshal方法将序列化为json: { "val": { "Val": {
  • Netty学习(三)
    Netty Google Protobuf 编码和解码 编写网络应用程序时,因为数据在网络中传输的都是二进制字节码数据,在发送数据时就需要编码,接收数据时就需要解码。codec(编解码器)的组成部分有两个:decoder(解码器)和coder(编码器)。encoder负责把业务数据转换成字节码数据;decoder负责把字节码数据转换为业务数据 Netty本身的编解码机制和问题分析 netty自身提供了一些cedec(编解码器)netty提供了StringEncoder、StringDecoder,可以对字符串数据进行编解码;ObjectEncoder、ObjectDecoder可以对java对象进行编解码Netty本身自带的ObjectEncoder、ObjectDecoder可以用来实现POJO对象或各种业务对象的编码和解码,底层使用的仍然是java序列化技术,效率不高,存在以下问题: 无法跨语言序列化后的体积太大,是二进制代码的五倍多序列化性能太低 Protobuf Protobuf是Google的开源项目,是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化。很适合用于做数据存储或RPC(远程过程调用)数据交换格式。——http + json和tcp + protobufProtobuf是以message的方法是来管理数据的
  • 深入理解 ProtoBuf 原理与工程实践(概述)
    ProtoBuf 作为一种跨平台、语言无关、可扩展的序列化结构数据的方法,已广泛应用于网络数据交换及存储。随着互联网的发展,系统的异构性会愈发突出,跨语言的需求会愈加明显,同时 gRPC 也大有取代Restful之势,而 ProtoBuf 作为g RPC 跨语言、高性能的法宝,我们技术人有必要 深入理解 ProtoBuf 原理,为以后的技术更新和选型打下基础。 我将过去的学习过程以及实践经验,总结成系列文章,与大家一起探讨学习,希望大家能有所收获,当然其中有不正确的地方也欢迎大家批评指正。 本系列文章主要包含: 深入理解 ProtoBuf 原理与工程实践(概述) 深入理解 ProtoBuf 原理与工程实践(编码) 深入理解 ProtoBuf 原理与工程实践(序列化) 深入理解 ProtoBuf 原理与工程实践(工程实践) 一、什么是ProtoBuf ProtoBuf(Protocol Buffers)是一种跨平台、语言无关、可扩展的序列化结构数据的方法,可用于网络数据交换及存储。 在序列化结构化数据的机制中,ProtoBuf是灵活、高效、自动化的,相对常见的XML、JSON,描述同样的信息,ProtoBuf序列化后数据量更小、序列化/反序列化速度更快、更简单。 一旦定义了要处理的数据的数据结构之后,就可以利用ProtoBuf的代码生成工具生成相关的代码。只需使用 Protobuf