MapStruct文档(十二)——protobuf映射

目录

11.1、protobuf2 

11.2、protobuf3


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") );

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值