在Java Web开发中,Expression Language(EL)和JavaServer Pages Standard Tag Library(JSTL)是提升代码可读性、减少脚本元素并增强页面功能的关键工具。本文将通过一个完整的产品管理系统实例,深度解析如何利用EL表达式和JSTL标签库进行数据绑定和逻辑控制,同时总结它们之间的区别及应用场景。
20.1 项目背景与目标
为了更好地理解EL和JSTL的应用,我们将构建一个简单的Web产品管理系统。系统包括产品的增删改查操作,展示产品的列表以及详情页面,使用EL表达式处理后端传来的数据,并运用JSTL进行循环、条件判断等逻辑控制。
20.2 技术概述
- Expression Language (EL):EL提供了一种简洁的方式来访问JavaBean对象、Servlet上下文、请求参数等数据源中的数据,无需编写Java代码即可实现数据的动态绑定。
- JavaServer Pages Standard Tag Library (JSTL):JSTL包含一系列标签库,用于替换传统的Scriptlet,简化了迭代、条件判断、流程控制、URL操作等功能的实现。
20.3 代码示例
- 产品列表页(products.jsp)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <title>Product List</title> </head> <body> <h1>Products</h1> <!-- 使用c:forEach遍历产品列表 --> <c:forEach var="product" items="${productList}"> <div> <h2>${product.name}</h2> <p>Price: ${product.price}</p> <a href="productDetails?id=${product.id}">View Details</a> </div> </c:forEach> </body> </html>
- 产品详情页(productDetails.jsp)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <title>Product Details</title> </head> <body> <h1>Product Details</h1> <c:if test="${not empty product}"> <div> <h2>${product.name}</h2> <p>Price: ${product.price}</p> <p>Description: ${product.description}</p> </div> </c:if> <c:if test="${empty product}"> <p>No product found with the given ID.</p> </c:if> </body> </html>
- Servlet处理请求并设置属性
@WebServlet("/productDetails") public class ProductDetailsServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int productId = Integer.parseInt(request.getParameter("id")); // 假设getProductById是从数据库获取产品信息的方法 Product product = getProductById(productId); request.setAttribute("product", product); // 设置属性供JSP页面使用 RequestDispatcher dispatcher = request.getRequestDispatcher("productDetails.jsp"); dispatcher.forward(request, response); } }
20.4 区别总结
- EL: 主要用于数据绑定,从作用域对象中获取或计算值,如
${product.name}
。 - JSTL: 提供了一系列标签来执行循环、条件判断、异常处理、输出等任务,增强了JSP的功能性和可维护性。
20.5 应用场景总结
- EL: 在任何需要动态显示数据的地方,例如显示用户信息、商品价格、查询结果等。
- JSTL:
c:forEach
标签可用于遍历集合数据,渲染列表、表格等内容。c:if
,c:choose
,c:when
,c:otherwise
等标签可以用来做条件分支判断。- 还有其他标签如
fmt
标签库处理国际化与格式化,sql
标签库处理SQL操作等。
20.6 进阶功能与扩展
在产品管理系统中,我们还可以进一步利用EL和JSTL实现更多高级功能,例如分页显示、搜索过滤等。
分页示例:
假设我们的产品列表需要分页展示,可以使用EL和JSTL结合Java代码处理分页逻辑,并动态渲染页面内容。
<!-- products.jsp --> ... <c:forEach var="product" items="${currentPageProducts}"> <!-- 显示产品信息 --> </c:forEach> <!-- 分页导航栏 --> <div> <c:if test="${not firstPage}"> <a href="?page=1">First</a> <a href="?page=${previousPage}">Previous</a> </c:if> <c:forEach var="i" begin="1" end="${totalPages}"> <c:choose> <c:when test="${currentPage eq i}"> <span>${i}</span> </c:when> <c:otherwise> <a href="?page=${i}">${i}</a> </c:otherwise> </c:choose> </c:forEach> <c:if test="${not lastPage}"> <a href="?page=${nextPage}">Next</a> <a href="?page=${totalPages}">Last</a> </c:if> </div>
在Servlet中,根据请求参数计算当前页码及对应的产品数据,并将其设置到请求属性中:
@WebServlet("/products") public class ProductsServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int currentPage = Integer.parseInt(request.getParameter("page")) || 1; // 根据当前页码查询相应的产品列表 List<Product> currentPageProducts = getProductListByPage(currentPage); int totalPages = calculateTotalPages(); // 计算总页数 request.setAttribute("currentPageProducts", currentPageProducts); request.setAttribute("currentPage", currentPage); request.setAttribute("totalPages", totalPages); RequestDispatcher dispatcher = request.getRequestDispatcher("products.jsp"); dispatcher.forward(request, response); } }
搜索过滤示例:
同样地,如果需要添加搜索功能,可以在JSP页面中使用表单提交搜索关键词,然后在Servlet中处理并返回结果。
<!-- searchForm.jsp --> <form action="searchResults" method="post"> <input type="text" name="keyword" placeholder="Search for products..."> <button type="submit">Search</button> </form>
@WebServlet("/searchResults") public class SearchResultsServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String keyword = request.getParameter("keyword"); List<Product> searchedProducts = searchProducts(keyword); request.setAttribute("searchedProducts", searchedProducts); RequestDispatcher dispatcher = request.getRequestDispatcher("searchResults.jsp"); dispatcher.forward(request, response); } } <!-- searchResults.jsp --> <c:forEach var="product" items="${searchedProducts}"> <!-- 显示搜索结果 --> </c:forEach>