现在的位置: 首页 > 综合 > 正文

第十一天:javabean_el_listener_聊天室

2018年05月17日 ⁄ 综合 ⁄ 共 6089字 ⁄ 字号 评论关闭

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表达式获取数据语法:“${标识符}”

EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从pagerequestsessionapplication四个域中查找相应的对象,找到则返回相应对象,找不到则返回””(注意,不是null,而是空字符串)。

 

更加准备的说法是:先看看是不是那11个隐含对象,如果是,则按照隐含对象处理,如果不是则按照在四个作用域里面找。

 

EL表达式也可以很轻松获取JavaBean的属性,或获取数组、CollectionMap类型集合的数据,例如:

•   ${user.address.city}

•   ${user.list[0]}:访问有序集合某个位置的元素

•   ${map.key} 
获得map集合中指定key的值

结合JSTLforeach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,示例:

•   迭代数组

•   迭代collection类型集合

•   迭代map类型集合

 

 

执行运算:

 

获得web开发常用对象:

EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。

语法:${隐式对象名称
:获得对象的引用

隐含对象名称

      

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

表示一个保存了所有cookieMap对象

initParam

表示一个保存了所有web应用初始化参数的map对象

在这11个中,只有一个pageContext就够了,因为它能够获得其它8JSP中的内置对象,并且可以获得它相应的方法属性,十分好啊

 

如果是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服务器。

注意:有些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事件监听器:

 

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。

Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession
ServletRequest
这三个域对象,即监听器就只能监听这三个对象。

Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。

监听三个域对象创建和销毁的事件监听器

监听域对象中属性的增加和删除的事件监听器

监听绑定到 HttpSession
域中的某个对象的状态的事件监听器。(查看API文档)

 

 

和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。

和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。

一个 web.xml
文件中可以配置多个 Servlet
事件监听器,web 服务器按照它们在 web.xml
文件中的注册顺序来加载和注册这些 Serlvet
事件监听器。

 

感知 Session
绑定的事件监听器:

保存在 Session
域中的对象可以有多种状态:绑定到 
Session 中;从 Session
域中解除绑定;随 Session
对象持久化到一个存储设备中;随 Session
对象从一个存储设备中恢复

Servlet
规范中定义了两个特殊的监听器接口来帮助 JavaBean
对象了解自己在 Session
域中的这些状态HttpSessionBindingListener接口和HttpSessionActivationListener接口实现这两个接口的类不需要
web.xml
文件中进行注册

 

实现HttpSessionBindingListener接口的 JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件

当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的  voidvalueBound(HttpSessionBindingEvent event) 方法

当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法

 

 

实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件

当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEvent event) 方法

当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用该对象的 void sessionDidActive(HttpSessionBindingEvent event)方法

 

 

序列化:

ObjectOutputStream.把一个对象存到硬盘或者网络上,它会把一个对象转换成二进制字节,那么想要被这个类操作的类,必须实现seriable接口,这就是它的作用,把对象在内存中的状态存储到硬盘上,然后用的时间再取出来。

 

聊天室:

Redirect after post模式。

post提交后,再用redirect

 

我的一个疑惑:解决首页访问问题,

jsp页面写上:<jsp:forwardpage="/chat/RegisterUI"></jsp:forward>

交给serlvet后再转到相应的注册页面。这也解决了SSHjobsys的问题。

Request.setAttributegetAttribute常常与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(“”)方法先从pagerequest,sessionapplication依次从小到大找寻,找到则停止(易知:本例中是从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");

抱歉!评论已关闭.