Como registrar um servlet em Java
*1. Introdução *
Este artigo fornecerá* uma visão geral de como registrar um servlet no Java EE e Spring Boot. *Especificamente, examinaremos duas maneiras de registrar um Servlet Java no Java EE - um usando um arquivo web.xml e o outro usando anotações. Em seguida, registraremos os servlets no Spring Boot usando a configuração XML, a configuração Java e as propriedades configuráveis.
Um ótimo artigo introdutório sobre servlets pode ser encontrado no link:/introdução aos servlets [aqui].
===* 2. Registrando Servlets no Java EE *
Vamos examinar duas maneiras de registrar um servlet no Java EE. Primeiro, podemos registrar um servlet via web.xml. Como alternativa, podemos usar a anotação Java EE _ @ WebServlet_.
====* 2.1 Via web.xml *
A maneira mais comum de registrar um servlet no seu aplicativo Java EE é adicioná-lo ao seu arquivo web.xml:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Example</servlet-name>
<servlet-class>com..Example</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Example</servlet-name>
<url-pattern>/Example</url-pattern>
</servlet-mapping>
Como você pode ver, isso envolve duas etapas: (1) adicionar nosso servlet à tag servlet, certificando-se de especificar também o caminho de origem para a classe em que o servlet reside e (2) especificar o caminho da URL em que o servlet será exposto na tag url-pattern.
O arquivo Java EE web.xml geralmente é encontrado em WebContent/WEB-INF.
====* 2.2 Via Anotações *
Agora vamos registrar nosso servlet usando a anotação _ @ WebServlet_ em nossa classe de servlet customizada. Isso elimina a necessidade de mapeamentos de servlet no server.xml e o registro do servlet em 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("<p>Hello World!</p>");
}
}
O código acima demonstra como adicionar essa anotação diretamente a um servlet. O servlet ainda estará disponível no mesmo caminho de URL que antes.
===* 3. Registrando Servlets no Spring Boot *
Agora que mostramos como registrar servlets no Java EE, vamos dar uma olhada em várias maneiras de registrar servlets em um aplicativo Spring Boot.
====* 3.1 Registro programático *
O Spring Boot suporta 100% de configuração programática de um aplicativo da web.
Primeiro, implementaremos a interface WebApplicationInitializer e, em seguida, implementaremos a interface WebMvcConfigurer, que permite substituir os padrões predefinidos em vez de especificar cada configuração específica, economizando tempo e permitindo que você trabalhe com várias configurações reais e experimentadas. -a Caixa.
Vejamos uma implementação de exemplo 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("/");
}
}
Em seguida, vamos implementar a interface 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());
}
}
Acima, especificamos algumas das configurações padrão para servlets JSP explicitamente, a fim de suportar visualizações .jsp e veiculação de recursos estáticos.
3.2 Configuração XML
Outra maneira de configurar e registrar servlets no Spring Boot é através de web.xml:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
O web.xml usado para especificar a configuração no Spring é semelhante ao encontrado no Java EE. Acima, você pode ver como especificamos mais alguns parâmetros por meio de atributos na tag servlet.
Aqui usamos outro XML para concluir a configuração:
<beans ...>
<context:component-scan base-package="com."/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Lembre-se de que o seu web.xml do Spring geralmente fica em src/main/webapp/WEB-INF.
3.3 Combinando XML e registro programático
Vamos misturar uma abordagem de configuração XML com a configuração programática do 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("/");
}
Vamos também configurar o servlet do expedidor:
<beans ...>
<context:component-scan base-package="com."/>
<bean class="com..configuration.WebAppInitializer"/>
</beans>
3.4 Registro pelo Bean
Também podemos configurar e registrar programaticamente nossos servlets usando um ServletRegistrationBean. Abaixo, faremos isso para registrar um HttpServlet (que implementa a interface javax.servlet.Servlet):
@Bean
public ServletRegistrationBean exampleServletBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(
new CustomServlet(), "/exampleServlet/*");
bean.setLoadOnStartup(1);
return bean;
}
A principal vantagem dessa abordagem é que ela permite adicionar vários servlets, bem como diferentes tipos de servlets, ao seu aplicativo Spring.
Em vez de simplesmente utilizar um DispatcherServlet, _ que é um tipo mais específico de _HttpServlet e o tipo mais comum usado na abordagem programática WebApplicationInitializer à configuração que exploramos na seção 3.1, usaremos uma instância mais simples da subclasse HttpServlet que expõe as quatro HttpRequest operações através de quatro funções: _doGet () _, _doPost () _, _doPut () _ e _doDelete () _ assim como no Java EE.
Lembre-se de que HttpServlet é uma classe abstrata (portanto, não pode ser instanciada). Podemos criar uma extensão personalizada facilmente, no entanto:
public class CustomServlet extends HttpServlet{
...
}
*4. Registrando Servlets com Propriedades *
Outra maneira, embora incomum, de configurar e registrar seus servlets é usar um arquivo de propriedades customizado carregado no aplicativo por meio de um objeto de instância PropertyLoader, PropertySource, _ ou _PropertySources .
Isso fornece um tipo intermediário de configuração e a capacidade de personalizar application.properties, que fornece pouca configuração direta para servlets não incorporados.
====* 4.1 Abordagem de propriedades do sistema *
Podemos adicionar algumas configurações personalizadas ao nosso arquivo application.properties ou outro arquivo de propriedades. Vamos adicionar algumas configurações para configurar nosso DispatcherServlet:
servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL
Vamos carregar nossas propriedades personalizadas em nosso aplicativo:
System.setProperty("custom.config.location", "classpath:custom.properties");
E agora podemos acessar essas propriedades via:
System.getProperty("custom.config.location");
====* 4.2 Abordagem de propriedades personalizadas *
Vamos começar com um arquivo custom.properties:
servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL
Em seguida, podemos usar um Carregador de propriedades comum:
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;
}
E agora podemos adicionar essas propriedades personalizadas como constantes à nossa implementação WebApplicationInitializer:
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");
Em seguida, podemos usá-los para, por exemplo, configurar nosso servlet de expedidor:
ServletRegistration.Dynamic servlet = container.addServlet(
SERVLET_NAME, new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping(SERVLET_MAPPING);
A vantagem dessa abordagem é a ausência de manutenção .xml, mas com definições de configuração fáceis de modificar que não exigem a reimplantação da base de código.
====* 4.3 A abordagem PropertySource *
Uma maneira mais rápida de fazer isso é usar o PropertySource do Spring, que permite que um arquivo de configuração seja acessado e carregado.
PropertyResolver é uma interface implementada por _ConfigurableEnvironment, _ que disponibiliza as propriedades do aplicativo na inicialização e inicialização do servlet:
@Configuration
@PropertySource("classpath:/com/yourapp/custom.properties")
public class ExampleCustomConfig {
@Autowired
ConfigurableEnvironment env;
public String getProperty(String key) {
return env.getProperty(key);
}
}
Acima, atribuímos automaticamente uma dependência à classe e especificamos o local do nosso arquivo de propriedades personalizadas. Podemos então buscar nossa propriedade saliente chamando a função _getProperty () _ que passa no valor String.
====* 4.4 A abordagem programática PropertySource *
Podemos combinar a abordagem acima (que envolve buscar valores de propriedade) com a abordagem abaixo (que nos permite especificar programaticamente esses valores):
ConfigurableEnvironment env = new StandardEnvironment();
MutablePropertySources props = env.getPropertySources();
Map map = new HashMap(); map.put("key", "value");
props.addFirst(new MapPropertySource("Map", map));
Criamos um mapa vinculando uma chave a um valor e, em seguida, adicionamos esse mapa a PropertySources, permitindo a chamada conforme necessário.
===* 5. Registrando Servlets Incorporados *
Por fim, também veremos a configuração básica e o registro de servlets incorporados no Spring Boot.
*Um servlet incorporado fornece a funcionalidade completa de contêiner da Web (Tomcat, Jetty etc.) sem precisar instalar ou manter o contêiner da Web separadamente* .
Você pode adicionar as dependências e a configuração necessárias para a implantação simples do servidor ativo, sempre que essa funcionalidade for suportada sem problemas, de forma compacta e rápida.
Vamos ver apenas como fazer isso Tomcat, mas a mesma abordagem pode ser adotada para o Jetty e alternativas.
Vamos especificar a dependência para um contêiner da Web Tomcat 8 incorporado em pom.xml:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.11</version>
</dependency>
Agora vamos adicionar as tags necessárias para adicionar com êxito o Tomcat ao .war produzido pelo Maven no momento da construção:
<build>
<finalName>embeddedTomcatExample</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.0.0</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>launch.Main</mainClass>
<name>webapp</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Se você estiver usando o Spring Boot, poderá adicionar a dependência spring-boot-starter-tomcat do Spring ao seu pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
5.1. Registro através de propriedades
O Spring Boot suporta a configuração da maioria das configurações possíveis do Spring através de application.properties. Após adicionar as dependências necessárias do servlet incorporado ao seu pom.xml, você pode personalizar e configurar o servlet incorporado usando várias dessas opções de configuração:
server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet
server.jsp-servlet.registered=true
server.port=8080
server.servlet-path=/
A seguir, estão algumas configurações do aplicativo que podem ser usadas para configurar o DispatcherServlet e o compartilhamento estático de recursos. Configurações para servlets incorporados, suporte SSL e sessões também estão disponíveis.
Existem realmente muitos parâmetros de configuração para listar aqui, mas você pode ver a lista completa em Spring Documentação de inicialização.
5.2 Configuração através do YAML
Da mesma forma, podemos configurar nosso contêiner de servlet incorporado usando o YAML. Isso requer o uso de um carregador de propriedades YAML especializado - o YamlPropertySourceLoader - que expõe nossa YAML e disponibiliza as chaves e valores disponíveis para uso em nosso aplicativo.
YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
PropertySource<?> yamlProps = sourceLoader.load("yamlProps", resource, null);
5.3. Configuração programática através do TomcatEmbeddedServletContainerFactory
A configuração programática de um contêiner de servlet incorporado é possível por meio de uma instância subclassificada de EmbeddedServletContainerFactory. Por exemplo, você pode usar o TomcatEmbeddedServletContainerFactory para configurar seu servlet Tomcat incorporado.
O TomcatEmbeddedServletContainerFactory envolve o objeto org.apache.catalina.startup.Tomcat, fornecendo opções de configuração adicionais:
@Bean
public ConfigurableServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcatContainerFactory
= new TomcatServletWebServerFactory();
return tomcatContainerFactory;
}
Em seguida, podemos configurar a instância retornada:
tomcatContainerFactory.setPort(9000);
tomcatContainerFactory.setContextPath("/springboottomcatexample");
Cada uma dessas configurações específicas pode ser configurada usando qualquer um dos métodos descritos anteriormente.
Também podemos acessar e manipular diretamente o objeto org.apache.catalina.startup.Tomcat:
Tomcat tomcat = new Tomcat();
tomcat.setPort(port);
tomcat.setContextPath("/springboottomcatexample");
tomcat.start();
*6. Conclusão *
Neste artigo, analisamos várias maneiras de* registrar um Servlet em um aplicativo Java EE e Spring Boot. *
O código fonte usado neste tutorial está disponível no Projeto Github.