servlets - por - como compartir wifi
Usar el servlet de inicio automático especial para inicializar al inicio y compartir datos de la aplicación (1)
Necesito obtener alguna configuración y conectarme a recursos / objetos / sistemas externos en alguna parte y almacenarla en el alcance de la aplicación.
Puedo ver dos formas de configurar mi aplicación:
- Anulando el
init()
en los servlets existentes y el código requerido allí y manteniendo todos los objetos construidos dentro de ese mismo servlet. - Tener algún tipo de servlet de inicialización y usar su
init()
para hacer el trabajo. Luego, almacenando objetos creados enServletContext
para compartirlos con mis otros servlets.
¿Cuál de los anteriores es un mejor enfoque? ¿Hay alguna forma mejor de compartir objetos entre servlets? ¿Llamarlos directamente el uno del otro o así ...?
Ninguno de los dos es el mejor enfoque. Los servlets están destinados a escuchar en eventos HTTP (solicitudes HTTP), no en eventos de implementación (inicio / apagado).
CDI / JSF / EJB no disponible? Use ServletContextListener
@WebListener
public class Config implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Do stuff during webapp''s startup.
}
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during webapp''s shutdown.
}
}
Si aún no está en Servlet 3.0 y no puede actualizar, y por lo tanto no puede usar la anotación @WebListener
, entonces necesita registrarla manualmente en /WEB-INF/web.xml
como se /WEB-INF/web.xml
a continuación:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
Para almacenar y obtener objetos en el ámbito de la aplicación (para que todos los servlets puedan acceder a ellos), use ServletContext#setAttribute()
y #getAttribute()
.
Aquí hay un ejemplo que permite que el oyente se almacene en el ámbito de la aplicación:
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("config", this);
// ...
}
y luego obténgalo en un servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Config config = (Config) getServletContext().getAttribute("config");
// ...
}
También está disponible en JSP EL por ${config}
. Entonces podrías convertirlo en un simple frijol.
CDI disponible? Use @Observes
en ApplicationScoped.class
import javax.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class Config {
public void init(@Observes @Initialized(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp''s startup.
}
public void destroy(@Observes @Destroyed(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp''s shutdown.
}
}
Esto está disponible en un servlet a través de @Inject
. Haga que sea necesario también @Named
para que esté disponible también a través de #{config}
en EL.
Notado debe ser que esto es nuevo desde CDI 1.1. Si todavía está en CDI 1.0 y no puede actualizar, elija otro enfoque.
JSF disponible? Use @ManagedBean(eager=true)
import javax.faces.bean.ManagedBean
import javax.faces.bean.ApplicationScoped;
@ManagedBean(eager=true)
@ApplicationScoped
public class Config {
@PostConstruct
public void init() {
// Do stuff during webapp''s startup.
}
@PreDestroy
public void destroy() {
// Do stuff during webapp''s shutdown.
}
}
Esto también está disponible a través de #{config}
en EL.
EJB disponible? Considera @Startup
@Singleton
@Startup
@Singleton
public class Config {
@PostConstruct
public void init() {
// Do stuff during webapp''s startup.
}
@PreDestroy
public void destroy() {
// Do stuff during webapp''s shutdown.
}
}
Esto está disponible en un servlet a través de @EJB
. Estoy diciendo "considerar", porque no debe abusar de un EJB por el bien de un gancho de inicio. Además, un @Singleton
es, por defecto, de lectura / escritura bloqueada y está principalmente destinado a elementos transaccionales, como la programación de trabajos en segundo plano.