JavaWeb:HTTP Status 500 - An exception occurred processing JSP page /ShowInfo.jsp at line 34---javax.el.PropertyNotFoundException: Property 'id' not found on type java.lang.String
前言:出现这个问题,要当好程序员需要培养自己的"强迫症",但仅仅是工作当中的。曾经难倒2位5年工作经验的大牛,找出这个问题能气死人
一、解决这个问题
1、提示:javax.el.PropertyNotFoundException: Property ‘id’ not found on type java.lang.String at JSP page /ShowInfo.jsp at line 34
提示显示错误发生在,34行
<td>${info.id }</td>
2、实际错误:at line 32
错误:多了一个空格
<c:forEach items="${infoList } " var="info">
正确:
<c:forEach items="${infoList }" var="info">
3、错误demo
<%@page import="com.dao.InfoDao"%>
<%@page import="com.model.Info"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 表格前信息展示 -->
用户:${realName }
<a href="DoLogout.do">登出</a>
<table border="1px">
<!-- 第一行 -->
<tr>
<td>工号</td>
<td>姓名</td>
<td>性别</td>
<td>部门</td>
<td>入职日期</td>
<td>爱好</td>
<td colspan="2"><a href="Insert.jsp">添加</a></td>
</tr>
<!-- 内容 -->
<c:forEach items="${infoList } " var="info">
<tr>
<td>${info.id }</td>
<td>${info.name }</td>
<td>${info.sex == 1? '男' : '女' }</td>
<td>${info.department }</td>
<td>${info.registed_date }</td>
<td>${info.hobby }</td>
<td><a href="Update.jsp?id=${info.id }&name=${info.name}&sex=${info.sex}&department=${info.department}®isted_date=${info.registed_date}&hobby=${info.hobby}">修改</a></td>
<td><a href="DoDelete.do?id=${info.id }">删除</a></td>
</tr>
</c:forEach>
</table>
<!-- 模糊查询 -->
<form action="DoSelect.do" method="post">
模糊查询:<input type="text" name="check">
<input type="submit" value="查询">
</form>
</body>
</html>
二、论强迫症
1、每个程序员的必修课:问题发现
从接触编程开始,就开始训练缩进,无论是前端的Html和编程语言C、C++、Java、甚至必须存在缩进的Python,都在培养程序员的"强迫症",实则是规范。有人问为什么?
“没有为什么,就是这么规定的”,虽然直接,这是最不负责任的回答。接下来明确给出答案:
首先、有的问题是语法问题,就跟一门生活中的语言一样,有自己的说法和语法,遵循人为规定就好。这类问题只有初学者才会犯错,倘若高手犯错,debug也是分分钟的事情。
其次、是逻辑问题,这个在于逻辑清晰与否。条件和循环的边界是出现这些问题的关键,处理这些问题,在于想没想清楚。
最终、就是这,简单到能气死人的Bug。处理这类错误的办法也有,就是从网上搜索,看有没有同样被气得半死的程序猿。但是,一旦网上找不到,没有像你这样”马虎“出现同样”愚蠢“的错误,那就是真的干瞪眼。这个错误,真的找起来烦死人,从后台数据库中列的命名、Dao层的数据查找SELECT,到JavaBean中的成员变量名和getter方法,全部都可能是问题。找2个小时是它,找一天也是他。写代码容易,改代码找错误难。
”有经验的程序员做的事情是,重新写一份“
这个简单的Demo还算简单,2个小时内能搞定,但是,重写1个大型项目着急不着急?这个问题永远存在,一些程序员加班要解决问题。
2、代码千千万,强迫症要泛:问题归因
首先、是缩进,为了清晰结构,这个必不可少。Python更是以缩进替代括号。是个程序员就要缩进,不必赘述。
其次、是“强迫症”,有一些貌似多余的格式。以一小段python代码为例:
result1=str(4+(9*5+3))+"ripper"
result2 = str(4 + (9 * 5 + 3)) + "ripper"
print(result1, result2)
同样是一样的结果,result2这种表达看起来更清晰。当我们学习编程的时候,最初始学习C语言的时候缩进也是没有不会报错的。但是缩进是必需品,这是因为缩进能让结构清晰,python更是使用缩进替代了括号和换行替代分号。同样,运算符、逻辑符号和赋值符号等简单操作符之间需要添加空格,为了一个简单又实在的需求----清晰,和缩进一样是必不可少的。
另一小段python代码为例:
string1 = "There is a sample which is too long and we need to cut to two pieces in two different line."
string2 = "There is a sample which is too long"
string2 += "and we need to cut to two pieces in two different line."
print(string1, string2)
bool1 = True and 10 > 9 and {1, 2, 4} > {1} and "Ripper" > "Aaron" and [34] > [3, 5] and not "" and not [] and bool(1)
boolTemp1 = True and 10 > 9 and {1, 2, 4} > {1} and "Ripper" > "Aaron"
boolTemp2 = [34] > [3, 5] and not "" and not [] and bool(1)
bool2 = boolTemp1 and boolTemp2
print(bool1, bool2)
这里不赘述哪个好,笔者认为第二个更清晰。第一种写法太长了,没有耐心看完。
另一小段C++代码为例:
int max(int num1, int num2)
{
// 局部变量声明
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
int max(int num1, int num2)
{
return num1 - num2;
}
int max(int num1, int num2)
{
return num1 + num2;
}
//**********华丽的分割线************华丽的分割线************华丽的分割线**********
// ***********************************************************
// 函数返回两个数中较大的那个数
int max(int num1, int num2)
{
// 局部变量声明
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
// ***********************************************************
// ***********************************************************
// 函数返回两个数的差值
int max(int num1, int num2)
{
return num1 - num2;
}
// ***********************************************************
// ***********************************************************
// 函数返回两个数的加和
int max(int num1, int num2)
{
return num1 + num2;
}
// ***********************************************************
不难看出差别,华丽的分割线后清晰的能看到是几个函数,每个函数开头都有对于这个函数详细的说明。
笔者写到这里,自然而然回想与思念国外读金融工程(MFE)研究生期间的授课老师----一位络腮胡和头发花白的老爷子学习C++的过程。每次上课,为我们debug的时候,70多岁的老爷子单膝跪地一点一点改格式,改成"强迫症的格式"。每周跟他探讨小组金融项目(C++程序)时候,老爷子每次都是不和你讨论项目先改个半个小时,并喊着“evil~~~, evil~~~.”。 当时,虽然知道"强迫症"对编程没有坏处,但是这老爷子有点过了。只有工作时间渐渐增长,才明白当时的"强迫症"我已经渐渐认同并学习了过来。