Как да регистрирам сървлет в Java

1. Въведение

Тази статия ще предостави преглед на това как да регистрирате сървлет в Джакарта EE и Spring Boot. По-конкретно, ще разгледаме два начина за регистриране на Java Servlet в Джакарта EE - единият с помощта на файл web.xml , а другият с помощта на анотации. След това ще регистрираме сървлети в Spring Boot, като използваме XML конфигурация, Java конфигурация и чрез конфигурируеми свойства.

Страхотна уводна статия за сървлетите можете да намерите тук.

2. Регистриране на сървлети в Джакарта EE

Нека да разгледаме два начина за регистриране на сървлет в Джакарта EE. Първо, можем да регистрираме сървлет чрез web.xml . Като алтернатива можем да използваме анотацията на Jakarta EE @WebServlet .

2.1. Чрез web.xml

Най-често срещаният начин да регистрирате сървлет във вашето приложение Джакарта EE е да го добавите към вашия web.xml файл:

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

Както можете да видите, това включва две стъпки: (1) добавяне на нашия сървлет към маркера на сървлета , като се уверите, че сте посочили и пътя на източника към класа, в който се намира сървлетът, и (2) посочване на URL адреса, който сървлетът ще бъде изложен върху в етикета на url-pattern .

Файлът на Джакарта EE web.xml обикновено се намира в WebContent / WEB-INF .

2.2. Чрез анотации

Сега нека регистрираме нашия сървлет, като използваме анотацията @WebServlet в нашия потребителски клас сървлет. Това елиминира необходимостта от съпоставяне на сървлети в server.xml и регистрация на сървлета в 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!

"); } }

Кодът по-горе показва как да добавите тази анотация директно към сървлет. Сервлетът все още ще бъде достъпен при същия URL път, както преди.

3. Регистриране на сървлети в Spring Boot

Сега, след като показахме как да регистрираме сервлети в Джакарта EE, нека разгледаме няколко начина за регистриране на сервлети в приложението Spring Boot.

3.1. Програмна регистрация

Spring Boot поддържа 100% програмна конфигурация на уеб приложение.

Първо ще приложим интерфейса WebApplicationInitializer , след това ще приложим интерфейса WebMvcConfigurer , който ви позволява да замените предварително зададените настройки по подразбиране, вместо да се налага да задавате всяка конкретна настройка на конфигурацията, спестявайки ви време и ви позволява да работите с няколко изпитани и истински настройки извън -кутията.

Нека разгледаме примерна реализация на WebApplicationInitializer :

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("/"); } }

След това нека приложим интерфейса WebMvcConfigurer :

@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()); } }

По-горе ние изрично посочваме някои от настройките по подразбиране за JSP сървлети, за да поддържаме .jsp изгледи и статично обслужване на ресурси.

3.2. XML конфигурация

Друг начин за конфигуриране и регистрация на сървлети в Spring Boot е чрез web.xml :

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

В web.xml използва за определяне на конфигурацията през пролетта е подобна на тази в Джакарта ЕЕ. По-горе можете да видите как посочваме още няколко параметъра чрез атрибути под маркера на сървлета .

Тук използваме друг XML за завършване на конфигурацията:

Не забравяйте, че вашият Spring web.xml обикновено ще живее в src / main / webapp / WEB-INF .

3.3. Комбиниране на XML и програмна регистрация

Нека смесим подход за XML конфигурация с програмната конфигурация на 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("/"); }

Нека също конфигурираме сървлета на диспечера:

3.4. Регистрация от Bean

Също така можем програмно да конфигурираме и регистрираме нашите сървлети, като използваме ServletRegistrationBean . По-долу ще направим това, за да регистрираме HttpServlet (който реализира интерфейса javax.servlet.Servlet ):

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

Основното предимство на този подход е, че ви позволява да добавяте както множество сървлети, така и различни видове сървлети към вашето приложение Spring.

Вместо просто да използваме DispatcherServlet, който е по-специфичен вид HttpServlet и най-често срещаният вид, използван в програмния подход WebApplicationInitializer към конфигурацията, който изследвахме в раздел 3.1, ще използваме по-опростен екземпляр на подклас HttpServlet, който излага четирите основни операции HttpRequest чрез четири функции: doGet () , doPost () , doPut () и doDelete () точно както в Джакарта EE.

Не забравяйте, че HttpServlet е абстрактен клас (така че не може да бъде създаден). Въпреки това можем лесно да създадем персонализирано разширение:

public class CustomServlet extends HttpServlet{ ... }

4. Регистриране на сървлети със свойства

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.

В TomcatEmbeddedServletContainerFactory увива org.apache.catalina.startup.Tomcat обект предоставяне на допълнителни опции за конфигуриране:

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

След това можем да конфигурираме върнатия екземпляр:

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

Всяка от тези конкретни настройки може да бъде конфигурирана с помощта на който и да е от описаните по-горе методи.

Също така можем директно да осъществяваме достъп и да манипулираме обекта org.apache.catalina.startup.Tomcat :

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

6. Заключение

В тази статия разгледахме няколко начина за регистриране на сървлет в приложението на Джакарта EE и Spring Boot.

Изходният код, използван в този урок, е достъпен в проекта Github.