12月25日——培训第31天

来源:互联网 发布:广电网络股票吧 编辑:程序博客网 时间:2024/05/16 05:51

圣诞节……西方基督徒笃信的一天,圣灵降临的一天,什么时候竟然变成了中国人津津乐道的节日了呢……全球化、国际化已经
让我们没有太多自己的东西了,今天的中国人血脉中的传统文化还能保留有多少呢?我们这些现在进行IT培训的人,又有
多少人会在乎这个呢? 无所谓……我们中国人本身就是以家族为重,一向家天下的我们不会太在乎整个国家或是民族的集体
前途发展或是利益,只要自己目前能够富有,能让自己的家庭富足就OK了,在这个社会的转型期,整体比较浮躁的时期就更
是如此吧,昨天网上看帖子还有人抵制什么圣诞节,说是中国人陷入了一种全民无文化的怪圈之中,哼,真可笑啊……说句难听
话,今天的中国人,谁TM在乎这个呢!

--------------------------------------------------------
上午课程开始:

今天的主要课程内容:
1 指令元素:page指令元素和include指令元素,重点掌握错误处理的方式
2 动作元素:有6个,其中重点掌握如何向页面中引入一个JavaBean
3 过滤器和监听器

--------------------------------------------------------
指令元素格式:<%@ %>

在一个JSP翻译单元(jsp源文件以及其他通过include指令包含进来的jsp文件)中,可以包含多个独立的page指令。
在整个翻译单元中,page指令中的属性一般情况下只能设置一次,除了pageEncoding和import属性。

page指令中有以下属性:
import属性、session属性、isErrorPage属性、errorPage属性、contentType属性、pageEncoding属性

浏览器的编码在internet浏览器的查看中去查看,响应有一个报头叫做ContentType,response.sendContentType()
方法可以设置响应的报头。

如果出现乱码:可能是请求递交的时候出现解码错误,还有pageEncoding中解码错误,数据库或是驱动程序也可能由于默认编码
是iso-8859-1导致乱码。解决乱码就是在能设置gbk的地方都设置成gbk得了

isErrorPage和errorPage属性:
在jsp页面中的数据库连接那里不需要写catch,因为翻译成的Servlet中有catch,异常会被抛到页面上去

开发的基本原则:不能有未被处理的异常!异常不能抛到页面上而是应该写到日志中去。

jsp提供的机制就是上面说的isErrorPage属性和errorPage属性。和它们相关的就是9个内置对象中的exception对象
如果isErrorPage属性设置值为true的话,那么该jsp页面上面的exception对象就完全可以使用了。

至于errorPage属性必须是个合法的url:比如errorPage="errors.jsp"

如果a页面出现异常的话,就会转到errors.jsp,异常会装到errors.jsp中的exception对象中

页面errors.jsp中的处理可以是这样子的(isErrorPage属性必须设置为true)
<%
 if(exception instanceof java.sql.SQLException)
 {
%>
  <font color=red>出现了数据库异常!!请与数据库管理员联系</font>
  <%}%>

<%
 else if(exception instanceof java.lang.NullPointerException)
 {
%>
  <font color=red>出现了空指针异常!!请与开发人员联系</font>
  <%}%>
 
在翻译过的Servlet中可以看到exception的定义:
Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
注意:由发生异常的页面转到errors.jsp页面的过程是请求的转发,也就是昨天说的RequestDispatcher的forward方法。

------------------------------------------------------

uri:uniform resourse identifier :统一资源标识符 , 它相当于一个虚拟的变量,但是对应着一个真实的地址
url:uniform resourse locator:统一资源定位符。

include指令元素:用于在翻译阶段将指定的文件加入到当前的页面中来。
类似于C语言中的#include(把头文件简单的读取出来放到程序中与之作为一个整体进行翻译。),这和java中的import
完全不一样,import只是引入一个名字空间,它不会引发文件的膨胀。
<%@include file="relativeURLspec"%>

include指令是原封不动的将include进来的页面以文本形式打开,完全的加入到当前的页面中来,并将它们作为一个
整体进行编译。file属性后面跟的文件应该是纯文本的,且该纯文本的内容符合jsp的语法。

include指令的作用:因为有些网站的头和尾几乎是固定的,所以可以考虑使用include指令来将之包含在每个页面中,
而且若这些头和尾需要变动的话,只需要改那些被include进来的头、尾文件即可,不需要每个页面每个页面的去更改。

例如:在页面a中加条尾巴:

//页面a的其他代码………………………………

<%@ include file="footer.html"%>

在footer.html中
<hr width="780">
<h1 align=center>this is a new era!!</h1>

注意如果包含html页面,那么必然有个读html页面的过程,既然符合jsp语法的都可以被包含进来,那么
在footer.html中,完全可以加上下面这行代码:
<%@ page pageEncoding="GBK" %> //告知如果读这个页面,则必须以GBK的编码去读!
不这样设置的话,肯定会出现乱码…………

页面的包含过程中经常会出现这种问题,这里注意pageEncoding和ContentType属性的设置!
pageEncoding是供容器读取而设置的编码,ContentType是供浏览器显示时指定的编码类型,这里注意pageEncoding
如果和ContentType属性中的编码类型一致的话,pageEncoding是可以省略的!可以只写
contentType或是写上pageEncoding的同时省略contentType中的charset。
contentType可以默认的指明pageEncoding,而且pageEncoding也可以默认的指明contentType中的charset。

最好就直接指明一个contentType就可以了。
----------------------------------------------------
动作元素:
JSP规范中定义了20多种动作元素,
<jsp:useBean>用来引入javaBean,它有两个作用:
1 将java对象与一个脚本变量相关联
2 在指定的作用域里面存储java对象。

<jsp:useBean id="list" class="java.util.ArrayList"/>
<%
 list.add("adfa");
 list.add("sdkalfjkfseir");
 Iterator it = list.iterator();

 ArrayList a = (ArrayList)pageContext.getAttribute("list");//useBean中的id值也可以当作作用域中的
               //属性名,也就是这个id名字既是引用,又是作用域中的
 while(it.hasNext())          //属性名!
 {
  out.println(it.next() + "<br>");
 }
%> //如果不指定作用域的话默认存到page作用域中。
--------------------------
那么下面这段代码翻译成Servlet会是什么样子的呢?
<jsp:useBean id="list" class="java.util.ArrayList" scope="page"/> //其中scope="page"可以省略。

逻辑:首先,到指定的作用域当中去找与useBean的ID同名的属性;如果存在这个属性,则直接返回属性;
如果不存在则创建一个新的对象,并且存储在指定的作用域中。

翻译后的代码大概是:
ArrayList list = null ;
list = (ArrayList)pageContext.getAttribute("list");
if(list==null)
{
 list = new ArrayList();
 pageContext.setAttribute("list");
}

<jsp:useBean id="list" class="java.util.ArrayList" type="java.util.List" scope="page"/>

type用于声明变量的句柄。type与class之间要么是接口与实现类的关系,要么是继承的关系
这样翻译后就是java.util.List list = new java.util.ArrayList() ;
如果我不加type的话,变量的句柄默认就是class啦。

-------------------------------------------------
<jsp:setProperty>:设置一个javaBean的属性。

比如我们现在写一个javaBean,名字叫做User
public class User
{
 private String name ;
 private int id ;
 还有getter和setter方法
};

<jsp:useBean id="list" class="cn.itcast.User" scope="session"/>
 <jsp:setProperty name="list" property="name" value="jsp"/> //相当于User.setName("jsp")
 //注意:如果User里面的name被改成了names的话,并且setter和getter方法也要一并改为setNames和getNames,
 //这样这里的property就得改成names了。setProperty中的property属性其实调用的是setter方法,和实体类中的
 //相应属性没什么太大的关系。对应的应该是setter方法对应的属性。
<%=list.getName()%>  //输出就是jsp!


如果写成:
<jsp:setProperty name="list" property="name" param="user"/>
这又是什么意思呢?

这时如果执行<%=list.getName()%>是null,
但是如果在地址栏后跟一个?user=xxx
那么执行的时候就会打印出xxx,这里的user相当于一个表单传入的参数,为实体类的属性name绑定一个
叫做user的参数,这个参数的值是需要单独指定的

<jsp:setProperty name="list" property="name" param="user"/>
<jsp:setProperty name="list" property="id" param="id"/>
如果地址栏后有?user=java&id=34
就打印出java和34。

还有一种形式:
<jsp:setProperty name="list" property="name"/> //仅仅对name属性设置同名参数。
或者<jsp:setProperty name="list" property="*"/> //对所有属性都同名设置参数
这两种可以说都是用同名的参数来设置属性!也就是说如果实体类中两个属性:一个是name,一个是id
那么地址栏后必须写上?name=yuanbin&id=123才能把值弄进去,如果写成别的不同名的还就不行了。

----------------------------------------------------------------
看看useBean和setProperty在登陆中的应用

用户实体类:
public class User
{
 private int id ;
 private String username ;
 private String password ;

 public boolean isValidate()
 {
  boolean result = false ;
  if("jsp".equals(username)&&"jsp".equals(password))
  {
   result = true ;
  }
  return result ;
 }
};

<form action="login.jsp" method="post">
既然同名参数设置同名属性,那么干脆在表单中把用户名和密码的文本框的name
分别命名为username和password就好,这样表单post提交之后username参数
和password参数里面分别装了用户名和密码

登陆页面中:
<body>
 <jsp:useBean id="user" class="cn.itcast.User" scope="session"/>
 <jsp:setProperty name="user" property="*"/>  //直接用这行把对应的参数设置到同名属性中就完事了
 //这样一来session中的这个user属性中就存好了用户名和密码了

 <%
  if(user.isValidate())
  {
   out.println("welcome");
  }
  else
  {
   out.println("failure!!");
  }
 %>
</body>

注意userBean动作不管登陆是否成功都会创建一个名为user对象在session中。

验证时,不能通过验证对象是否为空的方法来判断用户是不是登陆了!
User u = (User)session.getAttribute("user");
if(!u.isValidate())
{
 request.getRequestDispatcher("index.html").forward(request,response);
}
else
{

}
但是isValidate()方法一般都会读取数据库,如果每次这么判断用户是否登陆那可就太划不来了。

倒还不如我在实体类中再定义个布尔值属性来定义用户是否登陆成功。validate初始值设为false;再定义个方法用于登陆
后把这个validate设为true就可以了。validate也有getter和setter方法。

-----------------------------------------------

随机数字的程序:

首先新建一个工程:

表单页面提交给自己。

java.lang.Math.random()方法返回一个0.0到1.0之间的随机数字,乘以100后取整加1后就可以得到1到100间的随机整数了。
java.util.Random中的nextInt(int n)也可以返回随机数字。

建立一个javaBean,
public class NumBean //第一次生成这个对象的时候就得有随机数,因此得在构造方法中
{
 private int answer ;
 private String hint ; //提示信息。
 private String guess ;  //客户猜的数字,之所以使用字符串类型,是因为客户输入的未必是数字!
 private int times ;  //猜了多少次
 private boolean success; //看用户是否猜成功了

 public NumBean()
 {
  answer = (int)(Math.random()*100+1) ;
  success = false ;
  times = 0 ;
 }
 
 public void reset()
 {
  answer = (int)(Math.random()*100+1) ;
  success = false ;
  times = 0 ;
 }
 //然后是getter和setter方法,answer不需要getter和setter方法,guess不需要getter方法,
 //hint不需要setter方法,success不需要setter方法,times不需要setter方法。
 public void setGuess(String guess)
 {
  int g= -1 ;
  try
  {
   g = Integer.parseInt(guess);
  }
  catch(NumberFormatException e)
  {
   g = -1 ; //用户输入的是非数字
  }

  if(g==-1) //用户输入的是非数字
  {
   hint = "请输入正确数字" ;
  }
  else if(g < answer)
  {
   hint="请输入大一些的数字";
   }
  else if(g > answer)
  {
   hint="请输入更小的数字";
  }
  else
  {
   success = true ;
  }
  times++ ;
 }
};

应该使用useBean

<jsp:useBean id="num" class="cn.itcast.NumBean" scope="session" />
<jsp:setProperty name="num" property="*"> //这句话执行的是实体类中的setGuess方法!

<%
 if(num.isSuccess())
 {
%>
  您猜对了!!您一共猜了<%=num.getTimes()%>次!<br>
  <a href="index.jsp">您要再来一次?</a>
  <%num.reset();%>  //只要是猜成功了,那么绝对要把session中原来的属性全部改回初始值,不然就没办法继续猜了。
<%
 }
 else if(num.getTimes()==0) //从来没有猜过
 {
%>
  已经设置好了一个1到100间的数字,可以猜了!<br>
  您猜的数字是:

  <form>
  <input type=text name=guess/>
  <input type=submit/>
  </form>


<% 
 }
 else
 {
%>
 试着找一个<b><%=num.getHint()%></b>,您已经猜了<%=num.getTimes()%>次!<br>
 您猜的数字是:

//这个随机数字的jsp小程序还是很有练习价值的,老师的源代码要好好看一看……

--------------------------------------------
某培训机构的吴经理和张老师还有一期已经就业的学员王涛过来讲一下有关就业和学习心态方面的问题,
首先是王涛讲一下自己的就业经历

周五投递的简历,软通动力通知周一去,也就是今天上午10点,他九点就去了,是软通动力,人事部门的把他叫进去后,
填写一份很详细的表格,项目经验,开发平台的使用时间都包括在内,技术人员的基础面试:Sprint、Struts、
Hibernate的一些问题以及一些底层的问题,比如Servlet的init方法、service方法还有ArrayList和vector区别,
抽象类和接口区别,还问到了EJB,堆和栈的区别,JSTL标签你都用过哪些?自定义标签你写过哪些?
写一个标签要实现哪几个类?提交的时候get方法和post方法的区别,get方法显示的最大字节数1K,用在用户登陆
的时候使用post提交等,log4j如何使用?jsp有哪几大隐式对象?王涛漏掉了一个out对象,但是还有个outputStream
对象,这个对象和out对象只能得到一个,不能同时得到两个。

问题问完后,第三轮面试开始,为什么要使用Hibernate?
回答:ORM思想,封装数据

还问到上大学的时候哪一门课上的最好?打算要多少钱?(4000)为什么来我们公司(正规一些)

又来了一个女的,说这里是作外包,可能2月份就要被派到韩国去,五险一金,8日就可以上班了。

之所以来到这里,主要是张老师怕我们担心就业问题,所以一期班只要有了一个找到不错工作的,就立刻来给我们讲一讲,
王涛已经投过100来封简历了,就这个软通动力给了回复,就这么一个,其实当时去的时候心很虚,主要是那里排场比较大,
相当的正规,当时觉得可能没戏,但是没想到三轮面试一过,就通过了……最终的工资还不好说,得等最终从韩国回来后,
才好说。现在主要是人还没有招齐备,主要是王涛的英语不太能说,这是个问题。王涛强调基础,尤其是java编程思想要
好好的看一看,踏实一些,没坏处。

公司那里有个180人的团队,准备丰富到500人到600人

王涛就业后的心态问题:
丰台一家公司曾经给王涛面试过,那家公司特别的烂,好像是作搜索引擎,但是离着太远了,坐车都得两个多小时,因此没
报多大希望。当时有些希望渺茫,到底工作要找到什么时候呢?简历全部石沉大海……每天至少10封简历10封简历的投,但
就是没有回应,万一过年之前没有找到工作的话,如何向家里面说呢?王涛是个成了家的人,现在一切都是靠家里资助的,所以
心理压力是十分客观的,每天都怕有公司打电话自己没有接到。但是家里面还是比较支持的,王涛了解许多外面工作技术人员
都没有了解到的细节。
-------------------------------------------
某培训机构那里了解到我们的学习劲头不足,并且比较沉闷,担心我们的课程问题,一期学员需要某培训机构投递
简历的只有17个人,其他的人自己都有信心找到适合自己的职位。

现在是个姓吴的经理给我们讲一些鼓舞士气的话,但是很明显的,他的演讲能力还有待提高。他认为一定要跟着老师
走,不要认为自己是个消费者,就应该提出的要求老师必须服从,这是不对的,因为老师比我们清楚哪些东西重要
哪些东西不重要,他们在技术上面比我们看的更清楚,我们不能想当然的要求老师怎么样怎么样。

身体、技能、素质、机遇4方面是一个好人才不可或缺的,吴经理希望我们能够以主动的心态来投入进来,更何况4个月
的学习才进行了1个多月,就这么急于看到结果,这种想法是不对的,不要总是盯着一期学员的一举一动,没有过程就
没有结果。张老师在一期结束前1个月就压着一期的人不许发简历,吴经理说是为了让一期的学员踏实下来好好把最后的
关头把握好,其实是因为如果都早早的找到工作走了的话恐怕不利于某培训机构的广告效应……吴经理希望我们能够踏实下来
,而且以后如果有什么建议或问题的话及时联系邓丽就可以。吴经理讲话完毕,他的口才确实不是太好……

现在是张老师讲话,他也知道自己讲东西的时候有一些人并不喜欢,他说有些人来这里听课是砸场子的,自己的经验明明
比我们丰富,我们不应该挑刺,觉得我们有些时候作的过分了,比如Web服务器的工作原理方面有些学生认为是跑题了,
这让张老师十分的不满,现在张老师认为我们一期班和二期班的氛围完全不一样,我们的阅历明明有限,但是过分的挑刺了,
看现在的情形张老师好像确实的十分生气了……觉得我们好像是希望他手把手的教,而且有的人认为张老师总是吹牛皮,
这也大概起了一些负面效应,现在的问题就是张老师有些不知道怎么向我们说话了,因为张老师也知道自己好像给基础太差的
人讲起课好像效果并不好,因为他确实认为一期班的学员的基础明显好于我们,这也确实是事实,没有错。张老师也反复说
过自己在蓝点上课之所以失败就是因为蓝点学员的基础太差。

现在的气氛好像总觉得有点不大对劲,希望我和这些事情没有什么太大的关系……至于吹牛皮方面的什么东东是谁说出来的我
还真不知道,也不知道张老师是如何知道的。王涛是高中学历,简历写的是大学辍学。

3000就业的含义:是经历某培训机构课程这一过程的一个结果,不是说你自己坐在那里等着某培训机构给你找工作,这是绝对不可以的。
虽然某培训机构可以解决机遇和技能,但是素质问题是必须靠自己来培养的。保证3000就业是因为某培训机构敢于在技术方面配合,但是
还需要学员的身体和素质,一定要有学员的努力,学员一定不要有过强的个体意识,张老师认为很多人天天脑子里面想的是上当了而不是
今天讲的是什么知识点,这个东西张老师是从哪里得知的我还真是不清楚,果然底下有学员提出了一些不同的看法,杨仕明就
表达了一些自己的看法:来这里的大部分人绝对不可能是报着一种消极的心态。

……看来现在有了一些沟通方面的问题尚未解决,有了问题没有和老师及时的互动,这有时候人为的造成了一种障碍,心理上的隔膜,这样
是不好的,要重视课堂上的互动以及知识的交流,吴经理希望4个月之后能够达到脱胎换骨的程度,王涛就是,现在已经准备办理护照去
韩国了。李洁这个人很有意思,总是喜欢跳来跳去,从方正最厉害的部门没待几天就走人了,据说现在还没有安稳下来,但这确实建立
在自己强大技术的前提下。

张老师认为这个班远远不如第一个班,第一个班里面虽然高学历的人很少,但是技术强的人很多,而且张老师给我们讲了2、3天课程
就明显感觉到了班中的氛围是很有问题的,讲一些基础或是底层的东西的时候有很多人是认为跑题了,经常有一种课程进行不下去的
感觉,张老师现在明显有一种“曲高和寡”的感觉。

马蕾现在表明了一下自己的观点:班里有些人基础不是很好,希望老师能够及时的总结一些东西,但是学习能力,也就是总结老师讲解
的零散的知识点也是一种学习能力的培养,人的惰性总是需要这么来克服的,所以学员和老师之间能够互相理解一下很重要,如果
有些学员有一些认为讲的一些东西讲的乱了之类的也是应该理解的,张老师认为这种思维是有害的,不能够迁就,不锻炼自己思考问题
的能力就不可能有显著的提高,知道某种东西还要能够知道背后的情景,也就是要会猜会蒙,这也是张老师是最擅长的,但是这需要
时常反复的说,但是现在有一些人对这种讲法有逆反心理,这弄的张老师没有办法继续讲课了,确实是麻烦……

马蕾希望大家能够不要目光过分短浅,不要因为短暂的凌乱而导致心情的浮躁,这些过程对于以后是有好处的,但是有些学员的基础
太差,也不能拔得太猛。张老师现在认为班里面的人数有些太多,现在班里面的人数过于混杂,有些人要是这么学下去的话,3000是
绝对不可能到手的,所以考虑近期要安排考试,张老师的意思是即便是最后只剩下十几个人也不要紧,不合格的绝对要劝退。不同的人
听同样的课程心态是完全的不同的,你不要把某培训机构和其他培训中心横向比较,不要认为包3000就来到这里,其他培训中心要是有信心
每一个学员能够找到3000的工作的话,肯定也是会说的。

思想工作如果不作通的话,学习是不会有进展的。

王进明显表达了听张老师讲课不适应的想法,而且张老师和吴经理也表态:以后主要就是田老师主讲,张老师以后负责其他的事情,
比如视频、写书之类的。
-------------------------------------------------------
田老师觉得我们班的水平还是可以的,学习也挺上进,不像张老师说的那么糟糕,说不要让我们心里有什么太大的压力,因为他一直带我们
的课所以心里还是比较有底的……
不过话说回来,两名老师,两种截然相反的看法,总会有一个人说的是对的把?其实这也不重要,所谓不识庐山真面目,只缘
身在此山中大概就是这个意思吧。不过今天说的其他事情姑且不论,为什么张老师会有这么大的反映呢??班里只是对他的讲课
风格有一些小意见而已,希望能够系统一些,没别的意思啊,也没什么人认为上当了或是受骗了之类的,即便有的话也不可能公然
的说出来啊,那张老师又是如何知道我们这一班人的学习风气明显出了问题呢??我实在是有些不明白……

-------------------------------------------------------
一会儿要好好做做那个随机数字的例子,我以前确实没有这么用过useBean动作,感觉确实不错,现在先要讲一下表达式语言,
一会儿再给我们留时间练习。

表达式语言:是在jstl1.0的规范中提出来的,后来才被加入到jsp规范中,要想使用表达式语言,你使用的容器必须要支持jsp2.0,
tomcat5.0版本以上的肯定是支持表达式语言的,这一点不用担心。

表达式语言的形式是:${expr},具体来说,当EL应用在行为动作元素时,

例如${a+b} 在jsp页面中会被显示成为0,${a+1}会被显示为1,${1+1}会被显示为2 。

表达式语言中出现的所有变量都是引用存储在某一作用域的属性。

比如a,可能是pageContext.getAttribute("a")
假如我之前往pageContext中用setAttribute方法往“a”里面存了个new Integer(1)的话,
那么肯定${a+1}就得到2了!

但是现在问题来了,假如我的pageContext和request作用域同时存了a这个属性,那么我取哪个属性呢?
记住一点,表达式语言中出现的所有变量虽然都是引用存储在某一作用域的属性,但是在读取的时候要依次查找,也就是
找的顺序是page/request/session/application, 要是都没有找到的话,也就是返回的是null值的话,如果这个
变量参与的是数学运算的话,那么置为0!

但是如果pageContext.setAttribute("a","1");
那么${a+1}的值又会是什么呢??答案还是2, 表达式语言中是不能够进行字符串加的操作的,一定会转换成数字然后进行计算。
要是a那个属性里面设一个真正的字符串
比如:pageContext.setAttribute("a","fadjks");
那么执行${a+1}的话肯定出现内部错误!

但是如果我在任何作用域中都没有设置a属性的话,${a}会如何显示呢??
答案是什么都不显示,将之当成一个空的字符串。


pageContext.setAttribute("a",new cn.itcast.NumBean()) ;

${a.times} 会显示出javaBean中的那个实例的对应属性,这是绝对没有问题的,其他的属性诸如hint、success什么的
都是可以对应显示的,这里使用的javaBean是上面用的随机数例子中的javaBean

但是:${a.getTimes()} 是绝对不允许的!!表达式语言中是不允许调用方法的,但是有一点也要强调一下,即便是
${a.times}也是去javaBean中去找getTimes方法的,如果没有getTimes()方法的话,一样会出内部错误的!

既然有了表达式语言,那么javaBean的getter方法都可以转换为对应的表达式语言的形式:
也就是${javaBean对象名.属性名}的形式。

但是我为什么一定要把<% %> 替换成为${}呢?因为前者不是标准的xml元素,还需要转换才行,但是后者就不需要费劲转换了,也就是
表达式语言可以和xml文档兼容,而且我们看着也舒服。

所有的脚本表达式都可以换成表达式语言,但是脚本片断是不可以转换成表达式语言的,切记。

而且布尔值的getter方法是is加上属性名,而不是get加上属性名!!!!

在page指令中加上isELIgnored="false"就可以万无一失的使用EL表达式了!

-----------------------------------------------------------------
今日的总结:

1 指示元素--page指令元素和include指令元素,
page指令元素的属性:inport、 pageEncoding、contentType、isELIgnored、session、errorPage、isErrorPage
错误处理页面中的exception可用,必须设置isErrorPage为true,然后发生错误的页面中要求指明errorPage为一个响应的url

2 动作元素:有6个,今天说了两个,有useBean和setProperty
 
3 表达式语言:实质就是getter方法的使用。

明天要讲一下过滤器和监听器,这两个东西在张老师的书里没有讲,唉……

-----------------------------------------------------------------------------------------------------------------

晚上自己试着用useBean方法重写了一下老师上课时说过的例子,由于以前从来没怎么用过setProperty这种方法,所以确实不这么容易,
再加上这个随机数小游戏的逻辑也确实是……有点绕,结果花了番功夫,在这里把源代码整理出来。

其实源代码主要也就那么两部分,一是javaBean,一是jsp页面,javaBean是实体类,jsp是个自己提交给自己的页面,根据输入数字的
结果不同,会生成不同的页面

javaBean的代码:

package vo;

 

public class Ue {
 private String guessedNumber = null ; //用户猜测的数字
 private int guessedTimes = 0 ;        //用户猜测的次数
 private String hint = null ;          //提示信息
 private boolean success = false ;     //标明用户猜数字猜的是否正确,如果正确的话,值为true
 private int answer = 0 ;
 
 public Ue()
 {
  answer = (int)(Math.random()*100 + 1) ;
  success = false ;
  guessedTimes = 0 ;
  hint = "" ;
 }
 
 public void reset() //重新设置为初始值!
 {
  answer = (int)(Math.random()*100 + 1) ;
  success = false ;
  guessedTimes = 0 ;
  hint = "" ;
 }

 public int getAnswer() {
  return answer;
 }

 public int getGuessedTimes() {
  return guessedTimes;
 }

 public String getHint() {
  return hint;
 }

 public boolean isSuccess() {
  return success;
 }

 public void setGuessedNumber(String guessedNumber) {
  this.guessedNumber = guessedNumber;
  int i = 0 ;
  
      //猜测次数不为0说明已经开始猜了至少一次了
    //这里有4种情况,猜大了、猜小了、猜对了、输入不合法;
  {
   try
   {
    i = Integer.parseInt(guessedNumber);
   }
   catch(Exception e)
   {
    hint ="抱歉,您输入的数字并不合法,请您重新输入" ;
    guessedTimes ++ ;
    return ;
   }
   if(i == answer)
   {
    hint = "您猜对了!" ;
    success = true ; //只有在猜对的时候,才将它置为true!
   }
   if(i > answer)
   {
    hint = "您输入的数字大了!" ;  
   }
   if(i < answer)
   {
    hint = "您输入的数字小了!" ;
   }
  }
  guessedTimes ++ ;  //不管怎么样,每次猜完之后让猜的次数往上加1!
  
 }
 
}

你会注意到我这个javaBean在一个名叫vo的包里面,虽然我一开始也不愿意这么作,因为我的站点工程文件夹的源文件Servlet全是直接放到src目录下的,没有放到任何
包里面,所以本来这个实体javaBean本来也打算和那些源文件Servlet一并放的,但是事实证明这个javaBean如果不在一个具体的包里面它不会允许我编译通过,在调用
jsp:useBean动作时会提示无法解析class="User"这句话,甚至连编译成为Servlet都不可能,所以无奈之下我只有把这个实体类给放到了一个vo包里面,纯属无奈为之……


=================================

jsp页面的源代码如下:


<%@ page language="java" import="java.util.*" pageEncoding="GBK" isELIgnored="false" %>
<%@ page import="com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  
  </head>
 
  <body>
 
  <jsp:useBean id="num" class="vo.Ue"  scope="session"/>
  <jsp:setProperty name="num" property="*"/>
  <%--将post提交过来的参数值赋给javaBean中的同名属性! --%>
 
  <%--${num.answer}--%>
  <h1 align="center">欢迎光临猜数字小游戏</h1>
    <br><br>
    <p align="center">请您输入一个1到100之间的数字,输入后按提交按钮</p>
    <p>
  <%
   if(num.isSuccess())//如果猜对了
   {
  %>
    <h1 align="center">哈哈,您猜对了,恭喜啊!</h1>
    <p>
    <a href="guess.jsp">这么好玩,再来一次吧!</a>
  <%
    num.reset(); //重新玩的时候,要执行reset方法重新把对象信息初始化!
   }
   else if(num.getGuessedTimes()==0)//还没有开始猜,也就是第一次访问时的游戏界面
   { 
  %>
    <form name="form1" method="post">
     <TABLE align="center">
      <tr>
       <td>请输入数字</td>
       <td><input type="text" name="guessedNumber"></td>
      </tr>
      <tr>
       <td></td>
       <td><input type="submit" value="提交"></td>
      </tr>
     </TABLE>
     </form>
  <% 
   }
   else   //虽然已经猜了但是没有猜对,这里面分为4种情况,在Ue类里面已经详细分清楚了
   {
  %>
    <h3 align="center">您已经猜了${num.guessedTimes}次了</h3>
    <p align="center">${num.hint}</p>
    <p></p>
    <form name="form1" method="post">
     <TABLE align="center">
      <tr>
       <td>请输入数字</td>
       <td><input type="text" name="guessedNumber"></td>
      </tr>
      <tr>
       <td></td>
       <td><input type="submit" value="提交"></td>
      </tr>
     </TABLE>
     </form>
  <% 
   }
  %>
 
   ${num.guessedTimes}
   <br>
   ${num.answer} 
  </body>
</html>

 

说一下这道题目,其实随机数字游戏需要考虑的无非以下5种情况:
1 输入的数字过大,
2 输入的数字过小,
3 输入的数字正好等于随机数字,
4 输入的数字过长无法转化为整数或者输入的数字,
5 第一次进入页面


其中由于每次进入jsp页面都要执行setProperty方法,而setProperty方法是把表单传递过来的同名参数值设置成属性,
由于表单只是提交一个参数guessedNumber,所以每次执行setProperty方法的时候只是执行那个setGuessedNumber
就可以了。由于每次都要输入(除了第一次进来),所以业务逻辑代码就放到那个setGuessedNumber中去就可以了。
而且逻辑根据不同的情况分支分别生成了不同的hint提示,所以在jsp页面中就只需要考虑三种情况了:
一是第一次进入页面,二是非第一次进入页面,三是猜对了之后的提示页面,具体见代码就可以了。

还有就是EL表达式中的
${对象名.属性名}就是相应的对象调用属性的getter方法。

 


 

原创粉丝点击