Spring Boot 接管 web.xml 配置 [英] Spring Boot take over web.xml configuration

查看:98
本文介绍了Spring Boot 接管 web.xml 配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Spring Boot web application that works fine. Now I got a 3rd party lib which I must use in the project. The manual of integrating the lib is written with respect to an existing web.xml file. My project completely relies on a Java based config.

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

According to the Spring documentation I can reach my goal of taking over the web.xml content into my application with the help of a WebApplicationInitializer.

这就是我所做的(至少我认为我做得对).在详细介绍之前,这里是 web.xml:

That's what I did (at least I think I did it correctly). Before going into more details, here is the 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 配置中重构它的方式:

And here is how I refactored this in a Java config:

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 中 的运行时对象时被抛出作为我的 WebAppInitializer 类中的 InitialContext.

The problem is that the 3rd party lib throws an internal NPE with this setup. The NPE is thrown at the point where it @Injects (based on CDI) the runtime object of the <env-entry> in the web.xml which I implemented as InitialContext in my WebAppInitializer class.

我的 Spring Boot 应用程序使用 SpringBootServletInitializer.Spring 文档关于 传统部署 用以下文字提及它:

My Spring Boot application uses a SpringBootServletInitializer. The Spring documentation about Traditional Deployment mentions it with the words:

通常,来自现有 WebApplicationInitializer 的所有代码都可以移动到 SpringBootServletInitializer 中

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 主类中使用 SpringBootServletInitializer 吗?

Now, I am a unsure what to do? Is my implementation of WebApplicationInitializer correct or do I need to use the SpringBootServletInitializer in my Spring Boot main class?

感谢您的帮助.大卫

推荐答案

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

The problem was, that the Tomcat server which was used to deploy the application does not provide an implementation for the dependency injection (CDI). I had to change to Wildfly which provides the necessary implementation.

这篇关于Spring Boot 接管 web.xml 配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆