JSP ForEach循环触发JspPropertyNotFoundException,无法读取员工数据
问题分析与解决方案
你遇到的JspPropertyNotFoundException本质是JavaBean属性命名不符合规范,导致EL表达式无法正确映射到对应的getter方法,另外还有几处代码细节问题需要修正,下面逐一说明:
1. 核心问题:JavaBean属性与EL表达式的匹配错误
JavaBean规范有明确的命名规则:
- 属性名必须以小写字母开头(比如
nic而非Nic) - getter方法命名为
get+首字母大写的属性名(比如getNic()对应属性nic)
你的Person和Employee类中,属性名都是大写开头(Nic, Name, Specialization等),而EL表达式解析${emp.Nic}时,会按照规范尝试寻找getnic()方法(而非你写的getNic()),自然找不到对应的属性,就抛出了异常。
修改方案:
调整实体类属性命名(首字母小写),补充缺失的getter方法
修改后的Person类:
public class Person { // 属性名改为小写开头 private String nic; private String name; private String email; private String phone; private String address; public Person(String nic, String name, String email, String phone, String address) { this.nic = nic; this.name = name; this.email = email; this.phone = phone; this.address = address; } // 保持getter方法命名符合规范 public String getNic() { return nic; } public void setNic(String nic) { this.nic = nic; } // 补充其他属性的getter/setter(原代码只写了Nic的,必须补全) public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
修改后的Employee类:
public class Employee extends Person { // 属性名改为小写开头 private String yearsOfExperience; private String specialization; private String salary; public Employee(String nic, String name, String email, String phone, String address, String yearsOfExperience, String specialization, String salary) { super(nic, name, email, phone, address); this.yearsOfExperience = yearsOfExperience; this.specialization = specialization; this.salary = salary; } public String getYearsOfExperience() { return yearsOfExperience; } // 补充缺失的getter方法!原代码没有这两个,EL表达式无法访问 public String getSpecialization() { return specialization; } public String getSalary() { return salary; } }
调整JSP页面的EL表达式(使用小写开头的属性名),同时修正HTML结构
把<tbody>移出循环(避免重复生成tbody标签,不符合HTML规范):
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <table border="1"> <thead> <!-- 建议添加表头提升可读性 --> <tr> <td>NIC</td> <td>Name</td> <td>Email</td> <td>Phone</td> <td>Address</td> <td>Years of Experience</td> <td>Specialization</td> <td>Salary</td> </tr> </thead> <tbody> <c:forEach var="emp" items="${employeeDetails}"> <tr> <td>${emp.nic}</td> <td>${emp.name}</td> <td>${emp.email}</td> <td>${emp.phone}</td> <td>${emp.address}</td> <td>${emp.yearsOfExperience}</td> <td>${emp.specialization}</td> <td>${emp.salary}</td> </tr> </c:forEach> </tbody> </table>
2. 其他需要修正的细节
- 数据库资源泄漏问题:你的
EmployeeDBUtil.viewAllEmployee()方法没有关闭Connection、Statement、ResultSet,会导致数据库连接耗尽,建议在finally块中关闭资源:
public static List<Employee> viewAllEmployee() { ArrayList <Employee> emp = new ArrayList<>(); try { con = DBconnection.getConnection(); stmt = con.createStatement(); String sql = "Select * from employee"; rs= stmt.executeQuery(sql); while(rs.next()) { String nic= rs.getString(1); String name = rs.getString(2); String email = rs.getString(3); String phone =rs.getString(4); String address =rs.getString(5); String yearsOfExperience =rs.getString(6); String specialization =rs.getString(7); String salary =rs.getString(8); Employee e = new Employee(nic,name,email,phone,address,yearsOfExperience,specialization,salary); emp.add(e); System.out.println("im here"); } }catch(Exception e){ e.printStackTrace(); } finally { // 按顺序关闭资源:ResultSet -> Statement -> Connection try { if(rs != null) rs.close(); if(stmt != null) stmt.close(); if(con != null) con.close(); } catch (SQLException ex) { ex.printStackTrace(); } } return emp; }
为什么数据能存入但无法显示?
数据存入数据库是因为你直接把表单参数传给了DBUtil的插入方法,和JavaBean的属性命名无关;但显示数据时,EL表达式依赖JavaBean规范来调用getter方法,命名不规范就会导致无法读取属性值,抛出异常。
按照上面的修改后,EL表达式就能正确映射到对应的getter方法,表格就能正常显示员工数据了。
内容的提问来源于stack exchange,提问作者Vcode
相关产品推荐
相关产品推荐

