Groovy @MapConstructor无法正确实例化子列表指定类型求助
解决Groovy @MapConstructor嵌套泛型集合实例化问题
问题根源
Groovy的@MapConstructor注解生成的构造器仅自动处理顶层属性赋值。对于泛型集合(比如List<UtilisateurLightDto>),它无法自动将集合内的Map元素转换为目标DTO类型,只会保留原始的List<Map>结构,导致collaborators类型不符合预期。
解决方案(无需自定义全量构造器)
方案1:自定义setter自动转换
在CollectionDto中为collaborators添加自定义setter,手动完成List<Map>到List<UtilisateurLightDto>的转换:
@MapConstructor class CollectionDto { long collection String libelle List<UtilisateurLightDto> collaborators = [] // 自定义setter处理类型转换 void setCollaborators(List<Map> collaborators) { this.collaborators = collaborators.collect { new UtilisateurLightDto(it) } } }
调用newInstance(payload)时,构造器会自动触发该setter,完成嵌套对象的转换。
方案2:手动预处理Payload
创建DTO前,先转换collaborators中的元素:
def payload = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY).parse(body, "UTF-8") // 将collaborators内的每个Map转为UtilisateurLightDto payload.collaborators = payload.collaborators.collect { new UtilisateurLightDto(it) } def dto = CollectionDto.newInstance(payload) as DTO
方案3:用Groovy类型转换替代newInstance
利用Groovy的类型转换能力,直接将payload转为CollectionDto,自动处理嵌套对象转换:
def payload = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY).parse(body, "UTF-8") def dto = payload as CollectionDto
方案4:直接解析为目标类型(Groovy 2.5+)
Groovy 2.5及以上版本可直接用parse方法指定目标类型,一步完成JSON到DTO的转换:
def dto = new JsonSlurper().parse(body, CollectionDto)
总结
无需自定义全量构造器,以上方案均可解决嵌套泛型集合的类型转换问题。优先推荐方案1(自定义setter),将类型转换逻辑封装在DTO内部,代码更简洁可维护。
内容的提问来源于stack exchange,提问作者Patrick Ferreira
相关产品推荐
相关产品推荐

