JAVA Web学习笔记5

一、过滤器(Filter):
1、概念
(1)Servlet 过滤器本身并不生成请求和响应对象,它只提供过滤作用。
(2)Servlet 过滤器能够在 Servlet 被调用之前检查 Request 对象,修改Request Header 和 Request 内容;
(3)在Servlet被调用之后检查Response对象,修改Response Header和 Response内容。Servlet过滤器负责过滤的 Web组件可以是 Servlet、JSP 或 HTML 文件。

2、过滤过程
这里写图片描述

3、Filter接口
所有的 Servlet 过滤器类都必须实现javax.servlet.Filter接口。 这个接口含有3个过滤器类必须实现的方法:
• init(FilterConfig): 这是Servlet过滤器的初始化方法, Servlet容器创建Servlet过滤器实例后将调用这个方法。 在这个方法中可以读取web.xml 文件中Servlet过滤器的初始化参数。
• doFilter(ServletRequest, ServletResponse,FilterChain):这个方法完成实际的过滤操作。 当客户请求访问与过滤器关联的URL时, Servlet容器将先调用过滤器的doFilter方法。 FilterChain参数用于访问后续过滤器。
• destroy(): Servlet容器在销毁过滤器实例前调用该方法, 在这个方法中可以释放Servlet过滤器占用的资源。

4、过滤器例子
doFilter()方法中首先从request对象中读取客户姓名, 然后将客户姓名转换为中文字符编码。 如果客户姓名中包含黑名单里的字符串, 那么将直接向客户端返回一个拒绝网页。 由于在这种情况下没有调用chain.doFilter()方法, 因此客户请求不会到达所访问的Web组件。

    public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException{
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;

        String username = req.getParameter("username");
        String comment = req.getParameter("comment");

        username = username.replace("zhang", "li");
        comment = comment.replace("shengsiyuan", "****");

        req.setAttribute("username", username);
        req.setAttribute("comment", comment);

        chain.doFilter(request, response);
    }

配置web.xml文件(MyFilter1只对InfoServlet进行过滤):

   <filter>
        <filter-name>MyFilter1</filter-name>
        <filter-class>com.filter.MyFilter1</filter-class>
   </filter>
   <filter-mapping>
        <filter-name>MyFilter1</filter-name>
        <url-pattern>/InfoServlet</url-pattern>
   </filter-mapping>

• 如果客户名不在黑名单里, NoteFilter的doFilter方法就会调用chain.doFilter()方法, 这个方法用于调用过滤器链中后续过滤器的doFilter()方法。
• 假如没有后续过滤器, 那么就把客户请求传给相应的Web组件。
• 在本例中, 在调用chain.doFilter()方法前后记录了调用的时间, 从而计算出Web组件响应客户请求所花的时间。

5、练习题
(1)在Servlet过滤器中能否访问application范围内的共享数据?
可以的,先调用FilterConfig的getServletContext()方法获得ServletContext,再调用ServletContext的getAttribute()方法来获得application范围内的共享数据。
(2)“Servlet过滤器只能对Servlet进行过滤”, 这句话是否正确?
不正确。 Servlet过滤器可以对Servlet、 JSP和HTML文件过滤。

二、Listener
1、Listener
Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作, 比如监听在线的用户的数量。
• 当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1。

• 常用的监听接口有以下几个
– ServletContextAttributeListener监听对ServletContext属性的操作,比如增加、删除、修改属性
– ServletContextListener监听ServletContext。当创建ServletContext时,激发contextInitialized(ServletContextEventsce)方法;当销毁ServletContext时,激发contextDestroyed(ServletContextEventsce)方法。
• HttpSessionListener监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEventse)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEventse)方法。
• HttpSessionAttributeListener监听HttpSession中的属性的操作。当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEventse) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。

三、EL(Expression Language表达式语言)
1、EL默认对象
这里写图片描述

2、EL语法
EL 语法很简单,它最大的特点就是使用上很方便。

${sessionScope.user.sex}

所有EL都是以 ${ 为起始、以} 为结尾的。上述EL范例的意思是:从Session的范围中,取得用户的性别。假若依照之前JSP Scriptlet的写法如下:

User user = (User) session.getAttribute("user");
String sex = user.getSex( );

3、与[ ]运算符
EL 提供 . 和 [ ] 两种运算符来存取数据。
下列两者所代表的意思是一样的

${sessionScope.user.sex}
${sessionScope.user["sex"]}

. 和 [ ] 也可以同时混合使用,如下:

 ${sessionScope.shoppingCart[0].price}

回传结果为shoppingCart中第一项物品的价格。

两者差异:
(1) 当要存取的属性名称中包含一些特殊字符,如 . 或 – 等并非字母或数字的符号,就一定要使用 [ ],例如:

 ${user.My-Name }

• 上述是不正确的方式,应当改为:

 ${user["My-Name"] }

(2)我们来考虑下列情况:

${sessionScope.user[data]}

• 此时, data 是一个变量,假若data的值为”sex”时,那上述的例子等于${sessionScope.user.sex}
• 假若data 的值为”name”时,它就等于${sessionScope.user.name}。因此,如果要动态取值时,就可以用上述的方法来做,但 . 无法做到动态取值。

4、EL变量
EL 存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。因为我们并没有指定哪一个范围的username,所以它的默认值会先从Page 范围找,假如找不到,再依序到Request、 Session、Application范围。假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。

5、自动转变类型
• EL 除了提供方便存取变量的语法之外,它另外一个方便的功能就是: 自动转变类型
• ${param.count + 20}
• 会将传来的count自动转化为数值

6、EL隐含对象
与范围有关的EL 隐含对象包含以下四个: pageScope、requestScope、 sessionScope 和applicationScope,它们基本上就和JSP的pageContext、 request、session和application一样,不过必须注意的是,这四个隐含对象只能用来取得范围属性值,即JSP中的getAttribute(String name),却不能取得其他相关信息,例如: JSP中的request对象除可以存取属性之外,还可以取得用户的请求参数或表头信息等等。但是在EL中,它就只能单纯用来取得对应范围的属性值,例如:我们要在session 中储存一个属性,它的名称为username,在JSP 中使用session.getAttribute(“username”) 来取得username 的值, 但是在EL 中, 则是使用${sessionScope.username}来取得其值的。

四、客户化JSP标签
1、作用
• 客户化JSP标签技术是在JSP 1.1版本中才出现的,它支持用户在JSP文件中自定义标签,这样可以使JSP代码更加简洁。
• 这些可重用的标签能处理复杂的逻辑运算和事务,或者定义JSP网页的输出内容和格式。

2、创建步骤
( 1)创建标签的处理类
( 2)创建标签库描述文件
( 3) 在JSP文件中引入标签库,然后插入标签,例如:<mm:hello/>

3、JSP Tag API
Servlet容器编译JSP网页时, 如果遇到自定义标签, 就会调用这个标签的处理类。
• 标签处理类必须扩展以下两个类之一:
– javax.servlet.jsp. tagext .TagSupport
– javax.servlet.jsp. tagext .BodyTagSupport

4、TagSupport类的主要方法
• doStartTag
Servlet容器遇到自定义标签的起始标志时调用该方法
• doEndTag
Servlet容器遇到自定义标签的结束标志时调用该方法
• setValue(String k,Object o)
在标签处理类中设置key/value
• getValue(String k)
在标签处理类中根据参数key返回匹配的value
• removeValue(String k)
在标签处理类中删除key/value
• setPageContext(PageContext pc)
设置PageContext对象, 该方法由Servlet容器在调用doStartTag或doEndTag方法前调用
• setParent(Tag t)
设置嵌套了当前标签的上层标签的处理类, 该方法由Servlet容器在调用doStartTag或doEndTag方法前调用
• getParent()
返回嵌套了当前标签的上层标签的处理类
• parent
代表嵌套了当前标签的上层标签的处理类
• pageContext
代表 Web应用中的javax.servlet.jsp.PageContext对象

5、TagSupport类的两个重要属性
• JSP容器在调用doStartTag或doEndTag方法前 , 会先调用setPageContext 和setParent 方法 , 设置 pageContext 和parent。
• 在doStartTag或doEndTag方法中可以通过getParent方法获取上层标签的处理类;在TagSupport类中定义了protected类型的pageContext成员变量, 因此在标签处理类中可以直接访问pageContext变量。

6、PageContext类
• PageContext类提供了保存和访问Web应用的共享数据的方法:
– public void setAttribute(String name, Object value, int scope)
– public Object getAttribute(String name, int scope)
• 其中, scope参数用来指定属性存在的范围, 它的可选值包括:
– PageContext.PAGE_SCOPE
– PageContext.REQUEST_SCOPE
– PageContext.SESSION_SCOPE
– PageContext.APPLICATION_SCOPE
• 例如:

pageContext.setAttribute(“username”,”zhangsan”,
PageContext.SESSION_SCOPE);

7、doStartTag()方法
• 当Servlet容器遇到自定义标签的起始标志, 就会调用doStartTag()方法。
• doStartTag()方法返回一个整数值, 用来决定程序的后续流程。 它有两个可选值:
– Tag.SKIP_BODY
– Tag.EVAL_BODY_INCLUDE
• Tag.SKIP_BODY表示标签之间的内容被忽略。
• Tag.EVAL_BODY_INCLUDE表示标签之间的内容被正常执行。 例如
对于以下代码:

<prefix: Mytag>
Hello
……
……
</prefix:Mytag>

假若<Mytag>的doStartTag()方法返回Tag.SKIP_BODY, ” Hello”字符串不会显示在网页上;若返回Tag.EVAL_BODY_INCLUDE,“Hello” 字符串将显示在网页上。

8、doEndTag()方法
• 当Servlet容器遇到自定义标签的结束标志, 就会调用doEndTag()方法。
• doEndTag()方法也返回一个整数值, 用来决定程序后续流程。 它有两个可选值:
– Tag.SKIP_PAGE
– Tag.EVAL_PAGE
• Tag.SKIP_PAGE表示立刻停止执行JSP网页, 网页上未处理的静态内容和JSP程序均被忽略, 任何已有的输出内容立刻返回到客户的浏览器上。
• Tag.EVAL_PAGE表示按正常的流程继续执行JSP网页。
• 在标签中还能包含自定义的属性, 例如:

<prefix:mytag username=“zhangsan">
……
……
</prefix:mytag>

• 在标签处理类中应该将这个属性作为成员变量, 并且分别提供设置和读取属性的方法, 假定以上username为String类型,可以定义如下方法:

private String username;
public void setUsername(String value){
    this.username=value;
}
public String getUsername(){
    return username;
}

9、myTag.tld

<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.1</jsp-version>
    <short-name>myTag</short-name>
    <uri>/myTag</uri>

    <tag>
        <name>firstTag</name>
        <tag-class>com.shengsiyuan.tag.MyTag</tag-class>
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>message</name>
        <tag-class>com.shengsiyuan.tag.MyTag2</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>key</name>
            <required>true</required>
        </attribute>
    </tag>
</taglib>

10、练习题
(1)在标签处理类中, 如何访问session范围内的共享数据?
– (A) 在标签处理类TagSupport类中定义了pageContext成员变量, 先通过 它 的 getSession() 方 法 获 得 当 前 的 HttpSession 对 象 , 再 调 用HttpSession对象的getAttribute()方法。
– (B)pageContext.getAttribute(“attributename”,PageContext.SESSION_SCOPE)
(2)在 下 面 的 选 项 中 , 哪 些 是TagSupport类的doStartTag()方法的有
效返回值?
– (A) Tag.SKIP_BODY
– (B) Tag.EVAL_BODY_INCLUDE
备注:看到start ,联想到body;看到end,联想到page。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值