Spring Boot接管web.xml配置

时间:2018-03-05 07:26:07

标签: java spring spring-boot web.xml spring-java-config

我有一个可以正常运行的Spring Boot 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);
        }
    }
}

问题是第三方lib会使用此设置抛出内部NPE。 NPE在它@Inject(基于CDI)的时候抛出了web.xml中<env-entry>的运行时对象,我在WebAppInitializer类中实现为InitialContext。< / p>

我的Spring Boot应用程序使用SpringBootServletInitializer。关于Traditional Deployment的Spring文档提到了这个词:

  

通常,现有WebApplicationInitializer中的所有代码都可以移动到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主类中使用SpringBootServletInitializer

感谢您的帮助。 大卫

1 个答案:

答案 0 :(得分:0)

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