proxool默认提供了org.logicalcobwebs.proxool.admin.servlet.AdminServlet类,为用户提供页面查看连接池情况,包括连接池的配置信息、连接池连接的使用情况等。唯一缺陷是没有访问控制,人人都可访问(或许有,而我不知道)。本例重写AdminServlet类增加登录控制,并且增加Servlet3.0的@WebServlet注解。为简单起见,登录所用的用户名/密码直接写入AdminServlet类中。
为方便AppMain类启动时扫描到,将该类放在AppMain类所在的com.zweixhxu.springboot包的子包proxool里
AdminServlet.java
package com.zweixhxu.springboot.proxool; import org.logicalcobwebs.proxool.*; import org.logicalcobwebs.proxool.admin.SnapshotIF; import org.logicalcobwebs.proxool.admin.StatisticsIF; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebInitParam; import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.Properties; @WebServlet(urlPatterns="/proxoolPool", initParams={ @WebInitParam(name= AdminServlet.PARAM_USER_NAME, value="proxool"), @WebInitParam(name= AdminServlet.PARAM_LOGIN_PASS, value= "proxool@123"), }) public class AdminServlet extends HttpServlet { protected static final Logger LOG = LoggerFactory.getLogger(AdminServlet.class); private static final String[] STATUS_CLASSES = {"null", "available", "active", "offline"}; public static final String OUTPUT_FULL = "full"; public static final String OUTPUT_SIMPLE = "simple"; private String output; private String cssFile; private static final String STATISTIC = "statistic"; private static final String CORE_PROPERTY = "core-property"; private static final String STANDARD_PROPERTY = "standard-property"; private static final String DELEGATED_PROPERTY = "delegated-property"; protected static final String PARAM_REQ_ID = "requestId"; protected static final String PARAM_OP_TYPE = "opType"; public static final String PARAM_USER_NAME = "userName"; public static final String PARAM_LOGIN_PASS = "loginPass"; protected static final String OP_TYPE_LOGIN = "login"; private static final String SNAPSHOT = "snapshot"; private static String loginName = "proxool"; private static String loginPass = "proxool@123456"; public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); // Get output parameter. Default to OUTPUT_FULL. output = servletConfig.getInitParameter("output"); if (output != null) { if (output.equalsIgnoreCase(OUTPUT_FULL)) { output = OUTPUT_FULL; } else if (output.equalsIgnoreCase(OUTPUT_SIMPLE)) { output = OUTPUT_SIMPLE; } else { LOG.warn("Unrecognised output parameter for {}. Expected: {} or {}", this.getClass().getName(), OUTPUT_FULL, OUTPUT_SIMPLE); output = null; } } if (output == null) { output = OUTPUT_FULL; } loginName = servletConfig.getInitParameter(PARAM_USER_NAME); loginPass = servletConfig.getInitParameter(PARAM_LOGIN_PASS); cssFile = servletConfig.getInitParameter("cssFile"); } private static final DateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss"); private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static final DateFormat DATE_FORMAT_M = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00"); private static final String DETAIL = "detail"; private static final String DETAIL_MORE = "more"; private static final String DETAIL_LESS = "less"; /** * The request parameter name that defines: * <ol> * <li>{@link #TAB_DEFINITION} (default)</li> * <li>{@link #TAB_SNAPSHOT}</li> * <li>{@link #TAB_STATISTICS}</li> * </ol> */ private static final String TAB = "tab"; /** * @see #TAB */ private static final String TAB_DEFINITION = "definition"; /** * @see #TAB */ private static final String TAB_SNAPSHOT = "snapshot"; /** * @see #TAB */ private static final String TAB_STATISTICS = "statistics"; /** * The request parameter name that defines the pool */ private static final String ALIAS = "alias"; /** * If we are drilling down into a connection (on the {@link #TAB_SNAPSHOT snapshot} tab then * this points to the {@link org.logicalcobwebs.proxool.ProxyConnection#getId() ID} we are * getting detailed information for. */ private static final String CONNECTION_ID = "id"; protected static final String LOGIN_SESSION_KEY = "dbPoolLoginUser"; protected boolean checkNotLogin(HttpServletRequest request, HttpServletResponse response, String requestId){ return request.getSession().getAttribute(LOGIN_SESSION_KEY)==null; } protected boolean doLogin(HttpServletRequest request, HttpServletResponse response){ String userName = request.getParameter(PARAM_USER_NAME); String pwd = request.getParameter(PARAM_LOGIN_PASS); if (!loginName.equals(userName) || !loginPass.equals(pwd)){ LOG.error("用户{}登录失败,用户名或密码失败", userName); return false; } doLoginSuccess(request, response, userName+"="+pwd); return true; } protected void doLoginSuccess(HttpServletRequest request, HttpServletResponse response, Object result){ request.getSession().setAttribute(LOGIN_SESSION_KEY, result); } protected void doLogout(HttpServletRequest request, HttpServletResponse response){ request.getSession().removeAttribute(LOGIN_SESSION_KEY); } /** * Delegate to {@link #doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } /** * Show the details for a pool. */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Pragma", "no-cache"); PrintWriter out = response.getWriter(); String link = request.getRequestURI(); String opType = request.getParameter(PARAM_OP_TYPE); String requestId = request.getParameter(PARAM_REQ_ID); LOG.debug("ProxoolAdmin>opType={}, \"{}\".equals(opType) => {}", opType, OP_TYPE_LOGIN, OP_TYPE_LOGIN.equals(opType)); if (OP_TYPE_LOGIN.equals(opType)){ try{ if (doLogin(request, response)){ requestId = request.getSession().getId(); }else{ failedAndDispalyLoginPage("用户名或密码错误,登录失败", response, out, link); return; } }catch(Exception e){ failedAndDispalyLoginPage("系统异常:" + e.toString(), response, out, link); return; } } if ("logout".equals(opType)){ doLogout(request, response); } if (requestId==null || checkNotLogin(request, response, requestId)){ failedAndDispalyLoginPage("", response, out, link); return; } // Check the alias and if not defined and there is only one // then use that. String alias = request.getParameter(ALIAS); // Check we can find the pool. ConnectionPoolDefinitionIF def = null; if (alias != null) { try { def = ProxoolFacade.getConnectionPoolDefinition(alias); } catch (ProxoolException e) { alias = null; } } String[] aliases = ProxoolFacade.getAliases(); if (alias == null) { if (aliases.length > 0) { alias = aliases[0]; } } if (def == null && alias != null) { try { def = ProxoolFacade.getConnectionPoolDefinition(alias); } catch (ProxoolException e) { throw new ServletException("Couldn't find pool with alias " + alias); } } String tab = request.getParameter(TAB); if (tab == null) { tab = TAB_DEFINITION; } // If we are showing the snapshot, are we showing it in detail or not? String snapshotDetail = request.getParameter(DETAIL); // If we are showing the snapshot, are we drilling down into a connection? String snapshotConnectionId = request.getParameter(CONNECTION_ID); try { if (output.equals(OUTPUT_FULL)) { response.setContentType("text/html"); openHtml(out); } out.println("<div class=\"version\">Proxool " + Version.getVersion() + " <a href=\""+link+"?opType=logout&"+PARAM_REQ_ID+"="+requestId+"\">退出登录</a>"); out.println("</div>"); doList(out, alias, tab, link); // Skip everything if there aren't any pools if (aliases != null && aliases.length > 0) { StatisticsIF[] statisticsArray = ProxoolFacade.getStatistics(alias); final boolean statisticsAvailable = (statisticsArray != null && statisticsArray.length > 0); final boolean statisticsComingSoon = def.getStatistics() != null; // We can't be on the statistics tab if there are no statistics if (!statisticsComingSoon && tab.equals(TAB_STATISTICS)) { tab = TAB_DEFINITION; } doTabs(out, alias, link, requestId, tab, statisticsAvailable, statisticsComingSoon); if (tab.equals(TAB_DEFINITION)) { doDefinition(out, def); } else if (tab.equals(TAB_SNAPSHOT)) { doSnapshot(out, def, link, snapshotDetail, snapshotConnectionId, requestId); } else if (tab.equals(TAB_STATISTICS)) { doStatistics(out, statisticsArray, def); } else { throw new ServletException("Unrecognised tab '" + tab + "'"); } } } catch (ProxoolException e) { throw new ServletException("Problem serving Proxool Admin", e); } if (output.equals(OUTPUT_FULL)) { closeHtml(out); } } private void failedAndDispalyLoginPage(String failMsg, HttpServletResponse response, PrintWriter out, String link) throws IOException{ response.setContentType("text/html"); openHtml(out); displayLoginForm(out, link); out.println("<div style='color:red;'>" + failMsg +"</div>"); closeHtml(out); } private void doTabs(PrintWriter out, String alias, String link, String requestId, String tab, boolean statisticsAvailable, boolean statisticsComingSoon) throws IOException { out.println("<ul>"); out.println("<li class=\"" + (tab.equals(TAB_DEFINITION) ? "active" : "inactive") + "\"><a class=\"quiet\" href=\"" + link + "?alias=" + alias + "&"+PARAM_REQ_ID+"=" + requestId + "&tab=" + TAB_DEFINITION + "\">Definition</a></li>"); out.println("<li class=\"" + (tab.equals(TAB_SNAPSHOT) ? "active" : "inactive") + "\"><a class=\"quiet\" href=\"" + link + "?alias=" + alias + "&"+PARAM_REQ_ID+"=" + requestId + "&tab=" + TAB_SNAPSHOT + "\">Snapshot</a></li>"); if (statisticsAvailable) { out.println("<li class=\"" + (tab.equals(TAB_STATISTICS) ? "active" : "inactive") + "\"><a class=\"quiet\" href=\"" + link + "?alias=" + alias + "&"+PARAM_REQ_ID+"=" + requestId + "&tab=" + TAB_STATISTICS + "\">Statistics</a></li>"); } else if (statisticsComingSoon) { out.println("<li class=\"disabled\">Statistics</li>"); } out.println("</ul>"); } private void doStatistics(PrintWriter out, StatisticsIF[] statisticsArray, ConnectionPoolDefinitionIF cpd) throws IOException { for (int i = 0; i < statisticsArray.length; i++) { StatisticsIF statistics = statisticsArray[i]; openDataTable(out); printDefinitionEntry(out, ProxoolConstants.ALIAS, cpd.getAlias(), CORE_PROPERTY); // Period printDefinitionEntry(out, "Period", TIME_FORMAT.format(statistics.getStartDate()) + " to " + TIME_FORMAT.format(statistics.getStopDate()), STATISTIC); // Served printDefinitionEntry(out, "Served", statistics.getServedCount() + " (" + DECIMAL_FORMAT.format(statistics.getServedPerSecond()) + "/s)", STATISTIC); // Refused printDefinitionEntry(out, "Refused", statistics.getRefusedCount() + " (" + DECIMAL_FORMAT.format(statistics.getRefusedPerSecond()) + "/s)", STATISTIC); // averageActiveTime printDefinitionEntry(out, "Average active time", DECIMAL_FORMAT.format(statistics.getAverageActiveTime() / 1000) + "s", STATISTIC); // activityLevel StringBuffer activityLevelBuffer = new StringBuffer(); int activityLevel = (int) (100 * statistics.getAverageActiveCount() / cpd.getMaximumConnectionCount()); activityLevelBuffer.append(activityLevel); activityLevelBuffer.append("%<br/>"); String[] colours = {"0000ff", "eeeeee"}; int[] lengths = {activityLevel, 100 - activityLevel}; drawBarChart(activityLevelBuffer, colours, lengths); printDefinitionEntry(out, "Activity level", activityLevelBuffer.toString(), STATISTIC); closeTable(out); } } private void drawBarChart(StringBuffer out, String[] colours, int[] lengths) { out.append("<table style=\"margin: 8px; font-size: 50%;\" width=\"96%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr>"); // Calculate total length int totalLength = 0; for (int i = 0; i < colours.length; i++) { totalLength += lengths[i]; } // Draw segments for (int j = 0; j < colours.length; j++) { String colour = colours[j]; int length = lengths[j]; if (length > 0) { out.append("<td style=\"background-color: #"); out.append(colour); out.append("\" width=\""); out.append(100 * length / totalLength); out.append("%\"> </td>"); } } out.append("</tr></table>"); } private void doDefinition(PrintWriter out, ConnectionPoolDefinitionIF cpd) throws IOException { openDataTable(out); printDefinitionEntry(out, ProxoolConstants.ALIAS, cpd.getAlias(), CORE_PROPERTY); printDefinitionEntry(out, ProxoolConstants.DRIVER_URL, cpd.getUrl(), CORE_PROPERTY); printDefinitionEntry(out, ProxoolConstants.DRIVER_CLASS, cpd.getDriver(), CORE_PROPERTY); printDefinitionEntry(out, ProxoolConstants.MINIMUM_CONNECTION_COUNT, String.valueOf(cpd.getMinimumConnectionCount()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.MAXIMUM_CONNECTION_COUNT, String.valueOf(cpd.getMaximumConnectionCount()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.PROTOTYPE_COUNT, cpd.getPrototypeCount() > 0 ? String.valueOf(cpd.getPrototypeCount()) : null, STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.SIMULTANEOUS_BUILD_THROTTLE, String.valueOf(cpd.getSimultaneousBuildThrottle()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.MAXIMUM_CONNECTION_LIFETIME, formatMilliseconds(cpd.getMaximumConnectionLifetime()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.MAXIMUM_ACTIVE_TIME, formatMilliseconds(cpd.getMaximumActiveTime()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME, (cpd.getHouseKeepingSleepTime() / 1000) + "s", STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.HOUSE_KEEPING_TEST_SQL, cpd.getHouseKeepingTestSql(), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.TEST_BEFORE_USE, String.valueOf(cpd.isTestBeforeUse()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.TEST_AFTER_USE, String.valueOf(cpd.isTestAfterUse()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.RECENTLY_STARTED_THRESHOLD, formatMilliseconds(cpd.getRecentlyStartedThreshold()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.OVERLOAD_WITHOUT_REFUSAL_LIFETIME, formatMilliseconds(cpd.getOverloadWithoutRefusalLifetime()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.INJECTABLE_CONNECTION_INTERFACE_NAME, String.valueOf(cpd.getInjectableConnectionInterface()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.INJECTABLE_STATEMENT_INTERFACE_NAME, String.valueOf(cpd.getInjectableStatementInterface()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME, String.valueOf(cpd.getInjectableCallableStatementInterface()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME, String.valueOf(cpd.getInjectablePreparedStatementInterface()), STANDARD_PROPERTY); // fatalSqlExceptions String fatalSqlExceptions = null; if (cpd.getFatalSqlExceptions() != null && cpd.getFatalSqlExceptions().size() > 0) { StringBuffer fatalSqlExceptionsBuffer = new StringBuffer(); Iterator i = cpd.getFatalSqlExceptions().iterator(); while (i.hasNext()) { String s = (String) i.next(); fatalSqlExceptionsBuffer.append(s); fatalSqlExceptionsBuffer.append(i.hasNext() ? ", " : ""); } fatalSqlExceptions = fatalSqlExceptionsBuffer.toString(); } printDefinitionEntry(out, ProxoolConstants.FATAL_SQL_EXCEPTION, fatalSqlExceptions, STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.FATAL_SQL_EXCEPTION_WRAPPER_CLASS, cpd.getFatalSqlExceptionWrapper(), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.STATISTICS, cpd.getStatistics(), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.STATISTICS_LOG_LEVEL, cpd.getStatisticsLogLevel(), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.VERBOSE, String.valueOf(cpd.isVerbose()), STANDARD_PROPERTY); printDefinitionEntry(out, ProxoolConstants.TRACE, String.valueOf(cpd.isTrace()), STANDARD_PROPERTY); // Now all the properties that are forwarded to the delegate driver. Properties p = cpd.getDelegateProperties(); Iterator i = p.keySet().iterator(); while (i.hasNext()) { String name = (String) i.next(); String value = p.getProperty(name); // Better hide the password! if (name.toLowerCase().indexOf("password") > -1 || name.toLowerCase().indexOf("passwd") > -1) { value = "******"; } printDefinitionEntry(out, name + " (delegated)", value, DELEGATED_PROPERTY); } closeTable(out); } private void doSnapshot(PrintWriter out, ConnectionPoolDefinitionIF cpd, String link, String level, String connectionId, String requestId) throws IOException, ProxoolException { boolean detail = (level != null && level.equals(DETAIL_MORE)); SnapshotIF snapshot = ProxoolFacade.getSnapshot(cpd.getAlias(), detail); if (snapshot != null) { openDataTable(out); printDefinitionEntry(out, ProxoolConstants.ALIAS, cpd.getAlias(), CORE_PROPERTY); // dateStarted printDefinitionEntry(out, "Start date", DATE_FORMAT.format(snapshot.getDateStarted()), SNAPSHOT); // snapshot date printDefinitionEntry(out, "Snapshot", DATE_FORMAT.format(snapshot.getSnapshotDate()), SNAPSHOT); // connections StringBuffer connectionsBuffer = new StringBuffer(); connectionsBuffer.append(snapshot.getActiveConnectionCount()); connectionsBuffer.append(" (active), "); connectionsBuffer.append(snapshot.getAvailableConnectionCount()); connectionsBuffer.append(" (available), "); if (snapshot.getOfflineConnectionCount() > 0) { connectionsBuffer.append(snapshot.getOfflineConnectionCount()); connectionsBuffer.append(" (offline), "); } connectionsBuffer.append(snapshot.getMaximumConnectionCount()); connectionsBuffer.append(" (max)<br/>"); String[] colours = {"ff9999", "66cc66", "cccccc"}; int[] lengths = {snapshot.getActiveConnectionCount(), snapshot.getAvailableConnectionCount(), snapshot.getMaximumConnectionCount() - snapshot.getActiveConnectionCount() - snapshot.getAvailableConnectionCount()}; drawBarChart(connectionsBuffer, colours, lengths); printDefinitionEntry(out, "Connections", connectionsBuffer.toString(), SNAPSHOT); // servedCount printDefinitionEntry(out, "Served", String.valueOf(snapshot.getServedCount()), SNAPSHOT); // refusedCount printDefinitionEntry(out, "Refused", String.valueOf(snapshot.getRefusedCount()), SNAPSHOT); if (!detail) { out.println(" <tr>"); out.print(" <td colspan=\"2\" align=\"right\"><form action=\"" + link + "\" method=\"GET\">"); out.print("<input type=\"hidden\" name=\"" + ALIAS + "\" value=\"" + cpd.getAlias() + "\">"); out.print("<input type=\"hidden\" name=\"" + TAB + "\" value=\"" + TAB_SNAPSHOT + "\">"); out.print("<input type=\"hidden\" name=\"" + DETAIL + "\" value=\"" + DETAIL_MORE + "\">"); out.print("<input type=\"hidden\" name=\"" + PARAM_REQ_ID + "\" value=\"" + (requestId==null?"":requestId) + "\">"); out.print("<input type=\"submit\" value=\"More information>\">"); out.println("</form></td>"); out.println(" </tr>"); } else { out.println(" <tr>"); out.print(" <th valign=\"top\">"); out.print("Details:<br>(click ID to drill down)"); out.println("</th>"); out.print(" <td>"); doSnapshotDetails(out, cpd, snapshot, link, connectionId, requestId); out.println("</td>"); out.println(" </tr>"); long drillDownConnectionId; if (connectionId != null) { drillDownConnectionId = Long.valueOf(connectionId).longValue(); ConnectionInfoIF drillDownConnection = snapshot.getConnectionInfo(drillDownConnectionId); if (drillDownConnection != null) { out.println(" <tr>"); out.print(" <th valign=\"top\">"); out.print("Connection #" + connectionId); out.println("</td>"); out.print(" <td>"); doDrillDownConnection(out, drillDownConnection); out.println("</td>"); out.println(" </tr>"); } } out.println(" <tr>"); out.print(" <td colspan=\"2\" align=\"right\"><form action=\"" + link + "\" method=\"GET\">"); out.print("<input type=\"hidden\" name=\"" + ALIAS + "\" value=\"" + cpd.getAlias() + "\">"); out.print("<input type=\"hidden\" name=\"" + TAB + "\" value=\"" + TAB_SNAPSHOT + "\">"); out.print("<input type=\"hidden\" name=\"" + DETAIL + "\" value=\"" + DETAIL_LESS + "\">"); out.print("<input type=\"submit\" value=\"< Less information\">"); out.println("</form></td>"); out.println(" </tr>"); } closeTable(out); } } private void doSnapshotDetails(PrintWriter out, ConnectionPoolDefinitionIF cpd, SnapshotIF snapshot, String link, String connectionId, String requestId) throws IOException { long drillDownConnectionId = 0; if (connectionId != null) { drillDownConnectionId = Long.valueOf(connectionId).longValue(); } if (snapshot.getConnectionInfos() != null && snapshot.getConnectionInfos().length > 0) { out.println("<table cellpadding=\"2\" cellspacing=\"0\" border=\"0\">"); out.println(" <tbody>"); out.print("<tr>"); out.print("<td>#</td>"); out.print("<td align=\"center\">born</td>"); out.print("<td align=\"center\">last start</td>"); out.print("<td align=\"center\">last stop</td>"); out.print("<td align=\"center\">lap (ms)</td>"); out.print("<td> thread</td>"); out.print("</tr>"); ConnectionInfoIF[] connectionInfos = snapshot.getConnectionInfos(); for (int i = 0; i < connectionInfos.length; i++) { ConnectionInfoIF connectionInfo = connectionInfos[i]; if (connectionInfo.getStatus() != ConnectionInfoIF.STATUS_NULL) { out.print("<tr>"); // drillDownConnectionId out.print("<td style=\"background-color: #"); if (connectionInfo.getStatus() == ConnectionInfoIF.STATUS_ACTIVE) { out.print("ffcccc"); } else if (connectionInfo.getStatus() == ConnectionInfoIF.STATUS_AVAILABLE) { out.print("ccffcc"); } else if (connectionInfo.getStatus() == ConnectionInfoIF.STATUS_OFFLINE) { out.print("ccccff"); } out.print("\" style=\""); if (drillDownConnectionId == connectionInfo.getId()) { out.print("border: 1px solid black;"); out.print("\">"); out.print(connectionInfo.getId()); } else { out.print("border: 1px solid transparent;"); out.print("\"><a href=\""); out.print(link); out.print("?"); out.print(ALIAS); out.print("="); out.print(cpd.getAlias()); out.print("&"); out.print(TAB); out.print("="); out.print(TAB_SNAPSHOT); out.print("&"); out.print(DETAIL); out.print("="); out.print(DETAIL_MORE); out.print("&"); out.print(CONNECTION_ID); out.print("="); out.print(connectionInfo.getId()); out.print("&"); out.print(PARAM_REQ_ID); out.print("="); out.print(requestId==null?"":requestId); out.print("\">"); out.print(connectionInfo.getId()); out.print("</a>"); } out.print("</td>"); // birth out.print("<td> "); out.print(DATE_FORMAT.format(connectionInfo.getBirthDate())); out.print(" </td>"); // started out.print("<td> "); out.print(connectionInfo.getTimeLastStartActive() > 0 ? DATE_FORMAT_M.format(new Date(connectionInfo.getTimeLastStartActive())) : "-"); out.print(" </td>"); // stop out.print("<td> "); out.print(connectionInfo.getTimeLastStopActive() > 0 ? DATE_FORMAT_M.format(new Date(connectionInfo.getTimeLastStopActive())) : "-"); out.print(" </td>"); // active out.print("<td align=\"right\" class=\""); out.print(getStatusClass(connectionInfo)); out.print("\"> "); String active = " "; if (connectionInfo.getTimeLastStopActive() > 0) { active = String.valueOf((int) (connectionInfo.getTimeLastStopActive() - connectionInfo.getTimeLastStartActive())); } else if (connectionInfo.getTimeLastStartActive() > 0) { active = String.valueOf((int) (snapshot.getSnapshotDate().getTime() - connectionInfo.getTimeLastStartActive())); } out.print(active); out.print(" </td>"); // requester out.print("<td> "); out.print(connectionInfo.getRequester() != null ? connectionInfo.getRequester() : "-"); out.print(" </td>"); out.println("</tr>"); } } out.println(" </tbody>"); out.println("</table>"); } else { out.println("No connections yet"); } } private static String getStatusClass(ConnectionInfoIF info) { try { return STATUS_CLASSES[info.getStatus()]; } catch (ArrayIndexOutOfBoundsException e) { LOG.warn("Unknown status: {}", info.getStatus()); return "unknown-" + info.getStatus(); } } private void doDrillDownConnection(PrintWriter out, ConnectionInfoIF drillDownConnection) throws IOException { // sql calls String[] sqlCalls = drillDownConnection.getSqlCalls(); for (int i = 0; sqlCalls != null && i < sqlCalls.length; i++) { String sqlCall = sqlCalls[i]; out.print("<div class=\"drill-down\">"); out.print("sql = "); out.print(sqlCall); out.print("</div>"); } // proxy out.print("<div class=\"drill-down\">"); out.print("proxy = "); out.print(drillDownConnection.getProxyHashcode()); out.print("</div>"); // delegate out.print("<div class=\"drill-down\">"); out.print("delegate = "); out.print(drillDownConnection.getDelegateHashcode()); out.print("</div>"); // url out.print("<div class=\"drill-down\">"); out.print("url = "); out.print(drillDownConnection.getDelegateUrl()); out.print("</div>"); } private void openHtml(PrintWriter out) throws IOException { out.println("<html><header><title>Proxool Admin</title>"); out.println("<style media=\"screen\">"); out.println("body {background-color: #93bde6;}\n" + "div.version {font-weight: bold; font-size: 100%; margin-bottom: 8px;}\n" + "h1 {font-weight: bold; font-size: 100%}\n" + "option {padding: 2px 24px 2px 4px;}\n" + "input {margin: 0px 0px 4px 12px;}\n" + "table.data {font-size: 90%; border-collapse: collapse; border: 1px solid black;}\n" + "table.data th {background: #bddeff;text-align: left; padding-right: 8px; font-weight: normal; border: 1px solid black;}\n" + "table.data td {background: #ffffff; vertical-align: top; padding: 0px 2px 0px 2px; border: 1px solid black;}\n" + "td.null {background: yellow;}\n" + "td.available {color: black;}\n" + "td.active {color: red;}\n" + "td.offline {color: blue;}\n" + "div.drill-down {}\n" + "ul {list-style: none; padding: 0px; margin: 0px; position: relative; font-size: 90%;}\n" + "li {padding: 0px; margin: 0px 4px 0px 0px; display: inline; border: 1px solid black; border-width: 1px 1px 0px 1px;}\n" + "li.active {background: #bddeff;}\n" + "li.inactive {background: #eeeeee;}\n" + "li.disabled {background: #dddddd; color: #999999; padding: 0px 4px 0px 4px;}\n" + "a.quiet {color: black; text-decoration: none; padding: 0px 4px 0px 4px; }\n" + "a.quiet:hover {background: white;}\n"); out.println("</style>"); if (cssFile != null) { out.println("<link rel=\"stylesheet\" media=\"screen\" type=\"text/css\" href=\"" + cssFile + "\"></script>"); } out.println("</header><body>"); } private void closeHtml(PrintWriter out) throws IOException { out.println("</body></html>"); } private void openDataTable(PrintWriter out) throws IOException { out.println("<table cellpadding=\"2\" cellspacing=\"0\" border=\"1\" class=\"data\">"); out.println(" <tbody>"); } private void closeTable(PrintWriter out) throws IOException { out.println(" </tbody>"); out.println("</table>"); out.println("<br/>"); } private void printDefinitionEntry(PrintWriter out, String name, String value, String type) throws IOException { out.println(" <tr>"); out.print(" <th valign=\"top\">"); out.print(name); out.println(":</th>"); out.print(" <td class=\"" + type + "\"nowrap>"); if (value != null && !value.equals("null")) { out.print(value); } else { out.print("-"); } out.print("</td>"); out.println(" </tr>"); } private void doList(PrintWriter out, String alias, String tab, String link) throws IOException { String[] aliases = ProxoolFacade.getAliases(); if (aliases.length == 0) { out.println("<p>No pools have been registered.</p>"); } else if (aliases.length == 1) { // Don't bother listing. Just show it. } else { out.println("<form action=\"" + link + "\" method=\"GET\" name=\"alias\">"); out.println("<select name=\"alias\" size=\"" + Math.min(aliases.length, 5) + "\">"); for (int i = 0; i < aliases.length; i++) { out.print(" <option value=\""); out.print(aliases[i]); out.print("\""); out.print(aliases[i].equals(alias) ? " selected" : ""); out.print(">"); out.print(aliases[i]); out.println("</option>"); } out.println("</select>"); out.println("<input name=\"" + TAB + "\" value=\"" + tab + "\" type=\"hidden\">"); out.println("<input value=\"Show\" type=\"submit\">"); out.println("</form>"); } } /** * Express time in an easy to read HH:mm:ss format * * @param time in milliseconds * @return time (e.g. 180000 = 00:30:00) * @see #TIME_FORMAT */ private String formatMilliseconds(long time) { if (time > Integer.MAX_VALUE) { return time + "ms"; } else { Calendar c = Calendar.getInstance(); c.clear(); c.add(Calendar.MILLISECOND, (int) time); return TIME_FORMAT.format(c.getTime()); } } private void displayLoginForm(PrintWriter out, String link){ out.println("<form action=\"" + link + "\" method=\"POST\" name=\"loginForm\" onsubmit=\"return formSubmit();\">"); out.println(" <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"); out.println(" <tr><td>用户名:</td>"); out.println(" <td><input id=\""+PARAM_USER_NAME+"\" name=\""+PARAM_USER_NAME+"\" type=\"text\"></td>"); out.println(" </tr>"); out.println(" <tr><td>密码:</td>"); out.println(" <td><input id=\""+PARAM_LOGIN_PASS+"\" name=\""+PARAM_LOGIN_PASS+"\" type=\"password\"></td>"); out.println(" </tr>"); out.println(" <tr>"); out.println(" <td colspan=\"2\"><input id=\"btn\" name=\"btn\" type=\"submit\" value=\"登 录\"></td>"); out.println(" </tr>"); out.println(" </table>"); out.println(" <input name=\""+PARAM_OP_TYPE+"\" value=\""+OP_TYPE_LOGIN+"\" type=\"hidden\">"); out.println("</form>"); out.println("<script>"); out.println("function M(id){return document.getElementById(id);}"); out.println("function formSubmit(){"); out.println(" if (M(\""+PARAM_USER_NAME+"\").value==''){"); out.println(" alert(\"请输入用户名\");return false;"); out.println(" }"); out.println(" if (M(\""+PARAM_LOGIN_PASS+"\").value==''){"); out.println(" alert(\"请输入密码\");return false;"); out.println(" }"); out.println(" return true;"); out.println("}"); out.println("</script>"); } }
启动应用后,访问http://localhost:18081/proxoolPool显示登录页面,输入用户名/密码,就是@WebServlet注解里initParam配置的用户名密码登录即可
相关推荐
标题 "Spring+Hibernate+Proxool连接池" 涉及到的是在Java Web开发中,如何使用Spring框架集成Hibernate ORM框架,并结合Proxool作为数据库连接池的技术实践。这通常是为了提高应用性能,有效管理和复用数据库连接,...
Proxool是一个开源的、轻量级的Java数据库连接池实现,它提供了一种高效、灵活的方式来管理数据库连接。在某些场景下,为了保护敏感信息,如数据库的用户名和密码,我们需要对这些数据进行加密处理。"proxool连接池...
Proxool连接池是数据库连接管理的一种解决方案,它允许应用程序高效地管理和复用数据库连接,以提高系统的性能和响应速度。下面将详细讲解Proxool连接池的使用方法及其核心概念。 1. **Proxool简介** Proxool是...
Spring2.5配置proxool连接池
标题中的"spring+dwr+proxool连接池"指的是一个整合了Spring框架、Direct Web Remoting (DWR)和Proxool数据库连接池技术的应用程序。这个应用可能用于创建一个能够实时交互的Web应用程序,其中Spring提供了依赖注入...
在Java开发中,使用Hibernate作为持久层框架时,为了提高数据库操作的性能和资源利用率,通常会引入连接池技术。Proxool是Apache的一个开源项目,它提供了一个轻量级的数据库连接池实现。本篇将详细介绍如何在...
Proxool作为源码开放的项目,源自著名的开源平台SourceForge,它为Java开发者提供了一个高效且易于管理的数据库连接池解决方案。数据库连接池在多用户、多线程的应用环境中扮演着至关重要的角色,通过复用已建立的...
项目实用的proxool连接池配置文件,每个标签都有注释,可以直接拿来使用
这两个jar包的协同工作使得Java应用程序可以通过Proxool连接池管理和控制到MySQL数据库的连接。 配置Proxool时,你需要在应用的配置文件(如:`proxool.properties`)中设置一系列属性,例如: 1. `proxool.mysql....
-- proxool只能管理由自己产生的连接 --> <driver-url>jdbc:sqlserver://localhost:1433;dataBaseName=books</driver-url> - <!-- JDBC驱动程序 --> <driver-class>...
Proxool连接池使用方法 首先, 你要把下载 proxool 的 lib 下面所有的 jar 文件, 放到 WEB-INF/lib 下面, 另外, 把你的 jdbc driver 也放到相同的 lib,
Proxool 是一个高效、易用的数据库连接池,它通过提供中间代理层管理数据库连接,从而实现数据库连接的复用,提高应用程序的性能和效率。Proxool 的设计目标是为 Java 应用程序提供简单、灵活且强大的数据库连接管理...
接下来是Proxool连接池,它是一个开源的数据库连接池,用于管理数据库连接,提高数据库访问性能。Proxool通过复用已存在的数据库连接,减少创建和关闭连接的开销,从而提高了系统的效率。在Java应用程序中,开发者...
- **配置细节**:通过配置JMX代理ID和其他相关信息,可以在运行时监控和管理Proxool连接池的状态。 - **示例配置**: ```properties jmx=jmx-agent-id jmx-agent-id=my-jmx-agent jndi-name=java:jboss/data...
1. **连接池管理器(Connection Pool Manager)**:这是Proxool的核心,负责创建、管理和维护数据库连接池。它监控连接的使用情况,根据预设的策略自动增加或减少连接数量,确保系统资源的有效利用。 2. **连接池...
总结起来,SSH小框架结合Proxool连接池,为Java Web开发提供了强大的工具集,帮助开发者构建高效、可维护的业务系统。通过深入学习和实践,开发者可以提高自己的技术水平,更好地应对复杂的项目挑战。