【问题标题】:Apache CXF | JAX RS LoggingOutInterceptor - Access HttpServletRequest object阿帕奇 CXF | JAX RS LoggingOutInterceptor - 访问 HttpServletRequest 对象
【发布时间】:2015-09-03 07:07:52
【问题描述】:

伙计们,

我正在使用 Apache CXF (JAX-RS) 的 LoggingInInterceptorLoggingOutInterceptor 将请求和响应对象记录到我的 Web 服务并记录响应时间。 为此,我扩展了这两个类并在相应的 XML 文件中进行了相关配置。这样做,我能够记录请求和响应对象。 但是,我还想在这两个拦截器中记录请求 URL。我能够使用以下方法获取HttpServletRequest 对象(在LoggingInInterceptor 内):

HttpServletRequest request = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST);

然后,我可以从请求对象中获取请求 URL(在我的例子中为 REST URL)。但是,我无法使用此代码(或通过任何其他方式)在 LoggingOutInterceptor 中获取请求对象。

这里是问题的摘要:

我需要访问LoggingOutInterceptor 中的reqeuest URI(也许使用HttpServletRequest 对象?)。

不胜感激。

更新:添加拦截器代码。

public class StorefrontRestInboundInterceptor extends LoggingInInterceptor {

    /**
     * constructor.
     */
    public StorefrontRestInboundInterceptor() {
        super();
    }

    @Override
    public void handleMessage(final Message message) throws Fault {
        HttpServletRequest httpRequest = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
        if (isLoggingRequired()) {
            String requestUrl = (String) message.getExchange().get("requestUrl");
            Date requestTime = timeService.getCurrentTime();
            LOG.info("Performance Monitor started for session id:" + customerSession.getGuid());
            LOG.info(httpRequest.getRequestURI() + " Start time for SessionID " + customerSession.getGuid() + ": "
                + requestTime.toString());
        }
        try {
            InputStream inputStream = message.getContent(InputStream.class);
            CachedOutputStream outputStream = new CachedOutputStream();
            IOUtils.copy(inputStream, outputStream);
            outputStream.flush();
            message.setContent(InputStream.class, outputStream.getInputStream());
            LOG.info("Request object for " + httpRequest.getRequestURI() + " :" +  outputStream.getInputStream());
            inputStream.close();
            outputStream.close();
        } catch (Exception ex) {
            LOG.info("Error occured reading the input stream for " + httpRequest.getRequestURI());
        }
    }


public class StorefrontRestOutboundInterceptor extends LoggingOutInterceptor {

    /**
     * logger implementation.
     */
    protected static final Logger LOG = Logger.getLogger(StorefrontRestOutboundInterceptor.class);

    /**
     * constructor.
     */
    public StorefrontRestOutboundInterceptor() {
        super(Phase.PRE_STREAM);
    }

    @Override
    public void handleMessage(final Message message) throws Fault {
        if (isLoggingRequired()) {
            LOG.info(requestUrl + " End time for SessionID " + customerGuid + ": " + (timeService.getCurrentTime().getTime() - requestTime)
                    + " milliseconds taken.");
            LOG.info("Performance Monitor ends for session id:" + customerGuid);
        }
        OutputStream out = message.getContent(OutputStream.class);
        final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(out);
        message.setContent(OutputStream.class, newOut);
        newOut.registerCallback(new LoggingCallback(requestUrl));
    }

    public class LoggingCallback implements CachedOutputStreamCallback {

        private final String requestUrl;

        /**
         * 
         * @param requestUrl requestUrl.
         */
        public LoggingCallback(final String requestUrl) {
            this.requestUrl = requestUrl;
        }

        /**
         * @param cos CachedOutputStream.
         */
        public void onFlush(final CachedOutputStream cos) { //NOPMD

        }

        /**
         * @param cos CachedOutputStream.
         */
        public void onClose(final CachedOutputStream cos) {
            try {
                StringBuilder builder = new StringBuilder();
                cos.writeCacheTo(builder, limit);
                LOG.info("Request object for " + requestUrl + " :" + builder.toString());
            } catch (Exception e) {
                LOG.info("Error occured writing the response object for " + requestUrl);
            }
        }
    }

【问题讨论】:

  • 您无法使用message.get(Message.ENDPOINT_ADDRESS);message.get(Message.REQUEST_URI); 吗?我认为你应该是。
  • @Garry 是的,我试过这些。它们都解析为 null。

标签: apache web-services logging jax-rs cxf


【解决方案1】:

更新:由于您在 Out 链中,因此您可能需要从可以获取请求 URI 的位置获取 In 消息,因为请求 URI 可能为输出响应消息为空。

您可以尝试这样来获取传入消息:

Message incoming = message.getExchange().getInMessage();

那么我认为您应该能够使用以下方法获取请求 URI:

String requestURI = (String) incoming.get(Message.REQUEST_URI);

String endpointURI = (String) incoming.get(Message.ENDPOINT_ADDRESS);

如果这仍然不起作用,请尝试在 PRE_STREAM 阶段运行拦截器,如构造函数中的Phase.PRE_STREAM

您也可以尝试从拦截器链中获取消息,如下所示:

PhaseInterceptorChain chain = message.getInterceptorChain(); 
Message currentMessage = chain.getCurrentMessage();
HttpServletRequest req = (HttpServletRequest) currentMessage.get("HTTP.REQUEST");

【讨论】:

  • 在构造函数中添加 Phase.PRE_STREAM 没有帮助。同样使用 PhaseInterceptorChain 来获取 HttpSevletrequest 会产生空结果。
  • @va1b4av .. 将您的拦截器代码添加到问题中
  • 更新了原帖。
  • @va1b4av .. 请检查,我已经更新了答案。
  • @va1b4av .. 只是想知道...你能通过吗?
猜你喜欢
  • 1970-01-01
  • 2014-09-18
  • 2016-02-18
  • 2018-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多