Apache Camel Mapstruct 集成

huangapple go评论72阅读模式
英文:

Apache Camel Mapstruct integration

问题

在我的Springboot Camel微服务中,我使用以下依赖集成了Camel MapStruct:

<camel.version>3.20.1</camel.version>
<mapstruct.version>1.5.3.Final</mapstruct.version>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-spring-boot-starter</artifactId>
    <version>${camel.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-mapstruct-starter</artifactId>
    <version>${camel.version}</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${mapstruct.version}</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>${mapstruct.version}</version>
    <scope>provided</scope>
</dependency>

我还有一个类似以下的映射器:

@Mapper(componentModel = "spring")
public interface CamelTestMapper {

    @BeanMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
    CamelTestDto mapCamelTestEntity(CamelTestEntity camelTestEntity);

}

以及一个路由如下:

from("direct:get-by-id")
                .routeId("db-get-by-id-route")
                .transacted()
                .process(camelTestSampleDatabaseProcessor)
                .log(LoggingLevel.INFO, "Retrieved entity from db with name: ${body.name}")
                .to("mapstruct:org.example.model.dto.CamelTestDto")
                .log(LoggingLevel.INFO, "Mapped new Dto: ${body}");

你遇到问题的地方是使用 .convertBodyTo(CamelTestDto.class) 时抛出异常。异常信息是由于Camel无法找到合适的类型转换器。这是因为使用 .convertBodyTo 时,Camel 试图将消息体从 org.example.model.entity.CamelTestEntity 转换为 org.example.model.dto.CamelTestDto,但没有可用的类型转换器。

在你的场景中,你应该继续使用 to("mapstruct:org.example.model.dto.CamelTestDto") 来调用 MapStruct 映射器,这是正确的方式来执行映射。确保你的映射器配置正确,这样它将自动处理实体到 DTO 的映射。

你已经在应用的 application.yml 中进行了正确的配置:

camel:
  component:
    mapstruct:
      mapper-package-name: org.example.mapper

这将确保 Camel MapStruct 组件可以找到你的映射器。

至于列表的转换,你可以创建一个映射器方法,用于将实体列表映射为 DTO 列表,例如:

List<CamelTestDto> mapCamelTestEntities(List<CamelTestEntity> camelTestEntities);

然后在你的路由中使用这个方法来进行列表的映射。如果你有其他问题或需要更多示例,请随时提出。

英文:

In my Springboot Camel microservice I integrate camel mapstruct with this dependency:

&lt;camel.version&gt;3.20.1&lt;/camel.version&gt;
&lt;mapstruct.version&gt;1.5.3.Final&lt;/mapstruct.version&gt;

&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.apache.camel.springboot&lt;/groupId&gt;
    &lt;artifactId&gt;camel-spring-boot-starter&lt;/artifactId&gt;
    &lt;version&gt;${camel.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.apache.camel.springboot&lt;/groupId&gt;
    &lt;artifactId&gt;camel-mapstruct-starter&lt;/artifactId&gt;
    &lt;version&gt;${camel.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
    &lt;artifactId&gt;mapstruct&lt;/artifactId&gt;
    &lt;version&gt;${mapstruct.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
    &lt;artifactId&gt;mapstruct-processor&lt;/artifactId&gt;
    &lt;version&gt;${mapstruct.version}&lt;/version&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
&lt;/dependency&gt;

I also have a mapper like this:

@Mapper(componentModel = &quot;spring&quot;)
public interface CamelTestMapper {

    @BeanMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
    CamelTestDto mapCamelTestEntity(CamelTestEntity camelTestEntity);

}

and a route like this:

from(&quot;direct:get-by-id&quot;)
                .routeId(&quot;db-get-by-id-route&quot;)
                .transacted()
                .process(camelTestSampleDatabaseProcessor)
                .log(LoggingLevel.INFO, &quot;Retrieved entity from db with name: ${body.name}&quot;)
                .to(&quot;mapstruct:org.example.model.dto.CamelTestDto&quot;)
                .log(LoggingLevel.INFO, &quot;Mapped new Dto: ${body}&quot;);

I can't understand why in this way it works, and when I use

.convertBodyTo(CamelTestDto.class)

it throw this exception:

org.apache.camel.InvalidPayloadException: No body available of type: org.example.model.dto.CamelTestDto but has type: org.example.model.entity.CamelTestEntity on: Message[4939598FD4DFE7C-0000000000000103]. 
    Caused by: No type converter available to convert from type: org.example.model.entity.CamelTestEntity to the required type: org.example.model.dto.CamelTestDto. Exchange[4939598FD4DFE7C-0000000000000103]. 
    Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: org.example.model.entity.CamelTestEntity to the required type: org.example.model.dto.CamelTestDto]

Obviously I already set the application .yml in this way:

camel:
  component:
    mapstruct:
      mapper-package-name: org.example.mapper

Does anyone know how to solve it? Can you give to me some examples of how to use this integrations? Also with conversion with List please.

答案1

得分: 1

近期camel-mapstruct-starter针对SB出现了一个bug,当您在路由中没有使用mapstruct作为组件时,它无法正确地自动配置自身。

这将在即将发布的Camel版本中修复:
https://issues.apache.org/jira/browse/CAMEL-19181

英文:

There was a recent bug in camel-mapstruct-starter for SB that it did not auto-configure itself correctly, when you did not use mapstruct as a component in the routes.

This will be fixed in upcoming Camel releases:
https://issues.apache.org/jira/browse/CAMEL-19181

答案2

得分: 0

I have not tried this, but I'm guessing Camel wants a bean annotated as a typeconverter to use for the .convertBodyTo directive.

Since the actual converter is a generated class I'm not sure how you would do that... maybe there's a way to define it in an XML file Camel reads.

英文:

I have not tried this, but I'm guessing Camel wants a bean annotated as a typeconverter to use for the .convertBodyTo directive.

Since the actual converter is a generated class I'm not sure how you would do that... maybe there's a way to define it in an XML file Camel reads.

huangapple
  • 本文由 发表于 2023年2月8日 20:16:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385663.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定