我开发管理来自多个数据库中的信息(所有结构上相同),分别对应于不同的“业务”一个Java servlet的Web应用程序。用户选择“当前业务”,其被存储在会话和应用程序可以显示或修改“当前业务”。

我想用tomcat的资源以动态的方式来访问使用JNDI这些企业。这样,我可以使用的servlet JSTL的SQL标记或上下文查找。因为它们存储在SQL表,我不能在web.xml文件中定义的每个资源。最终的结果是能够编写简单的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);

在哪儿能买到“当前企业”正确的数据源。

我已经尝试了从书面衍生javax.naming.spi.ObjectFactory没有成功我自己ObjectFactories。如何轻松地做到这一点的任何指针?

有帮助吗?

解决方案

我最终解决以下解决方案,由上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); 

  }

}

每当创建一个用户登录和会话,可用数据源的列表,以及当前的,被放置到会话中。这是在会话级别,因为数据源取决于在用户登录完成。现在可以有从应用程序中的他们访问。要改变当前数据源我创建与该简化版本一个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>

希望它可以帮助别人。

其他提示

创建在的ServletContextListener 并将它们放置在 ServletContext的

这个方法肯定会“工作”,但对于每个业务独立,相同的数据库的概念似乎是错误的我。当然能够在架构中的某个地方划定业务似乎是可能的。将它们分开这种方式要求每个企业一个新的数据库,其中一个模式就只需要一个新的企业标志。

我还认为,跨业务的数据挖掘的可能性丢失,除非单独的数据库,你的ETL数据转换成即席报表和查询三维立方体。

和JSTL 标记只应在最简单的网络应用程序使用。你会把自己暴露给SQL注入攻击的可能性,当你在一个中间层放弃验证。

更新:

您必须AFAIK声明在web.xml资源,所以只要你有一个新的数据库,你必须停止该应用程序,配置新的JNDI源,并重新启动Tomcat。我希望你丛生,因为所有的以前的客户将每次添加一个新的商业/数据库时,应用程序是下降的影响。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top