So registrieren Sie ein Servlet in Java

1. Einleitung

Dieser Artikel bietet einen Überblick über die Registrierung eines Servlets in Jakarta EE und Spring Boot. Insbesondere werden zwei Möglichkeiten zum Registrieren eines Java-Servlets in Jakarta EE untersucht - eine mithilfe einer web.xml- Datei und die andere mithilfe von Anmerkungen. Anschließend registrieren wir Servlets in Spring Boot mithilfe der XML-Konfiguration, der Java-Konfiguration und über konfigurierbare Eigenschaften.

Einen großartigen Einführungsartikel zu Servlets finden Sie hier.

2. Registrieren von Servlets in Jakarta EE

Lassen Sie uns zwei Möglichkeiten durchgehen, um ein Servlet in Jakarta EE zu registrieren. Zunächst können wir ein Servlet über web.xml registrieren . Alternativ können wir die Annotation Jakarta EE @WebServlet verwenden .

2.1. Über web.xml

Die häufigste Methode zum Registrieren eines Servlets in Ihrer Jakarta EE-Anwendung besteht darin, es Ihrer Datei web.xml hinzuzufügen :

 index.html index.htm index.jsp   Example com.baeldung.Example   Example /Example 

Wie Sie sehen können, umfasst dies zwei Schritte: (1) Hinzufügen unseres Servlets zum Servlet- Tag, Sicherstellen , dass auch der Quellpfad zu der Klasse angegeben wird, in der sich das Servlet befindet, und (2) Angeben des URL-Pfads, für den das Servlet verfügbar gemacht wird on im URL-Pattern- Tag.

Die Datei Jakarta EE web.xml befindet sich normalerweise in WebContent / WEB-INF .

2.2. Über Anmerkungen

Registrieren wir nun unser Servlet mithilfe der Annotation @WebServlet für unsere benutzerdefinierte Servlet-Klasse. Dadurch entfallen Servlet-Zuordnungen in der Datei server.xml und die Registrierung des Servlets in der Datei web.xml :

@WebServlet( name = "AnnotationExample", description = "Example Servlet Using Annotations", urlPatterns = {"/AnnotationExample"} ) public class Example extends HttpServlet { @Override protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("

Hello World!

"); } }

Der obige Code zeigt, wie diese Annotation direkt zu einem Servlet hinzugefügt wird. Das Servlet ist weiterhin unter demselben URL-Pfad wie zuvor verfügbar.

3. Registrieren von Servlets im Spring Boot

Nachdem wir nun gezeigt haben, wie Servlets in Jakarta EE registriert werden, werfen wir einen Blick auf verschiedene Möglichkeiten, Servlets in einer Spring Boot-Anwendung zu registrieren.

3.1. Programmatische Registrierung

Spring Boot unterstützt die 100% ige programmgesteuerte Konfiguration einer Webanwendung.

Zuerst implementieren wir die WebApplicationInitializer- Schnittstelle und dann die WebMvcConfigurer- Schnittstelle, mit der Sie voreingestellte Standardeinstellungen überschreiben können, anstatt die einzelnen Konfigurationseinstellungen angeben zu müssen. Dies spart Zeit und ermöglicht es Ihnen, mit mehreren bewährten Einstellungen zu arbeiten -die Kiste.

Schauen wir uns ein Beispiel für eine WebApplicationInitializer- Implementierung an:

public class WebAppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(WebMvcConfigure.class); ctx.setServletContext(container); ServletRegistration.Dynamic servlet = container.addServlet( "dispatcherExample", new DispatcherServlet(ctx)); servlet.setLoadOnStartup(1); servlet.addMapping("/"); } }

Als Nächstes implementieren wir die WebMvcConfigurer- Schnittstelle:

@Configuration public class WebMvcConfigure implements WebMvcConfigurer { @Bean public ViewResolver getViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/"); resolver.setSuffix(".jsp"); return resolver; } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") .addResourceLocations("/resources/").setCachePeriod(3600) .resourceChain(true).addResolver(new PathResourceResolver()); } }

Oben geben wir einige Standardeinstellungen für JSP-Servlets explizit an, um .jsp- Ansichten und die Bereitstellung statischer Ressourcen zu unterstützen .

3.2. XML-Konfiguration

Eine andere Möglichkeit, Servlets in Spring Boot zu konfigurieren und zu registrieren, ist web.xml :

 dispatcher org.springframework.web.servlet.DispatcherServlet  contextConfigLocation /WEB-INF/spring/dispatcher.xml  1   dispatcher / 

Die web.xml , mit der die Konfiguration in Spring angegeben wird, ähnelt der in Jakarta EE. Oben sehen Sie, wie wir über Attribute unter dem Servlet- Tag einige weitere Parameter angeben .

Hier verwenden wir ein anderes XML, um die Konfiguration abzuschließen:

Denken Sie daran, dass Ihre Spring web.xml normalerweise in src / main / webapp / WEB-INF gespeichert ist .

3.3. Kombination von XML und programmatischer Registrierung

Mischen wir einen XML-Konfigurationsansatz mit der programmatischen Konfiguration von Spring:

public void onStartup(ServletContext container) throws ServletException { XmlWebApplicationContext xctx = new XmlWebApplicationContext(); xctx.setConfigLocation('classpath:/context.xml'); xctx.setServletContext(container); ServletRegistration.Dynamic servlet = container.addServlet( "dispatcher", new DispatcherServlet(ctx)); servlet.setLoadOnStartup(1); servlet.addMapping("/"); }

Konfigurieren wir auch das Dispatcher-Servlet:

3.4. Registrierung durch Bean

We can also programmatically configure and register our servlets using a ServletRegistrationBean. Below we'll do so in order to register an HttpServlet (which implements the javax.servlet.Servlet interface):

@Bean public ServletRegistrationBean exampleServletBean() { ServletRegistrationBean bean = new ServletRegistrationBean( new CustomServlet(), "/exampleServlet/*"); bean.setLoadOnStartup(1); return bean; }

The main advantage of this approach is that it enables you to add both multiple servlets as well as different kinds of servlets to your Spring application.

Instead of merely utilizing a DispatcherServlet, which is a more specific kind of HttpServlet and the most common kind used in the WebApplicationInitializer programmatic approach to configuration we explored in section 3.1, we'll use a simpler HttpServlet subclass instance which exposes the four basic HttpRequest operations through four functions: doGet(), doPost(), doPut(), and doDelete() just like in Jakarta EE.

Remember that HttpServlet is an abstract class (so it can't be instantiated). We can whip up a custom extension easily, though:

public class CustomServlet extends HttpServlet{ ... }

4. Registering Servlets With Properties

Another, though uncommon, way to configure and register your servlets is to use a custom properties file loaded into the app via a PropertyLoader, PropertySource, or PropertySources instance object.

This provides an intermediate kind of configuration and the ability to otherwise customize application.properties which provide little direct configuration for non-embedded servlets.

4.1. System Properties Approach

We can add some custom settings to our application.properties file or another properties file. Let's add a few settings to configure our DispatcherServlet:

servlet.name=dispatcherExample servlet.mapping=/dispatcherExampleURL

Let's load our custom properties into our application:

System.setProperty("custom.config.location", "classpath:custom.properties");

And now we can access those properties via:

System.getProperty("custom.config.location");

4.2. Custom Properties Approach

Let's start with a custom.properties file:

servlet.name=dispatcherExample servlet.mapping=/dispatcherExampleURL

We can then use a run-of-the-mill Property Loader:

public Properties getProperties(String file) throws IOException { Properties prop = new Properties(); InputStream input = null; input = getClass().getResourceAsStream(file); prop.load(input); if (input != null) { input.close(); } return prop; }

And now we can add these custom properties as constants to our WebApplicationInitializer implementation:

private static final PropertyLoader pl = new PropertyLoader(); private static final Properties springProps = pl.getProperties("custom_spring.properties"); public static final String SERVLET_NAME = springProps.getProperty("servlet.name"); public static final String SERVLET_MAPPING = springProps.getProperty("servlet.mapping");

We can then use them to, for example, configure our dispatcher servlet:

ServletRegistration.Dynamic servlet = container.addServlet( SERVLET_NAME, new DispatcherServlet(ctx)); servlet.setLoadOnStartup(1); servlet.addMapping(SERVLET_MAPPING);

The advantage of this approach is the absence of .xml maintenance but with easy-to-modify configuration settings that don't require redeploying the codebase.

4.3. The PropertySource Approach

A faster way to accomplish the above is to make use of Spring's PropertySource which allows a configuration file to be accessed and loaded.

PropertyResolver is an interface implemented by ConfigurableEnvironment, which makes application properties available at servlet startup and initialization:

@Configuration @PropertySource("classpath:/com/yourapp/custom.properties") public class ExampleCustomConfig { @Autowired ConfigurableEnvironment env; public String getProperty(String key) { return env.getProperty(key); } }

Above, we autowire a dependency into the class and specify the location of our custom properties file. We can then fetch our salient property by calling the function getProperty() passing in the String value.

4.4. The PropertySource Programmatic Approach

We can combine the above approach (which involves fetching property values) with the approach below (which allows us to programmatically specify those values):

ConfigurableEnvironment env = new StandardEnvironment(); MutablePropertySources props = env.getPropertySources(); Map map = new HashMap(); map.put("key", "value"); props.addFirst(new MapPropertySource("Map", map));

We've created a map linking a key to a value then add that map to PropertySources enabling invocation as needed.

5. Registering Embedded Servlets

Lastly, we'll also take a look at basic configuration and registration of embedded servlets within Spring Boot.

An embedded servlet provides full web container (Tomcat, Jetty, etc.) functionality without having to install or maintain the web-container separately.

You can add the required dependencies and configuration for simple live server deployment wherever such functionality is supported painlessly, compactly, and quickly.

We'll only look at how to do this Tomcat but the same approach can be undertaken for Jetty and alternatives.

Let's specify the dependency for an embedded Tomcat 8 web container in pom.xml:

 org.apache.tomcat.embed tomcat-embed-core 8.5.11 

Now let's add the tags required to successfully add Tomcat to the .war produced by Maven at build-time:

 embeddedTomcatExample   org.codehaus.mojo appassembler-maven-plugin 2.0.0  target   launch.Main webapp      package  assemble      

If you are using Spring Boot, you can instead add Spring's spring-boot-starter-tomcat dependency to your pom.xml:

 org.springframework.boot spring-boot-starter-tomcat provided 

5.1. Registration Through Properties

Spring Boot supports configuring most possible Spring settings through application.properties. After adding the necessary embedded servlet dependencies to your pom.xml, you can customize and configure your embedded servlet using several such configuration options:

server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet server.jsp-servlet.registered=true server.port=8080 server.servlet-path=/

Above are some of the application settings that can be used to configure the DispatcherServlet and static resource sharing. Settings for embedded servlets, SSL support, and sessions are also available.

There are really too many configuration parameters to list here but you can see the full list in the Spring Boot documentation.

5.2. Configuration Through YAML

Similarly, we can configure our embedded servlet container using YAML. This requires the use of a specialized YAML property loader — the YamlPropertySourceLoader — which exposes our YAML and makes the keys and values therein available for use within our app.

YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader(); PropertySource yamlProps = sourceLoader.load("yamlProps", resource, null);

5.3. Programmatic Configuration Through TomcatEmbeddedServletContainerFactory

Programmatic configuration of an embedded servlet container is possible through a subclassed instance of EmbeddedServletContainerFactory. For example, you can use the TomcatEmbeddedServletContainerFactory to configure your embedded Tomcat servlet.

Die TomcatEmbeddedServletContainerFactory umschließt das org.apache.catalina.startup.Tomcat- Objekt und bietet zusätzliche Konfigurationsoptionen:

@Bean public ConfigurableServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcatContainerFactory = new TomcatServletWebServerFactory(); return tomcatContainerFactory; }

Dann können wir die zurückgegebene Instanz konfigurieren:

tomcatContainerFactory.setPort(9000); tomcatContainerFactory.setContextPath("/springboottomcatexample");

Jede dieser speziellen Einstellungen kann mit einer der zuvor beschriebenen Methoden konfigurierbar gemacht werden.

Wir können auch direkt auf das Objekt org.apache.catalina.startup.Tomcat zugreifen und es bearbeiten :

Tomcat tomcat = new Tomcat(); tomcat.setPort(port); tomcat.setContextPath("/springboottomcatexample"); tomcat.start();

6. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten zum Registrieren eines Servlets in einer Jakarta EE- und Spring Boot-Anwendung beschrieben.

Der in diesem Tutorial verwendete Quellcode ist im Github-Projekt verfügbar.