我在my-transformer
中添加了一些标题:
public Message<?> transform(final Message<?> message) {
List<Item> items = doStuff(message);
final MessageBuilder<?> messageBuilder = MessageBuilder
.withPayload(message.getPayload())
.copyHeadersIfAbsent(message.getHeaders());
for (final Item item : items) {
messageBuilder.setHeader(item.getHeaderName(), item.getValue());
}
return messageBuilder.build();
}
我写了一个集成测试来确认我的标题出现在输出通道上:
public static class HeaderTest extends TransformerTest {
@Test
public void test() throws Exception {
channels.input().send(new GenericMessage<>(TransformerTest.EXAMPLE_PAYLOAD));
final Message<?> out = this.collector.forChannel(this.channels.output()).poll(10, TimeUnit.SECONDS);
assertThat(out, HeaderMatcher.hasHeader("header-test", notNullValue()));
}
}
但是,当我创建一个像:
这样的流时http --port=1234 | my-transformer | log --expression=toString()
并发送了相同的EXAMPLE_PAYLOAD
我在log
日志中收到了以下消息:GenericMessage [payload=..., headers={kafka_offset=0, id=f0a0727c-9351-274c-58b3-edee9ccbf6ce, kafka_receivedPartitionId=0, contentType=text/plain;charset=UTF-8, kafka_receivedTopic=myTopic.my-transformer, timestamp=1485171448947}]
。
为什么我的邮件标题中没有header-test
?
- 编辑 -
所以,如果我理解正确,我应该做类似的事情:
public class MyTransformer implements Transformer {
private final EmbeddedHeadersMessageConverter converter = new EmbeddedHeadersMessageConverter();
@Override
public Message<?> transform(final Message<?> message) {
List<Item> items = doStuff(message);
final MessageBuilder<byte[]> messageBuilder = MessageBuilder
.withPayload(((String) message.getPayload()).getBytes())
.copyHeadersIfAbsent(message.getHeaders());
final int itemsSize = items.size();
final String[] headerNames = new String[itemsSize];
for (int i = 0; i < itemsSize; i++) {
final Item item = items.get(i);
messageBuilder.setHeader(item.getHeaderName(), item.getValue());
headerNames[i] = item.getHeaderName();
}
final Message<byte[]> msg = messageBuilder.build();
final byte[] rawMessageWithEmbeddedHeaders;
try {
rawMessageWithEmbeddedHeaders = converter.embedHeaders(new MessageValues(msg), headerNames);
} catch (final Exception e) {
throw new HeaderEmbeddingException(String.format("Cannot embed headers from '%s' into message: %s", items, msg), e);
}
return new GenericMessage<>(rawMessageWithEmbeddedHeaders);
}
}
在spring.cloud.stream.bindings.output.producer.headerMode=raw
中设置application.properties
然后转换接收方的消息有效负载?或者我可以以某种方式使接收方自动转换消息有效负载?
答案 0 :(得分:1)
您不会说您是使用Spring XD还是Spring Cloud DataFlow,但解决方案在每种情况下都类似。
由于kafka没有标头的原生支持,我们必须将它们嵌入到消息有效负载中。由于我们不想传输不必要的标头,因此您必须通过在{X}的servers.yml
或application.yml
(或{{1}中设置标头名称来选择要传输的标头对于Spring Cloud Stream应用程序。
修改强>
不幸的是,没有对模式的支持。一种选择是自己使用.properties
,并将kafka EmbeddedHeadersMessageConverter
设置为raw(在变换器的输出目标上)。原始模式意味着活页夹不会嵌入标题。
这样,下一个应用程序(没有模式mode
)应该能够解码标题,就像它们已经被变换器中的活页夹编码一样。 Javadocs here
您只能使用255个标题。