2009-05-31 3 views
0

Я разрабатываю веб-приложение Java сервлета, которое управляет информацией из нескольких баз данных (все структурно одинаковые), каждый из которых соответствует другому «бизнесу». Пользователь выбирает «текущий бизнес», который хранится в сеансе, и приложение может отображать или изменять этот «текущий бизнес».Несколько динамических источников данных для контекста сервлета

Я хотел бы использовать ресурсы tomcat в динамическом режиме для доступа к этим предприятиям с помощью jndi. Таким образом, я могу использовать теги jstl sql или контекстные запросы в сервлетах. Я не могу определить каждый ресурс в файле web.xml, потому что он хранится в таблице SQL. Конечным результатом является то, чтобы иметь возможность написать простой JSP, который имеет такие строки:

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

или сервлеты, которые могут иметь такие строки

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

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

, где я могу получить правильный источник данных для «тока бизнес".

Я экспериментировал с написанием своих собственных ObjectFactories, полученных из javax.naming.spi.ObjectFactory, без успеха. Любые указатели на то, как легко это сделать?

ответ

2

Я, наконец, решил использовать следующее решение, состоящее из SessionListener и Servlet, которые работают следующим образом. SessionListener имеет следующий вид:

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

    } 

} 

Всякий раз, когда пользователь входит в систему и сеанс создается, список доступных DataSources, а ток один, помещаются в сессию. Это делается на уровне сеанса, потому что DataSources зависит от входа пользователя в систему. Теперь у них есть доступ к ним из приложения.Для изменения текущего DataSource я создал Servlet с этой упрощенной версией:

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 

    } 

}

С этой реализацией, что теперь можно создать следующие 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> 

Надеется, что это помогает кто-то остальное.

1

Создайте источники данных в ServletContextListener и поместите их в ServletContext.

+0

Как вы могли бы получить к нему доступ через интерфейс JNDI? – rmarimon

+0

Вы не сможете этого сделать. Возможно, в том же слушателе вы можете использовать context.bind (name, object)? –

+0

Пробовал это, но контекст, который создает tomcat, доступен только для чтения. – rmarimon

0

Этот подход, безусловно, «работает», но понятие отдельной идентичной базы данных для каждого бизнеса кажется мне неправильным. Конечно, возможность разграничения бизнеса где-то в схеме кажется возможной. Таким образом, для их разделения требуется новая база данных для бизнеса, где для схемы требуется только новый бизнес-идентификатор.

Я также утверждаю, что любая возможность кросс-бизнес-интеллектуального анализа данных теряется, если вы не используете данные ETL из отдельных баз данных в размерный куб для специальных отчетов и запросов.

И JSTL <sql> теги следует использовать только в простейших веб-приложениях. Вы отказываетесь от возможности атаки SQL-инъекций, когда вы отказываетесь от проверки на среднем уровне.

UPDATE:

Вы должны объявить ресурсы в вашем web.xml AFAIK, поэтому всякий раз, когда у вас есть новая база данных, вы должны остановить приложение, настроить новый источник JNDI, и перезапустить Tomcat. Я надеюсь, что вы сгруппированы, потому что все предыдущие клиенты будут затронуты тем, что приложение будет отключено каждый раз, когда вы добавляете новый бизнес/базу данных.

+0

Ограничение нескольких баз данных заключается в том, что они разные административные системы (не под моим контролем), представляющие несколько компаний. Я пишу модуль отслеживания дебиторской задолженности для всех компаний (не очень гламурный) и нуждаюсь в доступе к каждой компании отдельно. Что касается тегов jstl sql, я использую их только для отображения информации для каждой из компаний. – rmarimon

Смежные вопросы