如何用JSTL替代Scriptlets获取请求参数并转换JDBC结果集代码
解决方案:用JSTL替换Scriptlets并统一处理URL编码
我来帮你把这段混合了Scriptlets和JSTL的代码改成更规范的写法,同时解决URL编码的问题~
首先得说一句:尽量别在JSP里直接写JDBC代码,业务逻辑和视图混在一起不仅难维护,还容易出安全问题。更合理的做法是把数据库查询放到Servlet(或者Service层)里,把结果封装成Java对象列表再转发到JSP展示。下面分两步实现:
1. 把数据库操作移到Servlet中
先定义一个和数据库表对应的Employee实体类,用来封装每条员工数据:
public class Employee { private int id; private String firstName; private String lastName; // 构造方法、getter方法 public Employee(int id, String firstName, String lastName) { this.id = id; this.firstName = firstName; this.lastName = lastName; } public int getId() { return id; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } }
然后在Servlet里执行查询,把结果存入request域再转发到JSP:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Employee> employees = new ArrayList<>(); try { Class.forName("com.mysql.cj.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/login"; String username = "root"; String password = "your-password"; String query = "select * from employeesloginaccount"; // 用try-with-resources自动关闭资源,避免内存泄漏 try (Connection conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(query)) { while (rs.next()) { employees.add(new Employee( rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name") )); } } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); // 这里可以加异常处理,比如跳转到错误页面 } request.setAttribute("employees", employees); request.getRequestDispatcher("/your-page.jsp").forward(request, response); }
2. 在JSP中用JSTL遍历并处理URL
首先要在JSP顶部引入JSTL核心标签库:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
然后用<c:forEach>遍历员工列表,用<c:url>自动处理URL编码:
<table> <c:forEach items="${employees}" var="emp"> <tr> <td>${emp.id}</td> <td>${emp.firstName}</td> <td>${emp.lastName}</td> <td> <c:url value="/downloadFileServlet" var="downloadUrl"> <c:param name="id" value="${emp.id}" /> </c:url> <form method="get" action="${downloadUrl}"> <input style="text-align: center" type="submit" value="Save"> </form> </td> </tr> </c:forEach> </table>
关键细节说明
- 替换Scriptlets循环:用
<c:forEach>代替原来的while(rs.next()),JSTL会自动遍历request域里的employees列表,每个元素用var="emp"指代,直接通过EL表达式${emp.id}取值,比Scriptlets简洁又安全。 - 自动处理URL编码:
<c:url>标签会自动对参数进行URL编码,完全不用手动处理,你原来嵌套<%=rs.getInt(id)%>的写法不仅容易出错,也不符合JSP最佳实践,现在用EL表达式直接传参就搞定了。
退而求其次:如果暂时不想移走JSP里的JDBC代码
也可以用JSTL的SQL标签直接在JSP中处理,但还是强烈建议分离业务逻辑和视图:
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <sql:setDataSource driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/login" user="root" password="your-password"/> <sql:query var="employees" sql="select * from employeesloginaccount"/> <table> <c:forEach items="${employees.rows}" var="emp"> <tr> <td>${emp.id}</td> <td>${emp.first_name}</td> <td>${emp.last_name}</td> <td> <c:url value="/downloadFileServlet" var="downloadUrl"> <c:param name="id" value="${emp.id}" /> </c:url> <form method="get" action="${downloadUrl}"> <input style="text-align: center" type="submit" value="Save"> </form> </td> </tr> </c:forEach> </table>
内容的提问来源于stack exchange,提问作者Lollander
相关产品推荐
相关产品推荐

