SpringBoot Camel集成MapStruct:convertBodyTo转换失败求助
问题原因
to("mapstruct:org.example.model.dto.CamelTestDto")是直接调用Camel MapStruct组件的原生处理逻辑,它会通过你配置的mapper-package-name扫描并调用对应的MapStruct Mapper实现完成转换。
而convertBodyTo(CamelTestDto.class)依赖的是Camel全局TypeConverter体系,默认情况下Camel MapStruct组件不会自动将你的MapStruct Mapper注册为全局TypeConverter,因此Camel找不到从CamelTestEntity到CamelTestDto的转换逻辑,抛出NoTypeConversionAvailableException异常。
解决方案
方式1:手动注册MapStruct Mapper为Camel TypeConverter
创建Spring配置类,将MapStruct Mapper包装成Camel TypeConverter并注册到全局转换器注册表:
import org.apache.camel.TypeConverter; import org.apache.camel.TypeConverterRegistry; import org.example.mapper.CamelTestMapper; import org.example.model.entity.CamelTestEntity; import org.example.model.dto.CamelTestDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; @Configuration public class CamelMapStructConverterConfig { @Autowired private TypeConverterRegistry typeConverterRegistry; @Autowired private CamelTestMapper camelTestMapper; @PostConstruct public void registerMapStructConverters() { // 注册Entity转Dto的转换器 typeConverterRegistry.addTypeConverter(CamelTestDto.class, CamelTestEntity.class, (type, value) -> type.cast(camelTestMapper.mapCamelTestEntity((CamelTestEntity) value)) ); // 可选:注册Dto转Entity的反向转换器(如果有对应Mapper方法) typeConverterRegistry.addTypeConverter(CamelTestEntity.class, CamelTestDto.class, (type, value) -> // 替换为你的反向映射方法 // type.cast(camelTestMapper.mapCamelTestDto((CamelTestDto) value)) null ); } }
注册完成后,convertBodyTo(CamelTestDto.class)即可正常触发MapStruct的转换逻辑。
方式2:继续使用MapStruct组件端点
如果不想额外注册转换器,直接保留to("mapstruct:org.example.model.dto.CamelTestDto")的写法即可,这是Camel MapStruct组件的原生用法,无需额外配置。
完整集成示例(包含List类型转换)
1. 扩展MapStruct Mapper添加List转换方法
MapStruct会自动生成批量转换的实现代码:
@Mapper(componentModel = "spring") public interface CamelTestMapper { @BeanMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) CamelTestDto mapCamelTestEntity(CamelTestEntity camelTestEntity); // 批量转换List类型 List<CamelTestDto> mapCamelTestEntityList(List<CamelTestEntity> camelTestEntityList); }
2. 路由中的List转换实现
方式A:使用MapStruct端点转换List
直接指定目标泛型类型的全限定名:
from("direct:get-all") .routeId("db-get-all-route") .transacted() .process(camelTestSampleListDatabaseProcessor) // 处理后返回List<CamelTestEntity> .log(LoggingLevel.INFO, "Retrieved ${body.size()} entities from database") // 指定List<Dto>的全限定类名作为转换目标 .to("mapstruct:java.util.List<org.example.model.dto.CamelTestDto>") .log(LoggingLevel.INFO, "Mapped ${body.size()} DTOs successfully");
方式B:使用全局TypeConverter转换List
如果已经注册了单个对象的TypeConverter,Camel会自动遍历集合完成批量转换,只需通过GenericType指定泛型类型:
from("direct:get-all") .routeId("db-get-all-route") .transacted() .process(camelTestSampleListDatabaseProcessor) .log(LoggingLevel.INFO, "Retrieved ${body.size()} entities from database") // 用GenericType明确泛型参数,避免类型擦除问题 .convertBodyTo(new GenericType<List<CamelTestDto>>(){}) .log(LoggingLevel.INFO, "Mapped ${body.size()} DTOs successfully");
额外注意事项
- 确保
application.yml中camel.component.mapstruct.mapper-package-name的配置路径正确,必须包含你的CamelTestMapper接口所在包。 - 确认
mapstruct-processor依赖的scope为provided,且编译时已成功生成Mapper的实现类(通常在target/generated-sources/annotations目录下),否则Spring无法注入Mapper实例。
内容的提问来源于stack exchange,提问作者Alexxxx

