如何在 Spring-Integration 中的拦截器中获取消息 headers

How to get message headers in an interceptor in Spring-Integration

我正在使用 Spring-Integration 代理 SOAP Web 服务。我使用一些入站网关收到请求,经过一些转换后,消息传递 ws:outbound-gateway。我扩展了 ClientInterceptor 并定义了一个名为 WSLoggingInterceptor 的自定义记录 XML 请求和响应并将其添加到我的 ws:outbound-gateway.

我想在日志中添加一个标识符,以便在同一消息流中关联发送请求和接收响应的日志。我在消息流开始的集成 headers 中定义了一些名为 messageIdUUID。我的问题是如何在此类拦截器中获得集成消息的 messageId 或其他集成 headers?有什么办法吗?

谢谢。

下面是我的拦截器class。

package com.asansoft.interceptors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.context.MessageContext;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Mohammad Ghoreishi.
 * moha.gh22@gmail.com
 */

@Component(value = "wsLoggingInterceptor")
public class WSLoggingInterceptor implements ClientInterceptor {

    private final Logger requestLogger = LoggerFactory.getLogger("WSRequest");
    private final Logger responseLogger = LoggerFactory.getLogger("WSResponse");
    private final Logger errorLogger = LoggerFactory.getLogger("WSError");
    private List<String> exclusionRequestNSList = new ArrayList<>();
    private List<String> exclusionResponseNSList = new ArrayList<>();

    @Override
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            messageContext.getRequest().writeTo(byteArrayOutputStream);
            requestLogger.info("Web Service Request : " + removeRequestCredentials(removeSecurityHeaders(new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8))));
        } catch (IOException e) {
            errorLogger.error(e.getMessage(), e);
        }
        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            messageContext.getResponse().writeTo(byteArrayOutputStream);
            responseLogger.info("Web Service Response : " + removeResponseCredentials(removeSecurityHeaders(new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8))));
        } catch (IOException e) {
            errorLogger.error(e.getMessage(), e);
        }
        return true;
    }

    @Override
    public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
        try {
            long rs = (new Date()).getTime() - responseTime;
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            messageContext.getResponse().writeTo(byteArrayOutputStream);
            errorLogger.error("Web Service Response : " + removeResponseCredentials(removeSecurityHeaders(new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8))));
            errorLogger.error("Response Time : " + rs + "ms");
        } catch (IOException e) {
            errorLogger.error(e.getMessage(), e);
        }
        return true;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException {
        // Blah blah blah
    }


    private String removeSecurityHeaders(String xmlString) {
        // Blah blah blah
    }

    private String removeRequestCredentials(String xmlString) {
        // Blah blah blah
    }

    private String removeResponseCredentials(String xmlString) {
        // Blah blah blah
    }

    public List<String> getExclusionRequestNSList() {
        return exclusionRequestNSList;
    }

    public List<String> getExclusionResponseNSList() {
        return exclusionResponseNSList;
    }

    public void setExclusionRequestNSList(List<String> exclusionRequestNSList) {
        this.exclusionRequestNSList = exclusionRequestNSList;
    }

    public void setExclusionResponseNSList(List<String> exclusionResponseNSList) {
        this.exclusionResponseNSList = exclusionResponseNSList;
    }
}

首先,请查看消息历史记录和全局 wire-tap 日志通道适配器。通过这种方式,您将能够跟踪消息在您的流程中传播的所有路径,包括 headers 和有效负载。

有关详细信息,请参阅文档:

https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/system-management.html#message-history

https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/core.html#channel-wiretap

在 WS-specific 拦截器中获取请求信息的另一种方法(也是唯一的方法)是仅通过 ThreadLocal 变量。在调用 ws:outbound-gateway 之前将该信息存储在一些共享的 ThreadLocal 中,并从拦截器中的这个变量中获取该信息。您可能知道记录器中的 MDC 或 Spring 安全中的 SecurityContextHolder

您可能可以将自定义 header 映射到 SOAP 请求中,但从业务角度来看,将信息通过网络传送到 Web 服务显然不是什么好事...