【问题标题】:Spring: Logging outgoing HTTP requestsSpring:记录传出的 HTTP 请求
【发布时间】:2015-02-07 08:56:05
【问题描述】:

我正在尝试在基于 Spring 的 Web 应用程序中记录所有传出的 Http 请求。是否有为此目的的拦截器?我想在它离开应用程序之前记录所有传出的内容和标题。我正在使用 spring-ws 发送 SOAP 请求。所以基本上,我不仅要记录 SOAP 请求 xml(如这里提到的 How can I make Spring WebServices log all SOAP requests?),还要记录整个 http 请求。

【问题讨论】:

  • 你考虑过使用aop吗?

标签: java spring spring-ws


【解决方案1】:

WebServiceGatewaySupport 上使用ClientInterceptor 拦截请求/响应:

// soapClient extends WebServiceGatewaySupport
soapClient.setInterceptors(new ClientInterceptor[]{new ClientInterceptor() {
        @Override
        public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            try {
                messageContext.getRequest().writeTo(os);
            } catch (IOException e) {
                throw new WebServiceIOException(e.getMessage(), e);
            }

            String request = new String(os.toByteArray());
            logger.trace("Request Envelope: " + request);
            return true;
        }

        @Override
        public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            try {
                messageContext.getResponse().writeTo(os);
            } catch (IOException e) {
                throw new WebServiceIOException(e.getMessage(), e);
            }

            String response = new String(os.toByteArray());
            logger.trace("Response Envelope: " + response);
            return true;
        }
        ...

要获取标题,您还需要一个TransportOutputStream 的实例。 不幸的是,这个类是抽象的,所以你需要子类化。以下是它的外观:

class ByteArrayTransportOutputStream extends TransportOutputStream {

    private ByteArrayOutputStream outputStream;

    @Override
    public void addHeader(String name, String value) throws IOException {
        createOutputStream();
        String header = name + ": " + value + "\n";
        outputStream.write(header.getBytes());
    }

    public byte[] toByteArray() {
         return outputStream.toByteArray();
    }

    @Override
    protected OutputStream createOutputStream() throws IOException {
        if (outputStream == null) {
            outputStream = new ByteArrayOutputStream();
        }
        return outputStream;
    }
}

【讨论】:

  • 这个我已经试过了。它只记录 SOAP 请求 xml。不是 HTTP 请求以及 http 标头。
  • 您可以传递TransportOutputStream 而不是ByteArrayOutputStream。根据WebServiceMessage#writeTo的Javadoc:如果给定的流是{@link * org.springframework.ws.transport.TransportOutputStream}的实例,也会写入相应的头。
  • 这里如何获取TransportOutputStream的实例?
  • 您需要继承TransportOutputStream(没有可用的公共实现可供您使用)。
  • 我添加了一个您可以使用的示例实现。
猜你喜欢
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 2014-05-13
  • 2018-08-28
  • 2020-06-09
相关资源
最近更新 更多