Para aplicaciones de servlet, Spring Boot proporciona soporte para servidores integrados Tomcat, Jetty y Resaca . La mayoría de los desarrolladores
utilizan un "iniciador" apropiado para obtener una instancia completamente configurada. De forma predeterminada, el
servidor integrado escucha las solicitudes HTTP en el puerto 8080
.
Servlets, filtros y escuchas
Cuando se utiliza el servlet integrado contenedor, puede registrar servlets, filtros y cualquier
escucha (como HttpSessionListener
) desde la especificación del servlet, ya sea usando Spring beans o
rastreando componentes del servlet.
Registro de servlets, filtros, y oyentes como Spring beans
Cualquier instancia de un servlet Servlet
, Filter
o
*Listener
que sea un Spring Bean. Está registrado con el contenedor integrado. Esto puede ser
especialmente útil si necesita hacer referencia a un valor de
application.properties
durante la configuración.
De forma predeterminada, si un contexto
contiene
solo un servlet, se asigna a /
. En el caso de varios beans de servlet, el nombre del bean se utiliza
como prefijo de ruta. Los filtros se asignan a /*
.
Si la asignación basada en convenciones
no es lo suficientemente flexible, puede utilizar ServletRegistrationBean
,
FilterRegistrationBean
y ServletListenerRegistrationBean
para un control completo.
Normalmente, no es necesario
pedir el bean de filtro. Si se requiere un orden específico, entonces el Filter
debe anotarse con la
anotación @Order
o implementarse como una clase Ordered
. No puede configurar el orden de
un Filter
anotando su método de bean con la anotación @Order
. Si no puede modificar la
clase Filter
para agregar la anotación @Order
o implementar la clase Ordered
,
debe definir un FilterRegistrationBean
, para Filter
y establezca el orden del bean de
registro utilizando el método setOrder(int)
. Evite configurar un filtro que lea el cuerpo de la
solicitud por Ordered.HIGHEST_PRECEDENCE
, ya que esto puede entrar en conflicto con la configuración de
codificación de caracteres de su aplicación. Si un filtro de servlet envuelve una solicitud, su orden de ejecución
configurado debe ser menor o igual a OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER
.
Filter
en la aplicación,
habilite el registro de nivel de depuración para el grupo de registro web (logging.level.web=debug
).
Los detalles de los filtros registrados, incluido su orden y patrones de URL, se registrarán en el inicio inicial.
Filter
beans porque se crean
instancias de ellos muy temprano en el ciclo de vida de la aplicación. Si necesita registrar un Filtro
que interactúa con otros beans, utilice un DelegatingFilterProxyRegistrationBean
en su lugar.
Inicialización de un contexto de servlet
Los contenedores de servlet integrados no ejecutan
directamente la interfaz de servlet 3.0+ llamada javax.servlet.ServletContainerInitializer
o la
interfaz org.springframework.web.WebApplicationInitializer
de Spring. Esta es una decisión de diseño
deliberada para reducir el riesgo de que las bibliotecas de terceros diseñadas para ejecutarse dentro de un archivo
war puedan dañar las aplicaciones Spring Boot.
Si desea inicializar un contexto de servlet en una aplicación
Spring Boot, debe registrar el bean que implementa la interfaz org.springframework.boot.web.servlet.ServletContextInitializer
.
El método único onStartup
proporciona acceso al ServletContext
y, si es necesario, se
puede utilizar fácilmente como adaptador a un WebApplicationInitializer
existente.
Buscando servlets, filtros y oyentes
Cuando se utiliza un contenedor integrado, registra automáticamente las clases
marcadas con @WebServlet
, @WebFilter
y @ anotaciones WebListener
, se pueden
activar usando la anotación @ServletComponentScan
.
@ServletComponentScan
no funciona en un contenedor independiente,
donde en su lugar se utilizan los mecanismos de descubrimiento integrados del contenedor.
ServletWebServerApplicationContext
Internamente, Spring Boot utiliza un tipo diferente de ApplicationContext
para admitir el contenedor de servlet integrado. ServletWebServerApplicationContext
es un tipo especial
de WebApplicationContext
que se inicia buscando un único bean ServletWebServerFactory
. Por
lo general, TomcatServletWebServerFactory
, JettyServletWebServerFactory
o UndertowServletWebServerFactory
se configuran automáticamente.
ApplicationContext
y ServletWebServerFactory
se crean sin su intervención.
En la configuración del contenedor integrado, el ServletContext
está configurado como un
elemento de inicio del servidor que ocurre durante la inicialización del contexto de la aplicación. Debido a esto,
los beans en ApplicationContext
no se pueden inicializar de manera confiable usando ServletContext
.
Una forma de solucionar esta limitación es implementar ApplicationContext
como una dependencia de bean
y solo llamar a ServletContext
cuando sea necesario. Otra forma es utilizar una devolución de llamada
inmediatamente después de que se inicie el servidor. Esto se puede hacer usando un ApplicationListener
que escucha el ApplicationStartedEvent
de esta manera:
import javax.servlet.ServletContext;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.web.context.WebApplicationContext;
public class MyDemoBean implements ApplicationListener<ApplicationStartedEvent> {
private ServletContext servletContext;
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
this.servletContext = ((WebApplicationContext) applicationContext).getServletContext();
}
}
Personalización de la configuración para contenedores de servlets integrados
La configuración general
de un contenedor de servlet se puede configurar usando las Environment
del entorno de Spring.
Normalmente, las propiedades se definen en el archivo application.properties
o
application.yaml
.
La configuración general del servidor incluye:
-
Parámetros de red: puerto para escuchar solicitudes HTTP entrantes (
server.port
), dirección de interfaz para vincular aserver.address
, etc. -
Parámetros de sesión: si la sesión se almacena durante un tiempo prolongado (
server.servlet.session.persistent
), tiempo de espera de la sesión (server. servlet.session.timeout
), ubicación de los datos de la sesión (server.servlet.session.store-dir
) y configuración de las cookies de sesión (server.servlet.session.cookie.*
). Gestión de errores: ubicación de la página de error (
server.error.path
), etc.SSL
Compresión HTTP
Spring Boot toma todas las medidas necesarias para proporcionar acceso a muchas configuraciones generales, pero
esto no siempre es posible. En tales casos, los espacios de nombres especializados proporcionan configuraciones
específicas del servidor (consulte server.tomcat
y server.undertow
). Por ejemplo, los
registros de acceso se pueden configurar para que coincidan con las características específicas del contenedor de
servlets integrado.
ServerProperties
.
Atributo SameSite para cookies
Los navegadores web pueden utilizar aributo SameSite
para cookies, para controlar si las cookies se pasan en solicitudes entre sitios y cómo. El atributo es
especialmente relevante para los navegadores web modernos, que han comenzado a cambiar el valor predeterminado
utilizado cuando falta el atributo.
Si desea cambiar el atributo SameSite
de su sesión cookie,
puede utilizar la propiedad server.servlet.session.cookie.same-site
. Esta propiedad es compatible con
los servidores Tomcat, Jetty y Undertow configurados automáticamente. También se utiliza para configurar beans
SessionRepository
basados en servlets de sesión en Spring.
Por ejemplo, si desea que una cookie
de sesión tenga un atributo SameSite
cuyo valor es None
, entonces puede agregar el
siguiente código al archivo application.properties
o application.yaml
:
server.servlet.session.cookie.same-site=none
server:
servlet:
session:
cookie:
same-site: "none"
Si desea cambiar el atributo SameSite
para otras cookies agregadas a
HttpServletResponse
, puede utilizar CookieSameSiteSupplier
.
CookieSameSiteSupplier
se pasa a Cookie
y puede devolver SameSite
o null
.
Hay un Número de asistentes de fábrica y métodos de filtrado que se pueden utilizar para encontrar rápidamente
cookies específicas. Por ejemplo, agregar el siguiente bean aplicará automáticamente SameSite
de Lax
a todas las cookies con un nombre que coincida con la expresión regular myapp.*
.
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MySameSiteConfiguration {
@Bean
public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*");
}
}
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MySameSiteConfiguration {
@Bean
fun applicationCookieSameSiteSupplier(): CookieSameSiteSupplier {
return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*")
}
}
Personalizar configuración mediante programación
Si necesita configurar mediante programación un
contenedor de servlet integrado, puede registrar un Spring Bean que implemente la interfaz WebServerFactoryCustomizer
.
WebServerFactoryCustomizer
proporciona acceso a la fábrica
ConfigurableServletWebServerFactory
, que incluye muchos configuradores. El siguiente ejemplo muestra
cómo configurar un puerto mediante programación:
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory
import org.springframework.stereotype.Component
@Component
class MyWebServerFactoryCustomizer : WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
override fun customize(server: ConfigurableServletWebServerFactory) {
server.setPort(9000)
}
}
TomcatServletWebServerFactory
, JettyServletWebServerFactory
y UndertowServletWebServerFactory
son variantes especiales de ConfigurableServletWebServerFactory
que tienen configuradores adicionales
para Tomcat, Jetty y Undertow respectivamente. El siguiente ejemplo muestra cómo configurar un TomcatServletWebServerFactory
que proporciona acceso a opciones de configuración relacionadas con Tomcat:
import java.time.Duration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory server) {
server.addConnectorCustomizers((connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
}
}
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component
import java.time.Duration
@Component
class MyTomcatWebServerFactoryCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
override fun customize(server: TomcatServletWebServerFactory) {
server.addConnectorCustomizers({ connector -> connector.asyncTimeout = Duration.ofSeconds(20).toMillis() })
}
}
Personalización directa de la configuración de ConfigurableServletWebServerFactory
En casos de uso más complejos que requieren una extensión de ServletWebServerFactory
, puede abrir un
bean de este tipo usted mismo.
Se proporcionan configuradores para muchos parámetros de configuración. También hay varios "interceptores" para métodos protegidos si necesita hacer algo más inusual. Para obtener más información, consulte documentación en el código fuente.
Limitaciones de JSP
Cuando se ejecuta una aplicación Spring Boot que utiliza el contenedor de servlet integrado (y está empaquetada como un archivo ejecutable), existen algunas limitaciones en las funciones de soporte de JSP. .
Con Jetty y Tomcat todo debería funcionar si usas el empaquetado de archivos war. El archivo war ejecutable funcionará cuando se ejecute mediante
java -jar
y también se implementará en cualquier contenedor estándar. Las páginas JSP no son compatibles cuando se utiliza un archivo jar ejecutable.Undertow no admite páginas JSP.
Creación de una página JSP personalizada La página
error.jsp
no anula la vista predeterminada de manejo de errores. En su lugar, se deben utilizar páginas de error personalizadas.