Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring云数据流类型转换在处理器组件中不工作?_Java_Spring_Spring Integration_Spring Cloud Dataflow - Fatal编程技术网

Java Spring云数据流类型转换在处理器组件中不工作?

Java Spring云数据流类型转换在处理器组件中不工作?,java,spring,spring-integration,spring-cloud-dataflow,Java,Spring,Spring Integration,Spring Cloud Dataflow,我有一个处理器,可以将字节[]有效载荷转换为MyClass有效载荷: @Slf4j @EnableBinding(Processor.class) public class MyDecoder { @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) public MyClass decode(final byte[] payload) { MyCl

我有一个处理器,可以将
字节[]
有效载荷转换为
MyClass
有效载荷:

@Slf4j
@EnableBinding(Processor.class)
public class MyDecoder {

    @ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
    public MyClass decode(final byte[] payload) {
        MyClass decoded = doStuff(payload);
        if (decoded != null) {
            log.info("Successfully decoded!");
        }

        return decoded;
    }
}
我尝试创建以下DSL:
some source | my decoder | some sink
some sink
报告错误,因为类加载器中没有
MyClass
类。这是预期的行为

我尝试在我的解码器上应用类型转换,比如:
some source |我的解码器--spring.cloud.stream.bindings.output.contentType=application/json | some sink
,我在
我的解码器
日志中发现以下错误:

2017-01-20 21:45:17.278  INFO 9408 --- [afka-listener-2] com.example.MyDecoder  : Successfully decoded!
2017-01-20 21:45:18.441  INFO 9408 --- [afka-listener-2] com.example.MyDecoder  : Successfully decoded!
2017-01-20 21:45:20.512  INFO 9408 --- [afka-listener-2] com.example.MyDecoder  : Successfully decoded!
2017-01-20 21:45:20.515 ERROR 9408 --- [afka-listener-2] o.s.kafka.listener.LoggingErrorHandler   : Error while processing: ConsumerRecord(topic = example.some-source, partition = 0, offset = 1, key = null, value = [B@7dfad000)

org.springframework.messaging.MessageDeliveryException: failed to send Message to channel 'output'; nested exception is java.lang.IllegalArgumentException: payload must not be null
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:449) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.FixedSubscriberChannel.send(FixedSubscriberChannel.java:70) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.FixedSubscriberChannel.send(FixedSubscriberChannel.java:64) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105) ~[spring-messaging-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:171) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter.access$000(KafkaMessageDrivenChannelAdapter.java:47) ~[spring-integration-kafka-2.0.1.RELEASE.jar!/:na]
    at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter$IntegrationMessageListener.onMessage(KafkaMessageDrivenChannelAdapter.java:197) ~[spring-integration-kafka-2.0.1.RELEASE.jar!/:na]
    at org.springframework.kafka.listener.adapter.RetryingAcknowledgingMessageListenerAdapter$1.doWithRetry(RetryingAcknowledgingMessageListenerAdapter.java:76) ~[spring-kafka-1.0.4.RELEASE.jar!/:na]
    at org.springframework.kafka.listener.adapter.RetryingAcknowledgingMessageListenerAdapter$1.doWithRetry(RetryingAcknowledgingMessageListenerAdapter.java:71) ~[spring-kafka-1.0.4.RELEASE.jar!/:na]
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:276) ~[spring-retry-1.1.5.RELEASE.jar!/:na]
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:172) ~[spring-retry-1.1.5.RELEASE.jar!/:na]
    at org.springframework.kafka.listener.adapter.RetryingAcknowledgingMessageListenerAdapter.onMessage(RetryingAcknowledgingMessageListenerAdapter.java:71) ~[spring-kafka-1.0.4.RELEASE.jar!/:na]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:597) [spring-kafka-1.0.4.RELEASE.jar!/:na]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.access$1800(KafkaMessageListenerContainer.java:222) [spring-kafka-1.0.4.RELEASE.jar!/:na]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer$ListenerInvoker.run(KafkaMessageListenerContainer.java:778) [spring-kafka-1.0.4.RELEASE.jar!/:na]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_111]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_111]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
Caused by: java.lang.IllegalArgumentException: payload must not be null
    at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.3.5.RELEASE.jar!/:4.3.5.RELEASE]
    at org.springframework.integration.support.MutableMessage.<init>(MutableMessage.java:57) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.support.MutableMessage.<init>(MutableMessage.java:53) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.support.MutableMessageBuilder.withPayload(MutableMessageBuilder.java:86) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.support.MutableMessageBuilderFactory.withPayload(MutableMessageBuilderFactory.java:35) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.support.MutableMessageBuilderFactory.withPayload(MutableMessageBuilderFactory.java:26) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.cloud.stream.binding.MessageConverterConfigurer$ContentTypeConvertingInterceptor.preSend(MessageConverterConfigurer.java:194) ~[spring-cloud-stream-1.1.0.RELEASE.jar!/:1.1.0.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:538) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:415) ~[spring-integration-core-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
    ... 42 common frames omitted
我试着编写集成测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@DirtiesContext
public abstract class MyDecoderTests {

    @Autowired
    protected Processor channels;

    @Autowired
    protected MessageCollector collector;

    public static class UsingNothingIntegrationTests extends MyDecoderTest {

        @Test
        public void test() throws Exception {
            channels.input().send(new GenericMessage<Object>(Hex.decodeHex("ff".toCharArray())));
            assertThat(collector.forChannel(channels.output()), receivesPayloadThat(instanceOf(MyClass.class)));
        }
    }

    @SpringBootTest("spring.cloud.stream.bindings.output.contentType=application/json")
    public static class UsingOutputConverterIntegrationTests extends MyDecoderTest {

        @Test
        public void test() throws Exception {
            channels.input().send(new GenericMessage<Object>(Hex.decodeHex("ff".toCharArray())));
            assertThat(collector.forChannel(channels.output()), receivesPayloadThat(is("{\"example\": true\"}")));
        }
    }

    @Configuration
    @EnableAutoConfiguration
    @Import(MyDecoderConfiguration.class)
    public static class MyDecoderTestApplication {

    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.NONE)
@肮脏的环境
公共抽象类MyDecodeTests{
@自动连线
受保护的处理器通道;
@自动连线
受保护的消息收集器;
使用NothingIntegrationTests的公共静态类扩展了MyDecoderTest{
@试验
public void test()引发异常{
channels.input();
assertThat(collector.forChannel(channels.output()),receivesPayloadThat(instanceOf(MyClass.class));
}
}
@SpringBootTest(“spring.cloud.stream.bindings.output.contentType=application/json”)
使用OutputConverterIntegrationTests的公共静态类扩展了MyDecoderTest{
@试验
public void test()引发异常{
channels.input();
assertThat(collector.forChannel(channels.output()),receivesPayloadThat(即(“{\”示例\“:true\”));
}
}
@配置
@启用自动配置
@导入(MyDecoderConfiguration.class)
公共静态类MyDecoderTestApplication{
}
}
测试成功运行后,将进行转换

然后,我认为我的DSL不正确,所以我写了一个新的源代码来测试:

@Bean
@InboundChannelAdapter(Source.OUTPUT)
public MessageSource<MyClass> exampleSource() {
    return () -> new GenericMessage<>(getMyClassObject());
}
@Bean
@InboundChannelAdapter(Source.OUTPUT)
public MessageSource exampleSource(){
return()->new-GenericMessage(getMyClassObject());
}
下面的DSL按预期将MyClass转换为JSON:
mysource--spring.cloud.stream.bindings.output.contentType=application/JSON | some sink


为什么我收到关于解码的消息记录了3次,为什么它在“有效负载不得为空”消息中失败?这与我的处理器有关吗?

您看到了3次尝试,因为这是活页夹中输入通道的默认重试配置

活页夹中存在一个缺陷,即如果转换器无法转换消息,它会尝试创建一个负载为
null
的消息

它无法转换有效负载的原因是因为它看到了入站内容类型(可能是
应用程序/octet流
),并且无法从该类型转换为JSON

解决方法是将文件添加到类路径:

META-INF/spring.integration.properties

spring.integration.readOnly.headers=contentType
去吧

防止将入站内容类型标头传播到出站消息

这需要spring集成4.3.2或更高版本


在SCSt的未来版本中,这将默认设置。

我可以在哪里查看和更改绑定配置?因为kafka制作人在启动时报告了“retries=0”?另一件事,请您指出我在测试中犯了什么错误?UsingOutputConverterIntegrationTests为什么成功运行并将其转换为JSON?它已经成功了与kafka无关,这是消息传递后的内置功能,与binder实现无关;请参阅;特别是
maxAttempts
。测试工作的原因是您没有在测试发送的消息中设置
contentType
头。正如我所说的,这是一个bug;出站转换器正在使用inbound
contentType
header;如果您在测试中设置了该header,我希望您也会遇到同样的失败。感谢您的详细解释。对于未来的读者:我在Spring Cloud版本Dalston.SR2中观察到了这一点,建议的修复方案也有所帮助。
spring.integration.readOnly.headers=contentType