当前位置: 首页 > 知识库问答 >
问题:

Spring Boot:在使用嵌入式Jetty服务器时记录所有传入的HTTP请求?

毛宏达
2023-03-14

我正在使用Spring Boot 1.1.5构建一个web应用程序。我已经按照相关Spring Boot文档中的描述配置了一个嵌入式Jetty。

我想记录所有传入的HTTP请求,我能想到的唯一解决方案(在读了Spring Boot文档中的“如何配置Jetty”之后)是引入EmbeddedServletContainerCustomizer:

package com.acme.rest;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;


/**
 * blah blah
 * 
 * @author Dimi
 */
@Component
public class EmbededJettyConfig implements EmbeddedServletContainerCustomizer {

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer # customize
     */
    @Override
    public void customize(final ConfigurableEmbeddedServletContainer container) {
        // checks whether the container is Jetty
        if (container instanceof JettyEmbeddedServletContainerFactory) {
            ((JettyEmbeddedServletContainerFactory) container)
                    .addServerCustomizers(jettyServerCustomizer());
        }
    }

    @Bean
    public JettyServerCustomizer jettyServerCustomizer() {

        return new JettyServerCustomizer() {

            /*
             * (non-Javadoc)
             * 
             * @see org.springframework.boot.context.embedded.jetty.JettyServerCustomizer #
             * customize
             */
            @Override
            public void customize(final Server server) {

                HandlerCollection handlers = new HandlerCollection();
                RequestLogHandler requestLogHandler = new RequestLogHandler();
                handlers.setHandlers(new Handler[] {new DefaultHandler(), requestLogHandler});
                server.setHandler(handlers);

                NCSARequestLog requestLog = new NCSARequestLog("logs/requests.log");
                requestLog.setExtended(false);
                requestLogHandler.setRequestLog(requestLog);
            }
        };
    }
}

应用程序现在无法开始引发异常:

java.lang.IllegalArgumentException:需要一个ServletContext来配置默认的servlet处理

简而言之:在Spring Boot中配置嵌入式Jetty日志记录的正确方法是什么?

共有3个答案

孟思远
2023-03-14

这不适用于Spring Boot版本1.1.9,因为JettyEmbeddedServletContainer处理程序仅适用于JettyEmbeddedWebAppContext(处理程序)或HandlerWrapper。我认为没有办法在Spring Boot中为嵌入式Jetty设置多个处理程序,因为这一点。

来自org的代码片段。springframework。靴子上下文嵌入的jettyJettyEmbeddedServletContainer。

@Override
public void start() throws EmbeddedServletContainerException {
    this.server.setConnectors(this.connectors);

    if (!this.autoStart) {
        return;
    }
    try {
        this.server.start();
        for (Handler handler : this.server.getHandlers()) {
            handleDeferredInitialize(handler);
        }
        Connector[] connectors = this.server.getConnectors();
        for (Connector connector : connectors) {
            connector.start();
            this.logger.info("Jetty started on port: " + getLocalPort(connector));
        }
    }
    catch (Exception ex) {
        throw new EmbeddedServletContainerException(
                "Unable to start embedded Jetty servlet container", ex);
    }
}

private void handleDeferredInitialize(Handler handler) throws Exception {
    if (handler instanceof JettyEmbeddedWebAppContext) {
        ((JettyEmbeddedWebAppContext) handler).deferredInitialize();
    }
    else if (handler instanceof HandlerWrapper) {
        handleDeferredInitialize(((HandlerWrapper) handler).getHandler());
    }
}
齐起运
2023-03-14

来得有点晚,但我遇到了同样的问题,解决方案是将已经由引导创建的ServletHandler包装在RequestLogHandler中,如下所示:

@Component
public class EmbededJettyConfig implements EmbeddedServletContainerCustomizer {

/*
 * (non-Javadoc)
 * 
 * @see org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer # customize
 */
@Override
public void customize(final ConfigurableEmbeddedServletContainer container) {
    // checks whether the container is Jetty
    if (container instanceof JettyEmbeddedServletContainerFactory) {
        ((JettyEmbeddedServletContainerFactory) container)
                .addServerCustomizers(jettyServerCustomizer());
    }
}

@Bean
public JettyServerCustomizer jettyServerCustomizer() {

    return new JettyServerCustomizer() {

        /*
         * (non-Javadoc)
         * 
         * @see org.springframework.boot.context.embedded.jetty.JettyServerCustomizer #
         * customize
         */
        @Override
        public void customize(final Server server) {
            NCSARequestLog requestLog = new NCSARequestLog("logs/requests.log");
            requestLog.setExtended(false);

            RequestLogHandler requestLogHandler = new RequestLogHandler();
            requestLogHandler.setRequestLog(requestLog);
            requestLogHandler.setHandler(server.getHandler());
            server.setHandler(requestLogHandler);
        }
    };
}
姬振
2023-03-14

Jetty 9.3.8在服务器上有一个新方法setRequestLog

@Component
public class EnableRequestLog implements EmbeddedServletContainerCustomizer {

    private static final JettyServerCustomizer USE_SLF4J_REQUEST_LOG =
            server -> server.setRequestLog(new Slf4jRequestLog());

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        if (container instanceof JettyEmbeddedServletContainerFactory) {
            ((JettyEmbeddedServletContainerFactory) container)
                    .addServerCustomizers(USE_SLF4J_REQUEST_LOG);
        } else {
            throw new IllegalArgumentException(
                    "Expected a Jetty container factory but encountered " + container.getClass());
        }
    }
}

您可以实现特定的RequestLog,而不是Jetty的Slf4jRequestLog。看见http://www.eclipse.org/jetty/documentation/current/configuring-jetty-request-logs.html

 类似资料:
  • 问题内容: 我正在编写一些示例代码,其中启动了嵌入式Jetty服务器。服务器必须仅加载一个servlet,将所有请求发送到servlet并在localhost:80上侦听 到目前为止,我的代码: 我可以用更少的代码/行做同样的事情吗?(使用Jetty 6.1.0)。 问题答案: 删除了不必要的空格,并内联移动了ServletHolder创建。删除了5行。

  • 问题内容: 我讨厌问这样一个模糊的问题,但是我很难找到一个简单的例子。这是我到目前为止的内容: 我可以找到的嵌入式Jetty示例始终显示如下内容,以启动运行的Server实例,但我不知道如何实例化WebSocketServlet。 如何创建可以处理WebSocket连接请求的嵌入式服务器? 问题答案: 更新:2013年12月2日 有关带有WebSocket的嵌入式码头的最新示例,请参见: http

  • 我制作了一个非常基本的web应用程序,它只有一个html页面。我把它当作战争输出。 现在我创建了一个嵌入式jetty服务器。 } 我为这个嵌入式服务器创建了一个jar。但是当我试图通过嵌入式服务器运行我的web应用程序时,我得到以下错误。 C:\users\user>Java-jar C:\users\user\desktop\jetty\webserver.jar null 我使用过jetty

  • 问题内容: 这是In go中的后续问题,如何检查写入http.ResponseWriter的http响应因为那里的解决方案需要伪造一个请求,所以对于单元测试非常有效,但不适用于实时服务器。 我想将我的Web服务响应于从用户收到的请求而返回的HTTP响应转储到日志文件(或控制台)中。输出应该告诉我标题是什么和JSON有效负载。 如何做到这一点? 如果有一个使用http.ResponseWriter作

  • 问题内容: 澄清: 这个问题是关于对基于JAX-WS的REST服务进行GZIP处理,但是我决定更改主题以使其更容易找到 我正在通过JAX-WS实现REST服务,并以标准方式发布它(原因是我想避免使用servlet容器或应用程序服务器)。 有办法让服务器gzip响应内容吗? 如何 实际提供的示例可以正常工作,它使您可以在没有servlet容器的嵌入式轻量级服务器上构建JAX-RS样式的服务器,但是需