spring - 在 Camel Marshal 和 Unmarshal 标签中使用 Spring 表达式语言

标签 spring apache-camel protocol-buffers spring-el

我尝试过搜索此信息,但未能找到。我对 Camel(和 Java)比较陌生,所以如果我忽略了一些简单的事情,请原谅我。请记住,这只是示例代码,因此可能有点脆弱。

真正的问题可以在 Java 输出(一直在底部)的以下行中找到:

org.quartz.JobExecutionException: java.lang.ClassNotFoundException: #{${header.ProtobufType}} [See nested exception: java.lang.ClassNotFoundException: #{${header.ProtobufType}}]

我想(在运行时)决定在编码或解码消息时使用哪个实例类。我认为使用 Spring 表达式语言是可行的方法,但无法找到适合我要查找的内容的 Google 查询。我的 Spring 应用程序上下文如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <bean id="toBean" class="To.ToBean" />

    <bean id="fromBean" class="From.FromBean" />

    <bean id="addTypeProcessor" class="Processor.AddTypeProcessor" />

    <camel:errorHandler id="camelErrorHandler" type="NoErrorHandler" />

    <camelContext id="camelContext" errorHandlerRef="camelErrorHandler" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="quartz://myTimer?trigger.repeatCount=-1&amp;trigger.repeatInterval=5000" />
            <to uri="bean:fromBean" />
            <process ref="addTypeProcessor" />
            <marshal>
                <protobuf instanceClass="#{${header.ProtobufType}}" />
            </marshal>
            <unmarshal>
                <protobuf instanceClass="#{${header.ProtobufType}}" />
            </unmarshal>
            <to uri="bean:toBean" />
            <process ref="addTypeProcessor" />
        </route>
    </camelContext>

</beans>

我的 AddTypeProcessor 看起来像这样:

package Processor;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class AddTypeProcessor implements Processor {

    @Override
    public void process(Exchange exchange) throws Exception {
        String headerName = "ProtobufType";
        String headerValue = (String) exchange.getIn().getHeader(headerName);
        System.out.println(headerName + " was " + headerValue);
        exchange.getIn().setHeader(headerName, exchange.getIn().getBody().getClass().getCanonicalName());
        headerValue = (String) exchange.getIn().getHeader(headerName);
        System.out.println(headerName + " is " + headerValue);
    }

}

我的输出如下:

0    [main] INFO  org.springframework.context.support.ClassPathXmlApplicationContext  - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@63c5ab93: startup date [Fri Jun 28 16:33:17 EDT 2013]; root of context hierarchy
46   [main] INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader  - Loading XML bean definitions from class path resource [applicationContext.xml]
1081 [main] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory  - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7cb01f72: defining beans [toBean,fromBean,addTypeProcessor,camelErrorHandler,template,consumerTemplate,camelContext:beanPostProcessor,camelContext]; root of factory hierarchy
1285 [main] INFO  org.apache.camel.spring.SpringCamelContext  - Apache Camel 2.10.1 (CamelContext: camelContext) is starting
1356 [main] INFO  org.apache.camel.management.ManagementStrategyFactory  - JMX enabled.
1521 [main] INFO  org.apache.camel.impl.converter.DefaultTypeConverter  - Loaded 175 type converters
1633 [main] INFO  org.quartz.simpl.SimpleThreadPool  - Job execution threads will use class loader of thread: main
1645 [main] INFO  org.quartz.core.SchedulerSignalerImpl  - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
1645 [main] INFO  org.quartz.core.QuartzScheduler  - Quartz Scheduler v.1.8.5 created.
1646 [main] INFO  org.quartz.simpl.RAMJobStore  - RAMJobStore initialized.
1647 [main] INFO  org.quartz.core.QuartzScheduler  - Scheduler meta-data: Quartz Scheduler (v1.8.5) 'DefaultQuartzScheduler-camelContext' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

1647 [main] INFO  org.quartz.impl.StdSchedulerFactory  - Quartz scheduler 'DefaultQuartzScheduler-camelContext' initialized from an externally provided properties instance.
1647 [main] INFO  org.quartz.impl.StdSchedulerFactory  - Quartz scheduler version: 1.8.5
1812 [main] INFO  org.apache.camel.spring.SpringCamelContext  - Route: route1 started and consuming from: Endpoint[quartz://myTimer?trigger.repeatCount=-1&trigger.repeatInterval=5000]
1812 [main] INFO  org.apache.camel.management.DefaultManagementLifecycleStrategy  - StatisticsLevel at All so enabling load performance statistics
1817 [main] INFO  org.apache.camel.component.quartz.QuartzComponent  - Starting Quartz scheduler: DefaultQuartzScheduler-camelContext
1817 [main] INFO  org.quartz.core.QuartzScheduler  - Scheduler DefaultQuartzScheduler-camelContext_$_NON_CLUSTERED started.
1819 [main] INFO  org.apache.camel.spring.SpringCamelContext  - Total 1 routes, of which 1 is started.
1822 [main] INFO  org.apache.camel.spring.SpringCamelContext  - Apache Camel 2.10.1 (CamelContext: camelContext) started in 0.535 seconds
ProtobufType was null
ProtobufType is WireFormatProtos.WireFormat.A
1848 [DefaultQuartzScheduler-camelContext_Worker-1] WARN  org.apache.camel.util.ObjectHelper  - Cannot find class: $header.ProtobufType
1849 [DefaultQuartzScheduler-camelContext_Worker-1] ERROR org.apache.camel.component.quartz.QuartzEndpoint  - Error processing exchange. Exchange[Message: ]. Caused by: [org.quartz.JobExecutionException - java.lang.ClassNotFoundException: #{${header.ProtobufType}}]
1850 [DefaultQuartzScheduler-camelContext_Worker-1] INFO  org.quartz.core.JobRunShell  - Job DEFAULT.quartz-endpoint1 threw a JobExecutionException: 
org.quartz.JobExecutionException: java.lang.ClassNotFoundException: #{${header.ProtobufType}} [See nested exception: java.lang.ClassNotFoundException: #{${header.ProtobufType}}]
    at org.apache.camel.component.quartz.QuartzEndpoint.onJobExecute(QuartzEndpoint.java:117)
    at org.apache.camel.component.quartz.CamelJob.execute(CamelJob.java:54)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
Caused by: java.lang.ClassNotFoundException: #{${header.ProtobufType}}
    at org.apache.camel.impl.DefaultClassResolver.resolveMandatoryClass(DefaultClassResolver.java:52)
    at org.apache.camel.dataformat.protobuf.ProtobufDataFormat.loadDefaultInstance(ProtobufDataFormat.java:79)
    at org.apache.camel.dataformat.protobuf.ProtobufDataFormat.getInstance(ProtobufDataFormat.java:67)
    at org.apache.camel.dataformat.protobuf.ProtobufDataFormat.unmarshal(ProtobufDataFormat.java:109)
    at org.apache.camel.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:57)
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:91)
    at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:45)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.processor.interceptor.DefaultChannel.process(DefaultChannel.java:303)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:117)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
    at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:45)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.processor.UnitOfWorkProcessor.processAsync(UnitOfWorkProcessor.java:150)
    at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:117)
    at org.apache.camel.processor.RouteInflightRepositoryProcessor.processNext(RouteInflightRepositoryProcessor.java:48)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
    at org.apache.camel.processor.loadbalancer.QueueLoadBalancer.process(QueueLoadBalancer.java:44)
    at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:99)
    at org.apache.camel.processor.loadbalancer.QueueLoadBalancer.process(QueueLoadBalancer.java:71)
    at org.apache.camel.component.quartz.QuartzEndpoint.onJobExecute(QuartzEndpoint.java:113)
    ... 3 more

最佳答案

这是不可能的。

相反,您可以使用处理器/bean,然后在 java 代码中创建编码器和解码器,并调用 marshal/unmarshal 方法。由于这是 Java 代码,因此您可以从 Camel 消息头中定义实例类的动态行为。

关于spring - 在 Camel Marshal 和 Unmarshal 标签中使用 Spring 表达式语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17373285/

相关文章:

dependency-injection - 当 "@PropertyInject"字段被注入(inject)时,想要检查注入(inject)的值

c++ - 如何正确使用生成的 protobuf 源?

spring - 如何获取存储在默认模式表中的租户标识符?

spring - 具有 Spring Security 和 Java Config 的自定义身份验证提供程序

java - SimpleJdbcTestUtils.executeScript 和多行脚本

documentation - 有没有办法在 protobuf (proto2) 中创建类型别名?

c++ - 使用 boost::asio::read_async 读取 Protobuf 对象

spring - 替换 AuthorizationRequest 后 HttpSession 为空

Apache Camel - 动态构建端点和端点

java - 连接两个 AWS EC2 实例以将数据从一个 EC2 实例共享到另一 EC2 实例