You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ModelMapper映射对象并定义缺失/空属性的处理策略?

问题描述

我通过POST请求在其他微服务创建资源后,需要用PUT请求更新该资源——PUT端点要求必须发送资源的所有属性,哪怕属性值为空也不能省略。但通过GET请求获取资源时,空列表类型的impacts字段因为值为空没有返回,导致本地对象中该字段为null。现在需要用ModelMapper实现:将从GET获取的对象映射到用于PUT请求的目标对象时,所有字符串类型的未知值(null)填充为空字符串,所有列表类型的未知值填充为空列表,确保序列化时不会因为null省略属性。

实体类定义

public class Incident {
    private String assignee; // 注:原代码拼写错误为asignee,此处修正为与JSON字段一致的assignee
    private List<String> impacts;
    private String startDate;
    private String endDate;
    private String description;
    private String summary;

    // 省略getter、setter、无参/全参构造方法
}

GET请求返回的JSON

{
    "assignee": "xpto",
    "startDate": "01-01-2020",
    "endDate": "02-01-2020",
    "description": "test",
    "summary": "summary test"
}
解决方案

要实现这个需求,我们需要给ModelMapper配置自定义类型转换器,并调整映射策略,确保所有null值都被替换为对应类型的空值。

1. 编写自定义类型转换器

针对字符串和列表类型,分别实现转换器,把null值转换成空字符串或空列表:

字符串转换器

Converter<Object, String> stringNullConverter = context -> {
    Object source = context.getSource();
    return source == null ? "" : source.toString();
};

列表转换器

Converter<Object, List<?>> listNullConverter = context -> {
    Object source = context.getSource();
    return source == null ? new ArrayList<>() : (List<?>) source;
};

2. 配置ModelMapper

将转换器注册到ModelMapper,并设置严格匹配策略,确保所有属性都被处理:

ModelMapper modelMapper = new ModelMapper();

// 注册转换器
modelMapper.addConverter(stringNullConverter);
modelMapper.addConverter(listNullConverter);

// 开启严格匹配,保证所有属性都被映射
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
// 允许访问私有字段,确保实体类的私有属性能被正确映射
modelMapper.getConfiguration().setFieldMatchingEnabled(true);
modelMapper.getConfiguration().setFieldAccessLevel(AccessLevel.PRIVATE);

3. 执行映射

假设从GET请求反序列化得到的对象是sourceIncident(其中impacts为null),直接用ModelMapper映射到新对象即可:

Incident sourceIncident = // 从GET接口获取并反序列化的对象
Incident targetIncident = modelMapper.map(sourceIncident, Incident.class);

// 验证结果:
// targetIncident.getImpacts() 会是 empty ArrayList
// 所有字符串属性如果为null,都会被设置为""

4. 确保序列化时包含空值

最后要保证Jackson序列化时不会省略空值属性,有两种配置方式:

实体类级别配置

在Incident类上添加Jackson注解:

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.ALWAYS)
public class Incident {
    // ... 属性定义
}

全局配置(Spring环境)

如果是Spring项目,可以在配置类中全局设置:

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 强制序列化所有属性,包括空值
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        return objectMapper;
    }
}

这样最终生成的JSON会包含所有属性,哪怕是空字符串或空列表,完全符合PUT端点的要求。

内容的提问来源于stack exchange,提问作者emanoellucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:27:28