使用 mapStruct 将平面 protobuf 消息映射到具有内部 classes 的 class

mapping from flat protobuf message to class with inner classes using mapStruct

我需要使用 mapStruct 来编写从消息 AddressProtoclass 地址的映射。但是消息 AddressProto 仅包含字符串字段,而 Address class 具有内部 classes.

到目前为止我已经写了这样一个映射器,但是由于消息结构和class之间的差异,我不知道如何正确地将字段从消息AddressProto映射到class Address 并返回。

@Mapper(config = MapstructConfig.class, unmappedTargetPolicy = ReportingPolicy.ERROR)
public abstract class AddressProtoMapper {

  // from proto to object
  public abstract Address mapToAddress(AddressProto address);

  // from object to proto
  public abstract AddressProto mapAddressToProto(Address address);
}

proto message AddressProto(在每个字段的斜杠后,我写在需要映射的class字段中):

message AddressProto {
    string value = 1;               // Address.AddressValue.value
    string unrestricted_value = 2;  // Address.AddressValue.unrestrictedValue
    string country = 3;             // Address.Structure.Country.name
    string country_iso_code = 4;    // Address.Structure.Country.isoCode
    string region = 5;              // Address.Structure.Region.name
}

java class Address:

public class Address {
    public final AddressValue value;
    public final Structure structure;


    public static class AddressValue {
        public final String value;
        public final String unrestrictedValue;
    }


    public static class Structure {
        public final Country country;
        public final Region region;

        public static class Country {
            public final String name;
            public final String isoCode;
        }

        public static class Region {
            public final String name;
        }

    }
}

事实证明解决方案非常简单。甚至太多了:) 您只需要编写自己的实现即可。

@Mapper(
    config = MapstructConfig.class,
    unmappedTargetPolicy = ReportingPolicy.ERROR
)
public interface AddressProtoMapper {
  default Address mapToAddress(AddressProto address){
    return new Address(
        ...
    );
  }

  default AddressProto mapAddressToProto(Address address) {
    return new AddressProto(
        ...
    );
  }
}