Jakarta ee 动态JDBC凭据

Jakarta ee 动态JDBC凭据,jakarta-ee,jdbc,datasource,Jakarta Ee,Jdbc,Datasource,我正在开发一个JavaEEWeb应用程序。我希望web应用程序使用JDBC连接池 在应用服务器中定义数据源非常简单。我的问题是,所有数据库连接都是使用相同的凭据(用户/密码)创建的,我需要的是,根据访问web应用程序的用户的不同,应用程序使用已访问web应用程序的用户的凭据获得数据库连接 我正在使用JBoss应用服务器和Oracle数据库。我不知道有现成的解决方案(仅限配置)和数据源 但您可以实施它,看看这些方法: 在每个请求的基础上使用普通JDBC打开数据库连接。您可以在javax.serv

我正在开发一个JavaEEWeb应用程序。我希望web应用程序使用JDBC连接池

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


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

我不知道有现成的解决方案(仅限配置)和数据源

但您可以实施它,看看这些方法:

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

  • 如果您没有耗尽资源(连接数等),也可以在每个会话的基础上处理它。使用
    HttpSession.setAttribute()
    将连接放入会话范围。在这种情况下,还要在过滤器中进行额外检查,以确保连接仍然有效(这将处理超时、关闭的套接字等)。如果会话无效,请关闭连接(可以在
    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);
    }
}
此代码仅用于说明(您应该使用
request.getRemoteUser()
,密码应该存储在其他地方,…)


我已经使用PostgreSQL对其进行了测试:在这种情况下,它的速度足够快,可以根据请求进行测试。

我不知道有现成的解决方案(仅限配置)和数据源

但您可以实施它,看看这些方法:

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

  • 如果您没有耗尽资源(连接数等),也可以在每个会话的基础上处理它。使用
    HttpSession.setAttribute()
    将连接放入会话范围。在这种情况下,还要在过滤器中进行额外检查,以确保连接仍然有效(这将处理超时、关闭的套接字等)。如果会话无效,请关闭连接(可以在
    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);
    }
}
此代码仅用于说明(您应该使用
request.getRemoteUser()
,密码应该存储在其他地方,…)


我已经使用PostgreSQL对其进行了测试:在这种情况下,它的速度足够快,可以根据请求进行测试。

这只是一个建议:使用安全域研究数据源安全配置,而不是使用用户名和密码。我不知道有现成的解决方案(仅配置)和数据源。但是实现它并不是一个大任务。你说实现它不是一个大任务,你能给我一个关于如何实现它的线索吗?这只是一个建议:使用安全域研究数据源安全配置,而不是用户名和密码。我不知道有现成的解决方案(仅配置)以及数据来源。但是实现它不是一个大任务。你说实现它不是一个大任务,你能给我一个如何做的线索吗?谢谢你的回复,但我需要从服务器中定义的数据源获取连接。谢谢你的回复,但我需要从服务器中定义的数据源获取连接。