我正在开发一个Java EE Web应用程序。我希望Web应用程序使用JDBC连接池。
在应用程序服务器中定义DataSource非常简单。我的问题是所有数据库连接都是使用相同的凭据(用户/密码)创建的,我需要的是,根据访问Web应用程序的用户,应用程序获得与用户凭据的数据库连接已经加入了Web应用程序。
我正在使用JBoss应用程序服务器和Oracle数据库。
答案 0 :(得分:1)
我不知道开箱即用的解决方案(仅限配置)以及数据源。
但你可以实现它,看看这些方法:
基于每个请求使用普通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);
}
}
并在您的servlet中,例如:
final Connection conn = (Connection) request.getAttribute("dbConnection");
此代码仅供参考(您应使用request.getRemoteUser()
,密码应存储在其他地方,...)
我使用PostgreSQL测试过它:在这种情况下,它足够快,可以在请求的基础上进行测试。