1

我正在开发一个 Java EE Web 应用程序。我希望 Web 应用程序使用 JDBC 连接池。

在应用程序服务器中定义数据源非常容易。我的问题是所有数据库连接都是使用相同的凭据(用户/密码)创建的,而我需要的是,根据访问 Web 应用程序的用户,应用程序使用用户的凭据获得数据库连接已访问 Web 应用程序。

我正在使用 JBoss 应用程序服务器和 Oracle 数据库。

4

1 回答 1

1

我不知道开箱即用的解决方案(仅限配置)以及数据源。

但是你可以实现它,看看这些方法:

  • 在每个请求的基础上使用普通 JDBC 打开数据库连接。您可以在 a 中打开和关闭连接,javax.servlet.Filter以确保您没有泄漏连接。HttpServletRequest.setAttribute()例如,使用 将连接放入请求范围。这对于某些数据库来说足够快,但对于其他数据库来说可能太慢了。

  • 如果您没有用完资源(连接数等),您也可以在每个会话的基础上处理它。使用 . 将连接放入会话范围HttpSession.setAttribute()。在这种情况下,还要对过滤器进行额外检查,以确保连接仍然有效(这会处理超时、关闭的套接字等)。如果会话无效,请关闭连接(您可以在 a 中执行此操作HttpSessionListener)。

这些都是简单的方法。您可以改进第一个:在请求之间保持连接打开,在一段时间不活动后关闭。

至于第一个选项,一些代码:

过滤器:

@WebFilter("/pages/public/web/filter/dbconn/*")
public class DbConnectionFilter implements Filter {
    private final static Db db = new Db();

    public void init(FilterConfig fc) throws ServletException {
    }

    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) req;

        try {
            final Connection conn = db.getConnection(
                    request.getParameter("user"),
                    request.getParameter("password"));
            try {
                request.setAttribute("dbConnection", conn);
                chain.doFilter(req, resp);
            } finally {
                request.removeAttribute("dbConnection");
                conn.close();
            }
        } catch (SQLException e) {
            throw new ServletException(e);
        }
    }

    public void destroy() {
    }
}

使用一个小的实用程序类:

class Db {
    private final String jdbcDriver = "org.postgresql.Driver";
    private final String jdbcUrl = "jdbc:postgresql://localhost/sandbox";

    public Db() {
        try {
            final Class<?> cls = Class.forName(this.jdbcDriver);
            final Driver driver = (Driver) cls.newInstance();
            DriverManager.registerDriver(driver);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public Connection getConnection(final String jdbcUser,
            final String jdbcPassword) throws SQLException {
        return DriverManager
                .getConnection(this.jdbcUrl, jdbcUser, jdbcPassword);
    }
}

并在您的 servlet 中,例如:

final Connection conn = (Connection) request.getAttribute("dbConnection");

此代码仅用于说明(您应该使用request.getRemoteUser(),并且密码应该存储在其他地方,...)

我已经使用 PostgreSQL 对其进行了测试:在这种情况下,它的速度足以在请求的基础上进行。

于 2013-09-02T16:05:46.450 回答