目录
11.1、protobuf2
定义一些基础类
enum DownloadResourceTypeEnum{
download_resource_type_enum_audio = 0; //音频
download_resource_type_enum_vedio = 1; //视频
download_resource_type_enum_picture = 2; //图片
download_resource_type_enum_txtfile = 3; //txt文件
download_resource_type_enum_wordfile = 4; //word文档
download_resource_type_enum_excelfile = 5; //excel文档
download_resource_type_enum_pptfile = 6; //ppt文档
download_resource_type_enum_pdffile = 7; //pdf文档
}
message Test {
optional int32 id = 1;
optional string name = 2;
optional string create_time = 3;
repeated Item item = 4;
optional DownloadResourceTypeEnum download_resource_type_enum = 5;
optional Item main_item = 6;
optional bool disable = 7;
optional float pre_price = 8;
map<string, string> kv = 9;
oneof test_oneof {
string one_string = 10;
int32 one_int = 11;
}
repeated string number = 12;
repeated DownloadResourceTypeEnum types = 13;
repeated int32 nos = 14;
}
message Item {
optional int64 item_id = 1;
optional double price = 2;
optional uint32 uint32_count = 3; // 对应java int
optional uint64 uint64_count = 4; // 对应java Long
optional sint32 sint32_count = 5; // 对应java INT 比常规int32更有效地编码负数
optional sint64 sint64_count = 6; // 对应java long 比常规int64更有效地编码负数
optional fixed32 fixed32_count = 7; // 对应java int 总是四个字节。如果值通常大于228,则比uint32更有效
optional fixed64 fixed64_count = 8; // 对应java Long 总是八个字节。如果值通常大于256,则比uint64更有效
optional sfixed32 sfixed32_count = 9; // 对应java INT 总是四个字节。
optional sfixed64 sfixed64_count = 10; // 对应java long 总是八个字节。
optional bytes type = 11; // 不可变的字节数组 不涉及转码 通常用于传输字符流
}
@Data
public class TestDTO {
private Integer id;
private String name;
private Date createTime;
private TypeEnum downloadResourceTypeEnum;
private ItemDTO mainItem;
private Boolean disable;
private BigDecimal prePrice;
private Map<String, String> kv;
private String oneString;
private Integer oneInt;
private List<ItemDTO> itemList;
private List<String> numberList;
private List<TypeEnum> typesList;
private List<Integer> nosList;
}
@Data
public class ItemDTO {
private Long itemId;
private Double price;
private Integer uint32Count;
private Long uint64Count;
private Integer sint32Count;
private Long sint64Count;
private Integer fixed32Count;
private Long fixed64Count;
private Integer sfixed32Count;
private Long sfixed64Count;
private byte[] type;
}
使用
@Mapper
public class BaseMapper {
@ObjectFactory
public ProtocolStringList createProtocolStringList(List<String> list) {
return new LazyStringArrayList(list.size());
}
public static byte[] toByte(ByteString bytes) {
return bytes.toByteArray();
}
}
@Mapper(uses = {ByteString.class, BaseMapper.class}, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface TestMapper {
Test toProto(TestDTO testDTO);
TestDTO toDTO(Test test);
}
编译的结果
@Component
public class TestMapperImpl implements TestMapper {
@Autowired
private ByteString byteString;
@Override
public Test toProto(TestDTO testDTO) {
if ( testDTO == null ) {
return null;
}
Builder test = Test.newBuilder();
if ( testDTO.getId() != null ) {
test.setId( testDTO.getId() );
}
try {
if ( testDTO.getName() != null ) {
test.setName( byteString.toString( testDTO.getName() ) );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
if ( testDTO.getCreateTime() != null ) {
test.setCreateTime( new SimpleDateFormat().format( testDTO.getCreateTime() ) );
}
if ( testDTO.getDownloadResourceTypeEnum() != null ) {
test.setDownloadResourceTypeEnum( typeEnumToDownloadResourceEnum( testDTO.getDownloadResourceTypeEnum() ) );
}
if ( testDTO.getMainItem() != null ) {
test.setMainItem( itemDTOToItem( testDTO.getMainItem() ) );
}
if ( testDTO.getDisable() != null ) {
test.setDisable( testDTO.getDisable() );
}
if ( testDTO.getPrePrice() != null ) {
test.setPrePrice( testDTO.getPrePrice().floatValue() );
}
try {
if ( testDTO.getOneString() != null ) {
test.setOneString( byteString.toString( testDTO.getOneString() ) );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
if ( testDTO.getOneInt() != null ) {
test.setOneInt( testDTO.getOneInt() );
}
if ( testDTO.getItemList() != null ) {
for ( ItemDTO itemList : testDTO.getItemList() ) {
test.addItem( itemDTOToItem( itemList ) );
}
}
if ( test.getKv() != null ) {
Map<String, String> map = testDTO.getKv();
if ( map != null ) {
test.getKv().putAll( map );
}
}
try {
if ( testDTO.getNumberList() != null ) {
for ( String numberList : testDTO.getNumberList() ) {
test.addNumber( byteString.toString( numberList ) );
}
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
if ( testDTO.getTypesList() != null ) {
for ( TypeEnum typesList : testDTO.getTypesList() ) {
test.addTypes( typeEnumToDownloadResourceEnum( typesList ) );
}
}
if ( test.getNosList() != null ) {
List<Integer> list = testDTO.getNosList();
if ( list != null ) {
test.getNosList().addAll( list );
}
}
return test.build();
}
@Override
public TestDTO toDTO(Test test) {
if ( test == null ) {
return null;
}
TestDTO testDTO = new TestDTO();
if ( test.hasId() ) {
testDTO.setId( test.getId() );
}
try {
if ( test.hasName() ) {
testDTO.setName( byteString.toString( test.getName() ) );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
try {
if ( test.hasCreateTime() ) {
testDTO.setCreateTime( new SimpleDateFormat().parse( test.getCreateTime() ) );
}
}
catch ( ParseException e ) {
throw new RuntimeException( e );
}
if ( test.hasDownloadResourceTypeEnum() ) {
testDTO.setDownloadResourceTypeEnum( downloadResourceEnumToTypeEnum( test.getDownloadResourceTypeEnum() ) );
}
if ( test.hasMainItem() ) {
testDTO.setMainItem( itemToItemDTO( test.getMainItem() ) );
}
if ( test.hasDisable() ) {
testDTO.setDisable( test.getDisable() );
}
if ( test.hasPrePrice() ) {
testDTO.setPrePrice( BigDecimal.valueOf( test.getPrePrice() ) );
}
Map<String, String> map = test.getKv();
if ( map != null ) {
testDTO.setKv( new HashMap<String, String>( map ) );
}
try {
if ( test.hasOneString() ) {
testDTO.setOneString( byteString.toString( test.getOneString() ) );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
if ( test.hasOneInt() ) {
testDTO.setOneInt( test.getOneInt() );
}
List<ItemDTO> list = itemListToItemDTOList( test.getItemList() );
if ( list != null ) {
testDTO.setItemList( list );
}
ProtocolStringList protocolStringList = test.getNumberList();
if ( protocolStringList != null ) {
testDTO.setNumberList( new ArrayList<String>( protocolStringList ) );
}
List<TypeEnum> list1 = downloadResourceEnumListToTypeEnumList( test.getTypesList() );
if ( list1 != null ) {
testDTO.setTypesList( list1 );
}
List<Integer> list2 = test.getNosList();
if ( list2 != null ) {
testDTO.setNosList( new ArrayList<Integer>( list2 ) );
}
return testDTO;
}
protected DownloadResourceEnum typeEnumToDownloadResourceEnum(TypeEnum typeEnum) {
if ( typeEnum == null ) {
return null;
}
DownloadResourceEnum downloadResourceEnum;
switch ( typeEnum ) {
case download_resource_type_enum_audio: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_audio;
break;
case download_resource_type_enum_vedio: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_vedio;
break;
case download_resource_type_enum_picture: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_picture;
break;
case download_resource_type_enum_txtfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_txtfile;
break;
case download_resource_type_enum_wordfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_wordfile;
break;
case download_resource_type_enum_excelfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_excelfile;
break;
case download_resource_type_enum_pptfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_pptfile;
break;
case download_resource_type_enum_pdffile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_pdffile;
break;
default: throw new IllegalArgumentException( "Unexpected enum constant: " + typeEnum );
}
return downloadResourceEnum;
}
protected Item itemDTOToItem(ItemDTO itemDTO) {
if ( itemDTO == null ) {
return null;
}
com.ljc.orika.proto.Item.Builder item = Item.newBuilder();
if ( itemDTO.getItemId() != null ) {
item.setItemId( itemDTO.getItemId() );
}
if ( itemDTO.getPrice() != null ) {
item.setPrice( itemDTO.getPrice() );
}
if ( itemDTO.getUint32Count() != null ) {
item.setUint32Count( itemDTO.getUint32Count() );
}
if ( itemDTO.getUint64Count() != null ) {
item.setUint64Count( itemDTO.getUint64Count() );
}
if ( itemDTO.getSint32Count() != null ) {
item.setSint32Count( itemDTO.getSint32Count() );
}
if ( itemDTO.getSint64Count() != null ) {
item.setSint64Count( itemDTO.getSint64Count() );
}
if ( itemDTO.getFixed32Count() != null ) {
item.setFixed32Count( itemDTO.getFixed32Count() );
}
if ( itemDTO.getFixed64Count() != null ) {
item.setFixed64Count( itemDTO.getFixed64Count() );
}
if ( itemDTO.getSfixed32Count() != null ) {
item.setSfixed32Count( itemDTO.getSfixed32Count() );
}
if ( itemDTO.getSfixed64Count() != null ) {
item.setSfixed64Count( itemDTO.getSfixed64Count() );
}
if ( itemDTO.getType() != null ) {
item.setType( ByteString.copyFrom( itemDTO.getType() ) );
}
return item.build();
}
protected TypeEnum downloadResourceEnumToTypeEnum(DownloadResourceEnum downloadResourceEnum) {
if ( downloadResourceEnum == null ) {
return null;
}
TypeEnum typeEnum;
switch ( downloadResourceEnum ) {
case download_resource_type_enum_audio: typeEnum = TypeEnum.download_resource_type_enum_audio;
break;
case download_resource_type_enum_vedio: typeEnum = TypeEnum.download_resource_type_enum_vedio;
break;
case download_resource_type_enum_picture: typeEnum = TypeEnum.download_resource_type_enum_picture;
break;
case download_resource_type_enum_txtfile: typeEnum = TypeEnum.download_resource_type_enum_txtfile;
break;
case download_resource_type_enum_wordfile: typeEnum = TypeEnum.download_resource_type_enum_wordfile;
break;
case download_resource_type_enum_excelfile: typeEnum = TypeEnum.download_resource_type_enum_excelfile;
break;
case download_resource_type_enum_pptfile: typeEnum = TypeEnum.download_resource_type_enum_pptfile;
break;
case download_resource_type_enum_pdffile: typeEnum = TypeEnum.download_resource_type_enum_pdffile;
break;
default: throw new IllegalArgumentException( "Unexpected enum constant: " + downloadResourceEnum );
}
return typeEnum;
}
protected ItemDTO itemToItemDTO(Item item) {
if ( item == null ) {
return null;
}
ItemDTO itemDTO = new ItemDTO();
if ( item.hasItemId() ) {
itemDTO.setItemId( item.getItemId() );
}
if ( item.hasPrice() ) {
itemDTO.setPrice( item.getPrice() );
}
if ( item.hasUint32Count() ) {
itemDTO.setUint32Count( item.getUint32Count() );
}
if ( item.hasUint64Count() ) {
itemDTO.setUint64Count( item.getUint64Count() );
}
if ( item.hasSint32Count() ) {
itemDTO.setSint32Count( item.getSint32Count() );
}
if ( item.hasSint64Count() ) {
itemDTO.setSint64Count( item.getSint64Count() );
}
if ( item.hasFixed32Count() ) {
itemDTO.setFixed32Count( item.getFixed32Count() );
}
if ( item.hasFixed64Count() ) {
itemDTO.setFixed64Count( item.getFixed64Count() );
}
if ( item.hasSfixed32Count() ) {
itemDTO.setSfixed32Count( item.getSfixed32Count() );
}
if ( item.hasSfixed64Count() ) {
itemDTO.setSfixed64Count( item.getSfixed64Count() );
}
if ( item.hasType() ) {
itemDTO.setType( BaseMapper.toByte( item.getType() ) );
}
return itemDTO;
}
protected List<ItemDTO> itemListToItemDTOList(List<Item> list) {
if ( list == null ) {
return null;
}
List<ItemDTO> list1 = new ArrayList<ItemDTO>( list.size() );
for ( Item item : list ) {
list1.add( itemToItemDTO( item ) );
}
return list1;
}
protected List<TypeEnum> downloadResourceEnumListToTypeEnumList(List<DownloadResourceEnum> list) {
if ( list == null ) {
return null;
}
List<TypeEnum> list1 = new ArrayList<TypeEnum>( list.size() );
for ( DownloadResourceEnum downloadResourceEnum : list ) {
list1.add( downloadResourceEnumToTypeEnum( downloadResourceEnum ) );
}
return list1;
}
}
proto->bean:
看一下protoc生成的java类中的repeated类型的字段。
get集合的方法后面加上了“List”,就如第4.5章所介绍的,所以强烈建议javabean对应的List<T>类型的字段名同名且后面加上“List”。
因为optional类型的字段不能设为null,也推荐nullValueCheckStrategy设为NullValueCheckStrategy.ALWAYS;还可以发现生成的proto映射bean的方法中,会自动调用hasXXX方法判断"null"。
若有bytes类型的字段,要转成byte[],要导入ByteString.class。
当使用的是默认的集合映射策略,若有要转成List<String>,要手动创建一个工厂方法,正如BaseMapper#createProtocolStringList,因为自动映射生成的方法时会new ProtocolStringList(),然而ProtocolStringList是抽象类。
getNumberList返回的类型是ProtocolStringList。
若使用的是CollectionMappingStrategy.ADDER_PREFERRED,因为会一个个add进去,所以无需再调用工厂方法;但又因为可能匹配到多个add方法,所以最终还是会使用get-addAll的策略。
bean->proto:
注意byte[]转bytes时,要手动指定一个映射方法,正如BaseMapper#toByte方法。
不能更新protobuf对象,更新总是会clear-get-addAll:
使用protobuf的builder对象操作时,其中一个原因List<Long>类型的实现是一个UnmodifiableRandomAccessList,mapstruct在更新list时会clear集合,使用会抛异常。
使用protobuf对象而非builder时,集合是一个EmptyList,增删改查也会抛异常。
使用默认的集合映射策略的结果
@Component
public class TestMapperImpl implements TestMapper {
@Autowired
private ByteString byteString;
@Autowired
private BaseMapper baseMapper;
@Override
public Test toProto(TestDTO testDTO) {
if ( testDTO == null ) {
return null;
}
Builder test = Test.newBuilder();
if ( testDTO.getId() != null ) {
test.setId( testDTO.getId() );
}
try {
if ( testDTO.getName() != null ) {
test.setName( byteString.toString( testDTO.getName() ) );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
if ( testDTO.getCreateTime() != null ) {
test.setCreateTime( new SimpleDateFormat().format( testDTO.getCreateTime() ) );
}
if ( testDTO.getDownloadResourceTypeEnum() != null ) {
test.setDownloadResourceTypeEnum( typeEnumToDownloadResourceEnum( testDTO.getDownloadResourceTypeEnum() ) );
}
if ( testDTO.getMainItem() != null ) {
test.setMainItem( itemDTOToItem( testDTO.getMainItem() ) );
}
if ( testDTO.getDisable() != null ) {
test.setDisable( testDTO.getDisable() );
}
if ( testDTO.getPrePrice() != null ) {
test.setPrePrice( testDTO.getPrePrice().floatValue() );
}
try {
if ( testDTO.getOneString() != null ) {
test.setOneString( byteString.toString( testDTO.getOneString() ) );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
if ( testDTO.getOneInt() != null ) {
test.setOneInt( testDTO.getOneInt() );
}
if ( test.getItemList() != null ) {
List<Item> list = itemDTOListToItemList( testDTO.getItemList() );
if ( list != null ) {
test.getItemList().addAll( list );
}
}
if ( test.getKv() != null ) {
Map<String, String> map = testDTO.getKv();
if ( map != null ) {
test.getKv().putAll( map );
}
}
if ( test.getNumberList() != null ) {
try {
ProtocolStringList protocolStringList = stringListToProtocolStringList( testDTO.getNumberList() );
if ( protocolStringList != null ) {
test.getNumberList().addAll( protocolStringList );
}
}
catch ( UnsupportedEncodingException e ) {
throw new RuntimeException( e );
}
}
if ( test.getTypesList() != null ) {
List<DownloadResourceEnum> list1 = typeEnumListToDownloadResourceEnumList( testDTO.getTypesList() );
if ( list1 != null ) {
test.getTypesList().addAll( list1 );
}
}
if ( test.getNosList() != null ) {
List<Integer> list2 = testDTO.getNosList();
if ( list2 != null ) {
test.getNosList().addAll( list2 );
}
}
return test.build();
}
protected DownloadResourceEnum typeEnumToDownloadResourceEnum(TypeEnum typeEnum) {
if ( typeEnum == null ) {
return null;
}
DownloadResourceEnum downloadResourceEnum;
switch ( typeEnum ) {
case download_resource_type_enum_audio: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_audio;
break;
case download_resource_type_enum_vedio: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_vedio;
break;
case download_resource_type_enum_picture: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_picture;
break;
case download_resource_type_enum_txtfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_txtfile;
break;
case download_resource_type_enum_wordfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_wordfile;
break;
case download_resource_type_enum_excelfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_excelfile;
break;
case download_resource_type_enum_pptfile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_pptfile;
break;
case download_resource_type_enum_pdffile: downloadResourceEnum = DownloadResourceEnum.download_resource_type_enum_pdffile;
break;
default: throw new IllegalArgumentException( "Unexpected enum constant: " + typeEnum );
}
return downloadResourceEnum;
}
protected Item itemDTOToItem(ItemDTO itemDTO) {
if ( itemDTO == null ) {
return null;
}
com.ljc.orika.proto.Item.Builder item = Item.newBuilder();
if ( itemDTO.getItemId() != null ) {
item.setItemId( itemDTO.getItemId() );
}
if ( itemDTO.getPrice() != null ) {
item.setPrice( itemDTO.getPrice() );
}
if ( itemDTO.getUint32Count() != null ) {
item.setUint32Count( itemDTO.getUint32Count() );
}
if ( itemDTO.getUint64Count() != null ) {
item.setUint64Count( itemDTO.getUint64Count() );
}
if ( itemDTO.getSint32Count() != null ) {
item.setSint32Count( itemDTO.getSint32Count() );
}
if ( itemDTO.getSint64Count() != null ) {
item.setSint64Count( itemDTO.getSint64Count() );
}
if ( itemDTO.getFixed32Count() != null ) {
item.setFixed32Count( itemDTO.getFixed32Count() );
}
if ( itemDTO.getFixed64Count() != null ) {
item.setFixed64Count( itemDTO.getFixed64Count() );
}
if ( itemDTO.getSfixed32Count() != null ) {
item.setSfixed32Count( itemDTO.getSfixed32Count() );
}
if ( itemDTO.getSfixed64Count() != null ) {
item.setSfixed64Count( itemDTO.getSfixed64Count() );
}
if ( itemDTO.getType() != null ) {
item.setType( ByteString.copyFrom( itemDTO.getType() ) );
}
return item.build();
}
protected List<Item> itemDTOListToItemList(List<ItemDTO> list) {
if ( list == null ) {
return null;
}
List<Item> list1 = new ArrayList<Item>( list.size() );
for ( ItemDTO itemDTO : list ) {
list1.add( itemDTOToItem( itemDTO ) );
}
return list1;
}
protected ProtocolStringList stringListToProtocolStringList(List<String> list) throws UnsupportedEncodingException {
if ( list == null ) {
return null;
}
ProtocolStringList protocolStringList = baseMapper.createProtocolStringList( list );
for ( String string : list ) {
protocolStringList.add( byteString.toString( string ) );
}
return protocolStringList;
}
protected List<DownloadResourceEnum> typeEnumListToDownloadResourceEnumList(List<TypeEnum> list) {
if ( list == null ) {
return null;
}
List<DownloadResourceEnum> list1 = new ArrayList<DownloadResourceEnum>( list.size() );
for ( TypeEnum typeEnum : list ) {
list1.add( typeEnumToDownloadResourceEnum( typeEnum ) );
}
return list1;
}
}
11.2、protobuf3
protobuf3和protobuf2基本相同,区别在于生成的枚举对象会多一个UNRECOGNIZED。
所以在映射设,注意设此枚举映射为null。
@ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL)
TypeEnum toTypeEnum(DownloadResourceTypeEnum downloadResourceTypeEnum);
带有Any类型的映射
@EqualsAndHashCode(callSuper = true)
@Data
public class Test3DTO extends TestDTO {
private ItemDTO details;
}
message Test3 {
int32 id = 1;
string name = 2;
string create_time = 3;
repeated Item3 item = 4;
DownloadResourceTypeEnum download_resource_type_enum = 5;
Item3 main_item = 6;
bool disable = 7;
float pre_price = 8;
map<string, string> kv = 9;
oneof test_oneof {
string one_string = 10;
int32 one_int = 11;
}
repeated string number = 12;
repeated DownloadResourceTypeEnum types = 13;
repeated int32 nos = 14;
google.protobuf.Any details = 15;
}
message Item3 {
int64 item_id = 1;
double price = 2;
uint32 uint32_count = 3; // 对应java int
uint64 uint64_count = 4; // 对应java Long
sint32 sint32_count = 5; // 对应java INT 比常规int32更有效地编码负数
sint64 sint64_count = 6; // 对应java long 比常规int64更有效地编码负数
fixed32 fixed32_count = 7; // 对应java int 总是四个字节。如果值通常大于228,则比uint32更有效
fixed64 fixed64_count = 8; // 对应java Long 总是八个字节。如果值通常大于256,则比uint64更有效
sfixed32 sfixed32_count = 9; // 对应java INT 总是四个字节。
sfixed64 sfixed64_count = 10; // 对应java long 总是八个字节。
bytes type = 11; // 不可变的字节数组 不涉及转码 通常用于传输字符流
}
enum DownloadResourceTypeEnum{
download_resource_type_enum_audio = 0; //音频
download_resource_type_enum_vedio = 1; //视频
download_resource_type_enum_picture = 2; //图片
download_resource_type_enum_txtfile = 3; //txt文件
download_resource_type_enum_wordfile = 4; //word文档
download_resource_type_enum_excelfile = 5; //excel文档
download_resource_type_enum_pptfile = 6; //ppt文档
download_resource_type_enum_pdffile = 7; //pdf文档
}
@Mapper
public class BaseMapper {
@ObjectFactory
public ProtocolStringList createProtocolStringList(List<String> list) {
return new LazyStringArrayList(list.size());
}
public static byte[] toByte(ByteString bytes) {
return bytes.toByteArray();
}
public static ByteString copyFrom(byte[] bytes) {
return ByteString.copyFrom(bytes);
}
// any转javabean的中间转换方法
public static <T extends GeneratedMessageV3> T unpack(Any any, @TargetType Class<T> clazz) {
T unpack;
try {
unpack = any.unpack(clazz);
} catch (InvalidProtocolBufferException e) {
return null;
}
return unpack;
}
// 这里只是为了在mapstruct编译找最合适方法时中间的过渡,并不是直接调用,但一定要加,具体分析参见第12.6章
public static <T extends GeneratedMessageV3> Any pack(T message) {
return Any.pack(message);
}
// protobuf转javabean的中间转换方法
public static Any packGeneratedMessageV3(GeneratedMessageV3 message) {
return Any.pack(message);
}
public static Date toDateFromString(String dateString, String format) {
if (StringUtils.isEmpty(dateString)) {
return null;
}
Date date;
try {
date = new SimpleDateFormat(format).parse(dateString);
} catch (ParseException e) {
return null;
}
return date;
}
}
@Mapper(uses = { BaseMapper.class}, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface TestMapper {
Test3 toProto(Test3DTO test3DTO);
// 对象属性的转换一定要手动定义方法
Item3 toProtoItem(ItemDTO itemDTO);
@Mapping(target = "createTime", expression = "java(BaseMapper.toDateFromString(test.getCreateTime(), \"yyyy-mm-dd\"))")
Test3DTO toDTO(Test3 test);
// 对象属性的转换一定要手动定义方法
ItemDTO toItemDTO(Item3 item3);
@ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL)
TypeEnum toTypeEnum(DownloadResourceTypeEnum downloadResourceTypeEnum);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public Test3 toProto(Test3DTO test3DTO) {
if ( test3DTO == null ) {
return null;
}
Builder test3 = Test3.newBuilder();
if ( test3DTO.getId() != null ) {
test3.setId( test3DTO.getId() );
}
if ( test3DTO.getName() != null ) {
test3.setName( test3DTO.getName() );
}
if ( test3DTO.getCreateTime() != null ) {
test3.setCreateTime( new SimpleDateFormat().format( test3DTO.getCreateTime() ) );
}
if ( test3DTO.getDownloadResourceTypeEnum() != null ) {
test3.setDownloadResourceTypeEnum( typeEnumToDownloadResourceTypeEnum( test3DTO.getDownloadResourceTypeEnum() ) );
}
if ( test3DTO.getMainItem() != null ) {
test3.setMainItem( toProtoItem( test3DTO.getMainItem() ) );
}
if ( test3DTO.getDisable() != null ) {
test3.setDisable( test3DTO.getDisable() );
}
if ( test3DTO.getPrePrice() != null ) {
test3.setPrePrice( test3DTO.getPrePrice().floatValue() );
}
if ( test3DTO.getOneString() != null ) {
test3.setOneString( test3DTO.getOneString() );
}
if ( test3DTO.getOneInt() != null ) {
test3.setOneInt( test3DTO.getOneInt() );
}
if ( test3DTO.getDetails() != null ) {
test3.setDetails( BaseMapper.packGeneratedMessageV3( toProtoItem( test3DTO.getDetails() ) ) );
}
if ( test3DTO.getItemList() != null ) {
for ( ItemDTO itemList : test3DTO.getItemList() ) {
test3.addItem( toProtoItem( itemList ) );
}
}
if ( test3.getKv() != null ) {
Map<String, String> map = test3DTO.getKv();
if ( map != null ) {
test3.getKv().putAll( map );
}
}
if ( test3DTO.getNumberList() != null ) {
for ( String numberList : test3DTO.getNumberList() ) {
test3.addNumber( numberList );
}
}
if ( test3DTO.getTypesList() != null ) {
for ( TypeEnum typesList : test3DTO.getTypesList() ) {
test3.addTypes( typeEnumToDownloadResourceTypeEnum( typesList ) );
}
}
if ( test3.getNosList() != null ) {
List<Integer> list = test3DTO.getNosList();
if ( list != null ) {
test3.getNosList().addAll( list );
}
}
return test3.build();
}
@Override
public Item3 toProtoItem(ItemDTO itemDTO) {
if ( itemDTO == null ) {
return null;
}
com.ljc.orika.proto3.Item3.Builder item3 = Item3.newBuilder();
if ( itemDTO.getItemId() != null ) {
item3.setItemId( itemDTO.getItemId() );
}
if ( itemDTO.getPrice() != null ) {
item3.setPrice( itemDTO.getPrice() );
}
if ( itemDTO.getUint32Count() != null ) {
item3.setUint32Count( itemDTO.getUint32Count() );
}
if ( itemDTO.getUint64Count() != null ) {
item3.setUint64Count( itemDTO.getUint64Count() );
}
if ( itemDTO.getSint32Count() != null ) {
item3.setSint32Count( itemDTO.getSint32Count() );
}
if ( itemDTO.getSint64Count() != null ) {
item3.setSint64Count( itemDTO.getSint64Count() );
}
if ( itemDTO.getFixed32Count() != null ) {
item3.setFixed32Count( itemDTO.getFixed32Count() );
}
if ( itemDTO.getFixed64Count() != null ) {
item3.setFixed64Count( itemDTO.getFixed64Count() );
}
if ( itemDTO.getSfixed32Count() != null ) {
item3.setSfixed32Count( itemDTO.getSfixed32Count() );
}
if ( itemDTO.getSfixed64Count() != null ) {
item3.setSfixed64Count( itemDTO.getSfixed64Count() );
}
if ( itemDTO.getType() != null ) {
item3.setType( BaseMapper.copyFrom( itemDTO.getType() ) );
}
return item3.build();
}
@Override
public Test3DTO toDTO(Test3 test) {
if ( test == null ) {
return null;
}
Test3DTO test3DTO = new Test3DTO();
test3DTO.setId( test.getId() );
if ( test.getName() != null ) {
test3DTO.setName( test.getName() );
}
testDTO.setCreateTime( BaseMapper.toDateFromString(test.getCreateTime(), "yyyy-mm-dd") );
if ( test.getDownloadResourceTypeEnum() != null ) {
test3DTO.setDownloadResourceTypeEnum( toTypeEnum( test.getDownloadResourceTypeEnum() ) );
}
if ( test.hasMainItem() ) {
test3DTO.setMainItem( toItemDTO( test.getMainItem() ) );
}
test3DTO.setDisable( test.getDisable() );
test3DTO.setPrePrice( BigDecimal.valueOf( test.getPrePrice() ) );
Map<String, String> map = test.getKv();
if ( map != null ) {
test3DTO.setKv( new HashMap<String, String>( map ) );
}
if ( test.getOneString() != null ) {
test3DTO.setOneString( test.getOneString() );
}
test3DTO.setOneInt( test.getOneInt() );
List<ItemDTO> list = item3ListToItemDTOList( test.getItemList() );
if ( list != null ) {
test3DTO.setItemList( list );
}
ProtocolStringList protocolStringList = test.getNumberList();
if ( protocolStringList != null ) {
test3DTO.setNumberList( new ArrayList<String>( protocolStringList ) );
}
List<TypeEnum> list1 = downloadResourceTypeEnumListToTypeEnumList( test.getTypesList() );
if ( list1 != null ) {
test3DTO.setTypesList( list1 );
}
List<Integer> list2 = test.getNosList();
if ( list2 != null ) {
test3DTO.setNosList( new ArrayList<Integer>( list2 ) );
}
if ( test.hasDetails() ) {
test3DTO.setDetails( toItemDTO( BaseMapper.unpack( test.getDetails(), Item3.class ) ) );
}
return test3DTO;
}
@Override
public ItemDTO toItemDTO(Item3 item3) {
if ( item3 == null ) {
return null;
}
ItemDTO itemDTO = new ItemDTO();
itemDTO.setItemId( item3.getItemId() );
itemDTO.setPrice( item3.getPrice() );
itemDTO.setUint32Count( item3.getUint32Count() );
itemDTO.setUint64Count( item3.getUint64Count() );
itemDTO.setSint32Count( item3.getSint32Count() );
itemDTO.setSint64Count( item3.getSint64Count() );
itemDTO.setFixed32Count( item3.getFixed32Count() );
itemDTO.setFixed64Count( item3.getFixed64Count() );
itemDTO.setSfixed32Count( item3.getSfixed32Count() );
itemDTO.setSfixed64Count( item3.getSfixed64Count() );
if ( item3.getType() != null ) {
itemDTO.setType( BaseMapper.toByte( item3.getType() ) );
}
return itemDTO;
}
@Override
public TypeEnum toTypeEnum(DownloadResourceTypeEnum downloadResourceTypeEnum) {
if ( downloadResourceTypeEnum == null ) {
return null;
}
TypeEnum typeEnum;
switch ( downloadResourceTypeEnum ) {
case UNRECOGNIZED: typeEnum = null;
break;
case download_resource_type_enum_audio: typeEnum = TypeEnum.download_resource_type_enum_audio;
break;
case download_resource_type_enum_vedio: typeEnum = TypeEnum.download_resource_type_enum_vedio;
break;
case download_resource_type_enum_picture: typeEnum = TypeEnum.download_resource_type_enum_picture;
break;
case download_resource_type_enum_txtfile: typeEnum = TypeEnum.download_resource_type_enum_txtfile;
break;
case download_resource_type_enum_wordfile: typeEnum = TypeEnum.download_resource_type_enum_wordfile;
break;
case download_resource_type_enum_excelfile: typeEnum = TypeEnum.download_resource_type_enum_excelfile;
break;
case download_resource_type_enum_pptfile: typeEnum = TypeEnum.download_resource_type_enum_pptfile;
break;
case download_resource_type_enum_pdffile: typeEnum = TypeEnum.download_resource_type_enum_pdffile;
break;
default: throw new IllegalArgumentException( "Unexpected enum constant: " + downloadResourceTypeEnum );
}
return typeEnum;
}
protected DownloadResourceTypeEnum typeEnumToDownloadResourceTypeEnum(TypeEnum typeEnum) {
if ( typeEnum == null ) {
return null;
}
DownloadResourceTypeEnum downloadResourceTypeEnum;
switch ( typeEnum ) {
case download_resource_type_enum_audio: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_audio;
break;
case download_resource_type_enum_vedio: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_vedio;
break;
case download_resource_type_enum_picture: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_picture;
break;
case download_resource_type_enum_txtfile: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_txtfile;
break;
case download_resource_type_enum_wordfile: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_wordfile;
break;
case download_resource_type_enum_excelfile: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_excelfile;
break;
case download_resource_type_enum_pptfile: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_pptfile;
break;
case download_resource_type_enum_pdffile: downloadResourceTypeEnum = DownloadResourceTypeEnum.download_resource_type_enum_pdffile;
break;
default: throw new IllegalArgumentException( "Unexpected enum constant: " + typeEnum );
}
return downloadResourceTypeEnum;
}
protected List<ItemDTO> item3ListToItemDTOList(List<Item3> list) {
if ( list == null ) {
return null;
}
List<ItemDTO> list1 = new ArrayList<ItemDTO>( list.size() );
for ( Item3 item3 : list ) {
list1.add( toItemDTO( item3 ) );
}
return list1;
}
protected List<TypeEnum> downloadResourceTypeEnumListToTypeEnumList(List<DownloadResourceTypeEnum> list) {
if ( list == null ) {
return null;
}
List<TypeEnum> list1 = new ArrayList<TypeEnum>( list.size() );
for ( DownloadResourceTypeEnum downloadResourceTypeEnum : list ) {
list1.add( toTypeEnum( downloadResourceTypeEnum ) );
}
return list1;
}
}
test3.setDetails( BaseMapper.packGeneratedMessageV3( toProtoItem( test3DTO.getDetails() ) ) ),这里涉及了复杂映射,最里层转换方法是调用了手动定义的方法,因为通过第3.2章可知,自动生成子映射会在复杂转换规则之后,Any转javabean中间要先转成具体的protobuf对象,不先调用Any到具体的protobuf对象的转换,mapstruct会没有找到相应的转换发现,也不会再调用BaseMapper#packGeneratedMessageV3,转而执行规则5,而自动生成一个,但不能满足具体转换。
protobuf3中不再有基础属性类型的hasXXX检查,使用string类型默认值是“”,转换可能会有NPE,比如转Date,这里只有手动指定expression转换 testDTO.setCreateTime( BaseMapper.toDateFromString(test.getCreateTime(), "yyyy-mm-dd") );。