【问题标题】:How to get message headers in an interceptor in Spring-Integration如何在 Spring-Integration 的拦截器中获取消息头
【发布时间】:2020-09-23 07:56:17
【问题描述】:

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

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

谢谢。

下面是我的拦截器类。

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;
    }
}

【问题讨论】:

    标签: spring-integration spring-ws


    【解决方案1】:

    首先,请看一下消息历史记录和全局窃听日志通道适配器。通过这种方式,您将能够跟踪消息在您的流中传输的所有路径,包括标头和有效负载。

    查看文档了解更多信息:

    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 的拦截器中获取请求信息的另一种方法(也是唯一方法)是仅通过 ThreadLocal 变量。在调用ws:outbound-gateway 之前,您将该信息存储在一些共享的ThreadLocal 中,并从拦截器中的该变量中获取该信息。可能您知道 loggers 中的 MDC 或 Spring Security 中的 SecurityContextHolder 是什么。

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

    【讨论】:

    • 感谢您的回答。 MDC 解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多