l 用作JavaBean的类必须具有一个公共的、无参数的构造方法(因为在引用的时间它自动调用的是无参的构造方法),这个方法可以是通过编译器自动产生的那个缺省构造方法。
l JavaBean的属性通过遵循某种规范的公共方法暴露给外部,外部的其他程序可以通过Java 的反射API 来查找JavaBean中遵循这一规范的方法,从而发现JavaBean中的属性。
l 在JSP中如何使用JavaBean
l <jsp:useBean>标签
l <jsp:setProperty>标签
l <jsp:getProperty>标签
<jsp:useBean
id="myDate"class="java.util.Date"
scope="page"></jsp:useBean>
<%--pageContext.setAttribute("myDate",new java.util.Date()) ;--%>
<jsp:getProperty
name="myDate"
property="year"/>,
JavaBean的本质就是:
<%-- pageContext.setAttribute("myDate",new java.util.Date());--%>
然后利用<jsp:getProperty
name="myDate"
property="year"/>,可以打印出来,
这一话的真正含义又相当于<%=((Date)pageContext.findAttribute("myDate")).getYear() %>,
也可以对其进行赋值:<jsp:setProperty
name="myDate"
property="year"value="${120}"/>
其本质就是在JSP页面进行JAVA类的操作。
EL表达式:
l EL 全名为Expression Language。EL主要作用:
l 获取数据:
• EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)
l 执行运算:
• 利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}
l 获取web开发常用对象
• EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
l 调用Java方法
• EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
取值:
l 使用EL表达式获取数据语法:“${标识符}”
l EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回””(注意,不是null,而是空字符串)。
更加准备的说法是:先看看是不是那11个隐含对象,如果是,则按照隐含对象处理,如果不是则按照在四个作用域里面找。
l EL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
• ${user.address.city}
• ${user.list[0]}:访问有序集合某个位置的元素
• ${map.key}
:获得map集合中指定key的值
l 结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,示例:
• 迭代数组
• 迭代collection类型集合
• 迭代map类型集合
执行运算:
获得web开发常用对象:
l EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
l 语法:${隐式对象名称}
:获得对象的引用
隐含对象名称 |
描 |
pageContext |
对应于JSP页面中的pageContext对象(注意:取的是pageContext对象。) |
pageScope |
代表page域中用于保存属性的Map对象 pageScope.get(“userName”)à${pageScope.userName} |
requestScope |
代表request域中用于保存属性的Map对象 requestScope.get(“userName”)à${requestScope.userName} |
sessionScope |
代表session域中用于保存属性的Map对象 …… |
applicationScope |
代表application域中用于保存属性的Map对象 ….. . |
隐含对象名称 |
描 述 |
param |
表示一个保存了所有请求参数的Map对象 |
paramValues |
表示一个保存了所有请求参数的Map对象,它对于某个请求参数, 返回的是一个string[] |
header |
表示一个保存了所有http请求头字段的Map对象 |
headerValues |
同上,返回string[]数组。注意:如果头里面有“-” 例Accept-Encoding,则要headerValues[“Accept-Encoding”] |
cookie |
表示一个保存了所有cookie的Map对象 |
initParam |
表示一个保存了所有web应用初始化参数的map对象 |
在这11个中,只有一个pageContext就够了,因为它能够获得其它8个JSP中的内置对象,并且可以获得它相应的方法属性,十分好啊
如果是String[]数组可以用${headerValues.host[0]}取,如果是Map对象:
${cookie.JSESSIONID.value}
有时它与javascript相似,可以用点也可以用[‘aaa’].
如何记住这11个内置对象:
四个作用域,来源去脉。
URI就是一个标识符,不是一个网址,任何才行,只不过与URL在字母上相似,它们没有关系。
使用EL调用Java方法:
l EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。
• 示例:${prefix:method(params)}
• 在EL表达式中调用的只能是Java类的静态方法。
• 这个Java类的静态方法需要在TLD文件中描述,才可以被EL表达式调用。
• EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。
l 一般来说, EL自定义函数开发与应用包括以下三个步骤:
• 编写一个Java类的静态方法
• 编写标签库描述符(tld)文件,在tld文件中描述自定义函数。
• 在JSP页面中导入和使用自定义函数
l 编写完标签库描述文件后,需要将它放置到<web应用>\WEB-INF目录中或WEB-INF目录下的除了classes和lib目录之外的任意子目录中。
l TLD文件中的<uri> 元素用指定该TLD文件的URI,在JSP文件中需要通过这个URI来引入该标签库描述文件。
l <function>元素用于描述一个EL自定义函数,其中:
• <name>子元素用于指定EL自定义函数的名称。
• <function-class>子元素用于指定完整的Java类名,
• <function-signature>子元素用于指定Java类中的静态方法的签名,方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间用逗号分隔。
l EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。
l 注意:有些Tomcat服务器如不能使用EL表达式
(1)升级成tomcat6
(2)在JSP中加入<%@ pageisELIgnored="false" %>
<%@taglib
uri="chenxiaojian"prefix="chen"
%>
<%pageContext.setAttribute("content","<meta
http-equiv='Refresh'content='0;url=http://www.it315.org'/>");
%>
${chen:trans(content) }
Servlet事件监听器:
l 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
l 在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession
和 ServletRequest
这三个域对象,即监听器就只能监听这三个对象。
l Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。
l 监听三个域对象创建和销毁的事件监听器
l 监听域对象中属性的增加和删除的事件监听器
l 监听绑定到 HttpSession
域中的某个对象的状态的事件监听器。(查看API文档)
l 和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。
l 和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。
l 一个 web.xml
文件中可以配置多个 Servlet
事件监听器,web 服务器按照它们在 web.xml
文件中的注册顺序来加载和注册这些 Serlvet
事件监听器。
感知 Session
绑定的事件监听器:
l 保存在 Session
域中的对象可以有多种状态:绑定到
Session 中;从 Session
域中解除绑定;随 Session
对象持久化到一个存储设备中;随 Session
对象从一个存储设备中恢复
l Servlet
规范中定义了两个特殊的监听器接口来帮助 JavaBean
对象了解自己在 Session
域中的这些状态:HttpSessionBindingListener接口和HttpSessionActivationListener接口,实现这两个接口的类不需要
web.xml 文件中进行注册
l 实现了HttpSessionBindingListener接口的 JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件
l 当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的 voidvalueBound(HttpSessionBindingEvent event) 方法
l 当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法
l 实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件
l 当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEvent event) 方法
l 当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用该对象的 void sessionDidActive(HttpSessionBindingEvent event)方法
l
序列化:
ObjectOutputStream.把一个对象存到硬盘或者网络上,它会把一个对象转换成二进制字节,那么想要被这个类操作的类,必须实现seriable接口,这就是它的作用,把对象在内存中的状态存储到硬盘上,然后用的时间再取出来。
聊天室:
Redirect after post模式。
用post提交后,再用redirect
我的一个疑惑:解决首页访问问题,
以jsp页面写上:<jsp:forwardpage="/chat/RegisterUI"></jsp:forward>
交给serlvet后再转到相应的注册页面。这也解决了SSH中jobsys的问题。
Request.setAttribute与getAttribute常常与getRequestDispathcher结合在一起用。
在DAO层设计单例。在内存中我们模拟的数据库肯定是在一块内存区,所以在DAO层写一个单例。很重要,要用静态方法的和静态常量。十分重要。
<c:forEach
items="${userSessions}"
var="session">
<%HttpSessionuserSession = (HttpSession)pageContext.findAttribute("session");
%>
<%= ((User)userSession.getAttribute("user")).getUsername()
%><br/>
</c:forEach>
精解代码:
想用标签必须 先声明:<%@tagliburi="http://java.sun.com/jsp/jstl/core"
prefix="c"%>
items="${userSessions}"底层调用pageContext.findAttribute(“”)方法先从page、request,session、application依次从小到大找寻,找到则停止(易知:本例中是从application中找寻的)。这个foreach循环的意思是这样的,每次循环的值赋值给var="session",然后在循环内部调用${session}它就是在page这个范围内找,明白了吧。
我们知道userSessions是一个list集合,泛型是HttpSession,所以用pageContext.findAttribute("session")获取这个session,然后从session中取出它的值(session是一个map类型),取出的值是一个User对象,再调用它的对象的方法即可。
302问题:
其实就是重写的问题,我们发送sendRedirect后,服务器发过去给客户端的状态码就是302表示已移动,这句话从本质上来讲是这样的,
response.setStatus(302);
response.setHeader("Location",request.getContextPath()+"/chat/ListInfo");