【问题标题】:How to use custom yml file reference to map values using Mapstruct in Spring boot?如何在 Spring Boot 中使用 Mapstruct 使用自定义 yml 文件引用来映射值?
【发布时间】:2021-11-18 16:20:44
【问题描述】:

我正在开发一个 Spring Boot 项目,其中 Mapstruct 用于将传入的 JSON 转换为对象。 JSON 包含地址信息,如 cityCode、stateCode。代码到名称的映射保存在自定义 address.yml 文件中。 (为了在 springboot 项目中配置自定义 yml,我引用了这个 link 并且能够从 @Service 层类中的 AddressProperties 获取数据。)

我需要使用 JSON 中的 cityCode 来自 yml 的城市名称,同时将传入的 JSON 映射到 Address 对象。 为此创建了一个 Mapper - AddressMapper。

这是课程-

@Mapper(componentModel = "spring",  unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class AddressMapper {

    @Autowired
    AddressProperties addressProperties;

    @Mappings({@Mapping(target = "cityName", expression = "java(addressProperties.getCity().get(address.getCityCode()))")})
    abstract Address codeToName(AddressDTO address);
}

另一种方法-

@Mapper(componentModel = "spring",  unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class AddressMapper {

    @Autowired
    AddressProperties addressProperties;
    
    abstract Address codeToName(AddressDTO address);

    @AfterMapping
    public void populateNames(@MappingTarget Address address, AddressDTO addressDTO){
        address.setCityName(addressProperties.getCity().get(addressDTO.getCityCode()));
    }
}

但是,对于这两种方法,我都收到了NullPointerExceptionAddressProperties 在这两种情况下都为空。

有没有办法在 Mapstruct 或 Spring boot 中映射和设置自定义 yml 文件中的字段值?

这是 AddressProperties.java 文件,它指向 'address.yml' 并加载值:

@Data
@Builder
@Configuration
@ConfigurationProperties
@PropertySource(value = "classpath:address.yml", factory = YamlPropertySourceFactory.class)
public class AddressProperties {

    @Value("${city}")
    private Map<String, String> city;

}

这里 YamlPropertySourceFactory 引用自 Baeldung 的 this 文章。

地址.yml

city:
  101: AL
  102: AK
  103: AZ
  104: AR

【问题讨论】:

  • "AddressProperties 在这两种情况下都为空。" -> 向我们展示您在哪里“声明”/如何加载! ;)
  • 我可以得到addressproperties ref,但“城市”地图为空。
  • 请同时显示 yaml 的(大纲/结构)。

标签: java spring-boot nullpointerexception yaml mapstruct


【解决方案1】:

我尝试使用自动装配属性文件

@Mapper(componentModel = "spring",  unmappedTargetPolicy = ReportingPolicy.IGNORE)

但对象仍然为空。

通过在@Context 中传递属性对象并像这样调用映射器来尝试另一种方法 -

AddressMapper.INSTANCE.populateNames(AddressProperty property)

我仍然想知道为什么使用 componentmodel="spring" 没有提供解决方案。

【讨论】:

    猜你喜欢
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2021-02-24
    • 2019-01-04
    • 2018-08-05
    • 1970-01-01
    • 2015-04-04
    相关资源
    最近更新 更多