How can I register a secondary servlet with Spring Boot?

JavaSpringSpring Boot

Java Problem Overview


I have an extra servlet I need to register in my application. However with Spring Boot and its Java Config, I can't just add servlet mappings in a web.xml file.

How can I add additional servlets?

Java Solutions


Solution 1 - Java

Also available is the ServletRegistrationBean

@Bean
public ServletRegistrationBean servletRegistrationBean(){
    return new ServletRegistrationBean(new FooServlet(),"/someOtherUrl/*");
}

Which ended up being the path I took.

Solution 2 - Java

Just add a bean for the servlet. It'll get mapped to /{beanName}/.

@Bean
public Servlet foo() {
    return new FooServlet();
}

Solution 3 - Java

You can register multiple different servlet with different ServletRegistrationBean like @Bean in Application class and you can register a servlet has multiple servlet mapping;

   @Bean
   public ServletRegistrationBean axisServletRegistrationBean() {
      ServletRegistrationBean registration = new ServletRegistrationBean(new AxisServlet(), "/services/*");
      registration.addUrlMappings("*.jws");
      return registration;
   }

   @Bean
   public ServletRegistrationBean adminServletRegistrationBean() {
      return new ServletRegistrationBean(new AdminServlet(), "/servlet/AdminServlet");
   }

Solution 4 - Java

We can also register the Servlet as follow way:

@Configuration
public class ConfigureWeb implements ServletContextInitializer, EmbeddedServletContainerCustomizer {

  @Override
  public void onStartup(ServletContext servletContext) throws ServletException {
      registerServlet(servletContext);
  }

  private void registerServlet(ServletContext servletContext) {
	  log.debug("register Servlet");
	  ServletRegistration.Dynamic serviceServlet = servletContext.addServlet("ServiceConnect", new ServiceServlet());
	
	  serviceServlet.addMapping("/api/ServiceConnect/*");
	  serviceServlet.setAsyncSupported(true);
	  serviceServlet.setLoadOnStartup(2);
  }
}

Solution 5 - Java

If you're using embedded server, you can annotate with @WebServlet your servlet class:

@WebServlet(urlPatterns = "/example")
public class ExampleServlet extends HttpServlet

From @WebServlet:

> Annotation used to declare a servlet. > > This annotation is processed by the container at deployment time, and > the corresponding servlet made available at the specified URL > patterns.

And enable @ServletComponentScan on a base class:

@ServletComponentScan
@EntityScan(basePackageClasses = { ExampleApp.class, Jsr310JpaConverters.class })
@SpringBootApplication
public class ExampleApp 

Please note that @ServletComponentScan will work only with embedded server:

> Enables scanning for Servlet components (filters, servlets, and > listeners). Scanning is only performed when using an embedded web > server.

More info: The @ServletComponentScan Annotation in Spring Boot

Solution 6 - Java

This way worked for me, having a servlet called WS01455501EndpointFor89

@Bean
public ServletRegistrationBean<WS01455501EndpointFor89> servletRegistrationBeanAlt(ApplicationContext context) {
	ServletRegistrationBean<WS01455501EndpointFor89> servletRegistrationBean = new ServletRegistrationBean<>(new WS01455501EndpointFor89(),
			"/WS01455501Endpoint");
	servletRegistrationBean.setLoadOnStartup(1);
	return servletRegistrationBean;
}

Solution 7 - Java

Also available in the BeanDefinitionRegistryPostProcessor

package bj;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@SpringBootApplication
class App implements BeanDefinitionRegistryPostProcessor {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        registry.registerBeanDefinition("myServlet", new RootBeanDefinition(ServletRegistrationBean.class,
                () -> new ServletRegistrationBean<>(new HttpServlet() {
                    @Override
                    protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
                        resp.getWriter().write("hello world");
                    }
                }, "/foo/*")));
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncheckettsView Question on Stackoverflow
Solution 1 - JavacheckettsView Answer on Stackoverflow
Solution 2 - Javachrylis -cautiouslyoptimistic-View Answer on Stackoverflow
Solution 3 - JavaMuzuView Answer on Stackoverflow
Solution 4 - JavaPramod YadavView Answer on Stackoverflow
Solution 5 - JavaJustinas JakavonisView Answer on Stackoverflow
Solution 6 - JavacequattroView Answer on Stackoverflow
Solution 7 - JavaBaiJiFeiLongView Answer on Stackoverflow