Pregunta

Estoy desarrollando una aplicación web Java servlet que maneja la información de múltiples bases de datos (todo estructuralmente el mismo) cada una correspondiente a un "negocio" diferente. El usuario selecciona "el negocio actual" que se almacena en la sesión y la aplicación puede visualizar o modificar ese "negocio actual".

Me gustaría utilizar los recursos de Tomcat de forma dinámica para tener acceso a estas empresas que utilizan JNDI. De esta manera puedo usar las etiquetas jstl SQL o búsquedas de contexto en los servlets. No puedo definir cada recurso en el archivo web.xml ya que se almacenan en una tabla de SQL. El resultado final es ser capaz de escribir JSP simple que tiene líneas como las siguientes:

<%@ taglib uri="http://java.sun.com/jstl/sql" prefix="sql" %>

<sql:query var = "users" dataSource="sources/${sessionScope.currentBusiness}">
  select id, firstName, lastName FROM user
</sql:query>

o servlets que pueden tener líneas como éstas

String request.getSession().getAttribute("currentBusiness");

Context initial = new InitialContext();
Context context = (Context) initial.lookup("java:comp/env");
DataSource source = (DataSource) context.lookup("sources/" + currentBusiness);

donde puedo conseguir la fuente de datos correcto para el "negocio actual".

He experimentado con escribir mis propias ObjectFactories derivados de javax.naming.spi.ObjectFactory sin éxito. Cualquier punteros sobre cómo hacer esto fácilmente?

¿Fue útil?

Solución

Finalmente conformé con la siguiente solución que consiste en un SessionListener y un servlet que funciona de la siguiente manera. El SessionListener tiene la siguiente forma:

public class SessionListener implements HttpSessionListener {

  public void sessionCreated(HttpSessionEvent event) {

    HttpSession session = event.getSession();

    // get list of possible data sources available to this session
    List<DataSource> sources = new ArrayList<DataSource>();
    ... code to get the available sources

    // get the current data source
    DataSource source = null;
    ... code to get the current source                               
    source = sources.get(0); // for example

    // setup the session attributes
    session.setAttribute("availableSources", sources);
    session.setAttribute("currentSource", source); 

  }

}

Siempre que se crea un usuario inicia sesión y una sesión, la lista de DataSources disponibles, y el actual, se colocan en la sesión. Esto se hace a nivel de sesión porque DataSources dependen de la conexión del usuario en. Ahora es posible tener acceso a ellos desde dentro de la aplicación. Para cambiar el origen de datos actual creé un servlet con esta versión simplificada:

public abstract class BoxletServlet extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {

    HttpSession session = request.getSession(true);
    String s = request.getParameter("source");

    // based on 's' choose from the available DataSource
    List<DataSource> sources = (List<DataSource>) session.getParameter("availableSources");
    Source source = chooseFrom(sources, s);                                                       
    session.setParameter("currentSource", source);          

    // forward to a page saying that the DataSource changed

  }

}

Con esta aplicación ahora es posible crear los siguientes archivos JSP:

<%@ taglib uri="http://java.sun.com/jstl/sql" prefix="sql" %>

<sql:query var = "users" dataSource="${sessionScope.currentSource}">
  select id, firstName, lastName FROM user
</sql:query>

Espero que ayuda a otra persona.

Otros consejos

Crea las fuentes de datos en un ServletContextListener y colocarlos en el ServletContext .

Este enfoque sin duda "trabajar", pero la idea de una base de datos independiente, idéntico para cada negocio parece mal a mí. Sin duda, ser capaz de delimitar negocio en algún lugar en el esquema parece posible. Separándolos de esta manera requiere una nueva base de datos por negocios, donde un sólo esquema requeriría un nuevo identificador comercial.

También diría que cualquier posibilidad de minería de datos a través del negocio se pierde, a menos que los datos ETL a partir de bases de datos separadas en un cubo tridimensional de informes ad hoc y consultas.

Y JSTL etiquetas sólo se debe utilizar en las aplicaciones web más simples. Usted se deja abierto a la posibilidad de ataques de inyección SQL cuando renuncias a la validación en un nivel medio.

ACTUALIZACIÓN:

Hay que declarar los recursos en su web.xml yo sepa, por lo que cada vez que tenga una nueva base de datos que tenga que detener la aplicación, configurar la nueva fuente JNDI, y reiniciar Tomcat. Espero que estés agrupado, porque todos los clientes anteriores se verán afectados por la aplicación de estar abajo cada vez que añada un nuevo negocio / base de datos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top