Frage

Ich entwickle eine Java-Servlet-Web-Anwendung, die Informationen aus mehreren Datenbanken (alle strukturell das gleiche), die jeweils einem anderen „Geschäft“ verwaltet. Der Benutzer wählt „das aktuelle Geschäft“, die in der Sitzung gespeichert und die Anwendung kann, dass „aktuelles Geschäft“ anzuzeigen oder zu ändern.

Ich mag tomcat Ressourcen in einer dynamischen Art und Weise verwenden, um Zugang zu diesen Unternehmen jndi mit haben. Auf diese Weise kann ich die jstl SQL-Tags oder Kontext-Lookups in Servlets verwenden. Ich kann nicht jede Ressource in der Datei web.xml definieren, weil sie in einer SQL-Tabelle gespeichert werden. Das Endergebnis ist in der Lage einfachen jsp zu schreiben, die Zeilen wie diese hat:

<%@ 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>

oder Servlets, die Zeilen wie diese haben können

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

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

, wo ich die richtige Datenquelle für das „laufende Geschäft“ erhalten.

Ich habe meine eigene ObjectFactories experimentiert mit dem Schreiben von javax.naming.spi.ObjectFactory abgeleitet ohne Erfolg. Alle Hinweise, wie man dies leicht zu tun?

War es hilfreich?

Lösung

ich schließlich für folgende Lösung angesiedelt, bestehend auf einem SessionListener und einem Servlet, die wie folgt arbeiten. Die SessionListener hat die folgende Form:

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); 

  }

}

Jedes Mal, wenn sich ein Benutzer anmeldet und eine Sitzung erstellt wird, die Liste der verfügbaren Datasource und die aktuellen, in die Sitzung gebracht. Dies wird auf der Sitzungsebene getan, weil Datasources in auf der Benutzer-Login ab. Es ist nun möglich, den Zugang zu haben, um sie aus der Anwendung heraus. Um die aktuelle Datasource zu ändern habe ich ein Servlet mit dieser vereinfachten Version:

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

  }

}

Mit dieser Implementierung ist es nun möglich, die folgenden jsps zu erstellen:

<%@ 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>

Hoffe, es hilft jemand anderes.

Andere Tipps

Erstellen Sie die Datenquellen in einer ServletContextListener und legen sie sie in der ServletContext .

Dieser Ansatz wird sicherlich „arbeiten“, aber die Vorstellung einer separaten, identischen Datenbank für jedes Geschäft scheint mir falsch. Sicherlich Unternehmen in der Lage zu beschreiben irgendwo im Schema scheint möglich. sie auf diese Weise zu trennen erfordert eine neue Datenbank pro Geschäft, in dem ein Schema nur eine neue Business-Kennung erfordern würde.

Ich würde auch argumentieren, dass jede Möglichkeit der Quer Business Data Mining verloren, es sei denn, Sie ETL Daten aus verschiedenen Datenbanken in einen dimensionalen Würfel für Ad-hoc-Reporting und Abfragen.

Und JSTL Tags sollten nur in den einfachsten Web-Anwendungen verwendet werden. Sie verlassen sich offen für die Möglichkeit von SQL-Injection-Angriffe, wenn Sie die Validierung auf einer mittleren Ebene verzichten.

UPDATE:

Sie müssen Ressourcen in Ihrem web.xml erklären AFAIK, so, wenn Sie eine neue Datenbank haben, müssen Sie die Anwendung beenden, konfigurieren Sie die neue JNDI Quelle und starten Sie Tomcat neu. Ich hoffe, Sie gruppierten, weil alle bisherigen Kunden werden durch die App wird nach unten jedes Mal, wenn ein neues Geschäft / Datenbank hinzufügen betroffen sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top