How to register the Spring MVC dispatcher servlet with an embedded tomcat without spring-boot?

1.5k views Asked by At

My question is similar to this one Embedded Tomcat Integrated With Spring. I want to run a Spring MVC Dispatcher Servlet on an embedded Tomcat. But I always end up with an exception saying that the WebApplicationObjectSupport instance does not run within a ServletContext. My example has just the two classes:

 class Application {
    public static void main(String[] args) throws LifecycleException, ServletException {
        try (AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext()) {
            context.registerShutdownHook();
            context.register(WebConfig.class);
            context.refresh();
            Tomcat tomcat = new Tomcat();
            tomcat.setPort(9090);
            File base = new File("");
            System.out.println(base.getAbsolutePath());
            Context rootCtx = tomcat.addWebapp("", base.getAbsolutePath());
            DispatcherServlet dispatcher = new DispatcherServlet(context);
            Tomcat.addServlet(rootCtx, "SpringMVC", dispatcher);
            rootCtx.addServletMapping("/*", "SpringMVC");
            tomcat.start();
            tomcat.getServer().await();
        }
    }
}


@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/assets/");
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:index.html");
    }
}

How do I have to define the servlet context differently then by calling the tomcat.addWebApp(..) method? Does anybody have an example how the Spring MVC dispatcher can be used with an embedded tomcat but without boot?

1

There are 1 answers

0
Igor On

You can create a ServletContextInitializer and sneak it in via @Configuration:

@Configuration
class WebAppInitConfig implements ServletContextInitializer {
    @Override
    void onStartup(ServletContext context) {
        AnnotationConfigWebApplicationContext webAppContext = new AnnotationConfigWebApplicationContext()
        webAppContext.register(RootConfig)
        webAppContext.registerShutdownHook()

        ServletRegistration.Dynamic dispatcher = context.addServlet("dispatcher", new DispatcherServlet(webAppContext))
        dispatcher.loadOnStartup = 1
        dispatcher.addMapping("/*")
        // Whatever else you need
    }
}