在 org.springframework.amqp.core.Message class 中使用 HttpHeader

Using HttpHeaders in org.springframework.amqp.core.Message class

我正在尝试将传入的 HttpHeader 保存在 org.springframework.amqp.core.Message 中,以便稍后从 queue 和 cleanly 中提取消息,并在 RestTemplate 中用作 HttpHeader。它对我来说似乎不太干净。

我在 spring 休息控制器中有一个 @PostMapping,它采用这样的入站 HttpHeader:

@PostMapping
public ResponseEntity<String> inbound(@PathVariable String flow, @RequestHeader HttpHeaders headers, @RequestBody byte[] payload) {

然后在 org.springframework.amqp.core.Message 中调用 createMessage(下方)方法以将 HttpHeader 存储在 Message 中。

像我这样从 org.springframework.amqp.core.Message 中检索 headers 似乎不太干净,因为:

有谁知道将 headers 从 Message 中拉出并将它们添加到 HttpHeaders object 的更简洁的方法?我所拥有的似乎相当假设和笨拙,因为我不想:

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.http.HttpHeaders;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;

@Component
public class MessageHelper {

    public Message createMessage(HttpHeaders httpHeaders, byte[] payload) {
        Map<String, Object> headers = new HashMap<>();
        headers.putAll(httpHeaders);

        return MessageBuilder
                .withBody(payload)
                .copyHeaders(new MessageHeaders(headers))
                .setContentType(httpHeaders.getContentType().toString())
                .setContentEncoding(StandardCharsets.UTF_8.displayName()).build();
    }

    public HttpHeaders getHeaders(Message message) {
        HttpHeaders httpHeaders = new HttpHeaders();
        Map<String, Object> headers = message.getMessageProperties().getHeaders();
        for (Map.Entry<String, Object> header : headers.entrySet()) {
            String value = header.getValue().toString().replace("]", "").replace("[", "");
            httpHeaders.addIfAbsent(header.getKey(), value);
        }

        return httpHeaders;
    }
}

注意:我没有使用 spring-integrations,它似乎有其他选项,例如 MessageHeaderAccessor 或 spring-messaging,它似乎有 MessageHeaders - 但我会遗漏什么?

请参阅此处 https://github.com/spring-projects/spring-amqp/blob/main/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/support/DefaultMessagePropertiesConverter.java#L176-L223,了解 Spring 在写入 AMQP 时如何映射任意 header。

如果 header 值不是 AMQP 支持的类型之一,则会对其执行简单的 toString() 操作(因此 [...],如果它类似于Set).

支持的类型:

        boolean valid = (value instanceof String) || (value instanceof byte[])
                || (value instanceof Boolean) || (value instanceof Class)
                || (value instanceof LongString) || (value instanceof Integer) || (value instanceof Long)
                || (value instanceof Float) || (value instanceof Double) || (value instanceof BigDecimal)
                || (value instanceof Short) || (value instanceof Byte) || (value instanceof Date)
                || (value instanceof List) || (value instanceof Map) || (value instanceof Object[]);

对于容器类型(数组、列表),递归调用该方法。

一个解决方案可能是将 header 序列化为单个 byte[] header.