Spring 引导接管 web.xml 配置

Spring Boot take over web.xml configuration

我有一个 Spring 启动 Web 应用程序,运行良好。现在我得到了一个我必须在项目中使用的第三方库。集成 lib 的手册是针对现有的 web.xml 文件编写的。我的项目完全依赖于基于 Java 的配置。

根据 Spring 文档,我可以在 WebApplicationInitializer.

的帮助下实现将 web.xml 内容接管到我的应用程序中的目标

我就是这么做的(至少我认为我做对了)。 在进入更多细节之前,这里是 web.xml:

<servlet>
   <servlet-name>LoginServlet</servlet-name>
   <servlet-class>some.package.path.LoginServlet</servlet-class>
</servlet>
<servlet>
   <servlet-name>LogoutServlet</servlet-name>
   <servlet-class>some.package.path.LogoutServlet</servlet-class>
</servlet>
<servlet>
   <servlet-name>ResultServlet</servlet-name>
   <servlet-class>some.package.path.ResultServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>LoginServlet</servlet-name>
   <url-pattern>/saml/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>LogoutServlet</servlet-name>
   <url-pattern>/saml/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>ResultServlet</servlet-name>
   <url-pattern>/saml/result</url-pattern>
</servlet-mapping>
<env-entry>
   <env-entry-name>some.package.path.config-file</env-entry-name>
   <env-entry-type>java.lang.String</env-entry-type>
   <env-entry-value>$HOME/.libName/libName-config.xml</env-entry-value>
</env-entry>

下面是我在 Java 配置中重构它的方式:

public class WebAppInitializer implements WebApplicationInitializer {

    private static final Logger LOG = Logger.getLogger(WebAppInitializer.class.getSimpleName());

    @Override
    public void onStartup(ServletContext servletContext) {
        final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.scan("de.davidartmann.myapp.configuration");

        final ServletRegistration.Dynamic dispatcher =
            servletContext.addServlet("dispatcher", new DispatcherServlet(context));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        final ServletRegistration.Dynamic loginServlet =
            servletContext.addServlet("LoginServlet", LoginServlet.class);
        loginServlet.addMapping("/saml/login");

        final ServletRegistration.Dynamic logoutServlet =
            servletContext.addServlet("LogoutServlet", LogoutServlet.class);
        logoutServlet.addMapping("/saml/logout");

        final ServletRegistration.Dynamic resultServlet =
            servletContext.addServlet("ResultServlet", ResultServlet.class);
        resultServlet.addMapping("/saml/result");

        try {
            final InitialContext initialContext = new InitialContext();
            initialContext.addToEnvironment("some.package.path.config-file",
                "$HOME/.libName/libName-config.xml");
        } catch (NamingException e) {
            LOG.log(Level.SEVERE, "Could not initialize an InitialContext", e);
        }
    }
}

问题是第 3 方库使用此设置抛出内部 NPE。 NPE 在 @Injects(基于 CDI)web.xml 中 <env-entry> 的运行时对象的位置抛出,我在我的 WebAppInitializer [中将其实现为 InitialContext class.

我的 Spring 引导应用程序使用 SpringBootServletInitializer。关于 Traditional Deployment 的 Spring 文档提到了它:

Normally, all the code from an existing WebApplicationInitializer can be moved into a SpringBootServletInitializer

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(MyApplication.class);
    }
}

现在,我不确定该怎么办?我的 WebApplicationInitializer 实现是否正确,或者我是否需要在我的 Spring Boot main class 中使用 SpringBootServletInitializer

感谢您的帮助。 大卫

问题是,用于部署应用程序的 Tomcat 服务器没有提供依赖注入 (CDI) 的实现。我不得不更改为提供必要实现的 Wildfly。