JSP调用自定义打印方法无法在Tomcat网页正常显示输出问题
JSP调用自定义方法打印ResultSet无法在网页正常显示
我在Tomcat上运行Web应用,自定义了ResultsPrinter类的printResultSet方法,用System.out.println()打印ResultSet内容,但在JSP中调用时,输出没法在网页正常显示,预期的表格只会出现在Tomcat控制台里。
问题代码
ResultsPrinter类代码
public class ResultsPrinter { public static void printResultSet(ResultSet rs) throws SQLException { ResultSetMetaData resultSetMetaData = rs.getMetaData(); int ColumnCount = resultSetMetaData.getColumnCount(); int[] columnMaxLengths = new int[ColumnCount]; ArrayList<String[]> results = new ArrayList<>(); while (rs.next()) { String[] columnStr = new String[ColumnCount]; for (int i = 0; i < ColumnCount; i++) { columnStr[i] = rs.getString(i + 1); columnMaxLengths[i] = Math.max(columnMaxLengths[i], (columnStr[i] == null)? 0 : columnStr[i].length()); } results.add(columnStr); } printSeparator(columnMaxLengths); printColumnName(resultSetMetaData, columnMaxLengths); printSeparator(columnMaxLengths); Iterator<String[]> iterator = results.iterator(); String[] columnStr; while (iterator.hasNext()) { columnStr = iterator.next(); for (int i = 0; i < ColumnCount; i++) { System.out.printf("|%" + columnMaxLengths[i] + "s", columnStr[i]); } System.out.println("|"); } printSeparator(columnMaxLengths); } private static void printColumnName(ResultSetMetaData resultSetMetaData, int[] columnMaxLengths) throws SQLException { int columnCount = resultSetMetaData.getColumnCount(); for (int i = 0; i < columnCount; i++) { System.out.printf("|%" + columnMaxLengths[i] + "s", resultSetMetaData.getColumnName(i + 1)); } System.out.println("|"); } private static void printSeparator(int[] columnMaxLengths) { for (int columnMaxLength : columnMaxLengths) { System.out.print("+"); for (int j = 0; j < columnMaxLength; j++) { System.out.print("-"); } } System.out.println("+"); } }
JSP代码
<% try { ResultsPrinter.printResultSet(connector.query("show tables;")); } catch (SQLException e) { throw new RuntimeException(e); } %>
问题原因
System.out.println()的输出目标是Tomcat服务器的控制台/日志文件,不是JSP用来向浏览器返回内容的响应输出流,所以网页上看不到任何输出。另外,即使把输出转到响应流,浏览器默认会忽略文本中的换行和连续空格,直接输出会导致格式混乱,需要用HTML的<pre>标签保留控制台样式的格式。
解决方案
方案1:修改方法输出到JSP响应流
修改ResultsPrinter类,让方法接收JSP内置的PrintWriter对象(代表响应输出流),将内容输出到浏览器:
import java.io.PrintWriter; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; public class ResultsPrinter { public static void printResultSet(ResultSet rs, PrintWriter out) throws SQLException { ResultSetMetaData resultSetMetaData = rs.getMetaData(); int columnCount = resultSetMetaData.getColumnCount(); int[] columnMaxLengths = new int[columnCount]; ArrayList<String[]> results = new ArrayList<>(); while (rs.next()) { String[] columnStr = new String[columnCount]; for (int i = 0; i < columnCount; i++) { columnStr[i] = rs.getString(i + 1); columnMaxLengths[i] = Math.max(columnMaxLengths[i], (columnStr[i] == null) ? 0 : columnStr[i].length()); } results.add(columnStr); } // 用<pre>标签保留格式 out.println("<pre>"); printSeparator(columnMaxLengths, out); printColumnName(resultSetMetaData, columnMaxLengths, out); printSeparator(columnMaxLengths, out); Iterator<String[]> iterator = results.iterator(); String[] columnStr; while (iterator.hasNext()) { columnStr = iterator.next(); for (int i = 0; i < columnCount; i++) { out.printf("|%" + columnMaxLengths[i] + "s", columnStr[i]); } out.println("|"); } printSeparator(columnMaxLengths, out); out.println("</pre>"); } private static void printColumnName(ResultSetMetaData resultSetMetaData, int[] columnMaxLengths, PrintWriter out) throws SQLException { int columnCount = resultSetMetaData.getColumnCount(); for (int i = 0; i < columnCount; i++) { out.printf("|%" + columnMaxLengths[i] + "s", resultSetMetaData.getColumnName(i + 1)); } out.println("|"); } private static void printSeparator(int[] columnMaxLengths, PrintWriter out) { for (int columnMaxLength : columnMaxLengths) { out.print("+"); for (int j = 0; j < columnMaxLength; j++) { out.print("-"); } } out.println("+"); } }
修改JSP代码,传入out对象:
<% try { ResultsPrinter.printResultSet(connector.query("show tables;"), out); } catch (SQLException e) { throw new RuntimeException(e); } %>
方案2:返回HTML格式字符串(推荐)
让方法返回拼接好的HTML字符串,再在JSP中输出,更符合Web开发的职责分离原则:
import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; public class ResultsPrinter { public static String getResultSetAsHtml(ResultSet rs) throws SQLException { StringBuilder htmlBuilder = new StringBuilder(); ResultSetMetaData resultSetMetaData = rs.getMetaData(); int columnCount = resultSetMetaData.getColumnCount(); int[] columnMaxLengths = new int[columnCount]; ArrayList<String[]> results = new ArrayList<>(); while (rs.next()) { String[] columnStr = new String[columnCount]; for (int i = 0; i < columnCount; i++) { columnStr[i] = rs.getString(i + 1); columnMaxLengths[i] = Math.max(columnMaxLengths[i], (columnStr[i] == null) ? 0 : columnStr[i].length()); } results.add(columnStr); } htmlBuilder.append("<pre>"); printSeparator(columnMaxLengths, htmlBuilder); printColumnName(resultSetMetaData, columnMaxLengths, htmlBuilder); printSeparator(columnMaxLengths, htmlBuilder); for (String[] columnStr : results) { for (int i = 0; i < columnCount; i++) { htmlBuilder.append(String.format("|%" + columnMaxLengths[i] + "s", columnStr[i])); } htmlBuilder.append("|\n"); } printSeparator(columnMaxLengths, htmlBuilder); htmlBuilder.append("</pre>"); return htmlBuilder.toString(); } private static void printColumnName(ResultSetMetaData resultSetMetaData, int[] columnMaxLengths, StringBuilder sb) throws SQLException { int columnCount = resultSetMetaData.getColumnCount(); for (int i = 0; i < columnCount; i++) { sb.append(String.format("|%" + columnMaxLengths[i] + "s", resultSetMetaData.getColumnName(i + 1))); } sb.append("|\n"); } private static void printSeparator(int[] columnMaxLengths, StringBuilder sb) { for (int columnMaxLength : columnMaxLengths) { sb.append("+"); for (int j = 0; j < columnMaxLength; j++) { sb.append("-"); } } sb.append("+\n"); } }
JSP代码修改为:
<% try { String tableHtml = ResultsPrinter.getResultSetAsHtml(connector.query("show tables;")); out.print(tableHtml); } catch (SQLException e) { throw new RuntimeException(e); } %>
内容的提问来源于stack exchange,提问作者Allonsy Jia
相关产品推荐
相关产品推荐

