ServletJSP:下

来源:互联网 发布:sql语句查询多张表 编辑:程序博客网 时间:2024/05/15 11:08

过滤器

  • 过滤器是Servlet2.3规范中定义的一种小型的,可插入的web组件,用来拦截Servlet容器的请求和响应过程,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据
  • 过滤器通常是封装了一些功能的web组件,这些功能很重要,但对于处理客户端请求或发送响应来说不是决定性的

这里写图片描述

使用过滤器

  • step1. 写一个java类,实现Filter接口。
  • step2. 在接口方法当中,实现拦截处理逻辑。
public class CommentFilter implements Filter{    private FilterConfig config;    /**     * 容器在销毁过滤器实例之前,会调用此方法。     */    public void destroy() {        System.out.println("destroy()");    }    /**     * 容器会调用doFilter方法来处理请求     * FilterChain(过滤器链):如果调用了该对象的     * doFilter方法,则继续向后执行,否则中断请求。     */    public void doFilter(ServletRequest request, ServletResponse response,FilterChain arg2)throws IOException, ServletException {        System.out.println("doFilter begin...");        request.setCharacterEncoding("utf-8");        response.setContentType("text/html;charset=utf-8");        PrintWriter out = response.getWriter();        String content = request.getParameter("content");        //读取初始化参数        String illegal = config.getInitParameter("illegal");        if(content.indexOf(illegal) != -1){            out.println("<h1>评论内容非法</h1>");        }else{            //继续向后执行            arg2.doFilter(request, response);        }        System.out.println("doFilter end.");    }    /**     * 容器启动之后,会立即创建过滤器实例(只会创建一个)     * 接下来,会调用该实例的init方法(只会执行一次)     * FilterConfig:用来读取初始化参数。     */    public void init(FilterConfig arg0) throws ServletException {        System.out.println("init()");        //将容器传递过来的FilterConfig对象保存下来        config = arg0;    }
  • step3. 配置过滤器。
    配置文件必须写对,不然问题很多,比如404或者无法启动服务器。
<filter>    <filter-name>commentFilter</filter-name>    <filter-class>web.CommentFilter</filter-class>    <!-- 配置初始化参数 -->    <init-param>        <param-name>illegal</param-name>        <param-value></param-value>    </init-param>  </filter>  <filter-mapping>    <filter-name>commentFilter</filter-name>    <url-pattern>/comment</url-pattern><!-- 这个位置要和需要滤的servlet相同 -->  </filter-mapping>

过滤器的优先级

当有多个过滤器都满足过滤的条件
则容器依据<filter-mapping> 配置的先后顺序来执行。

优点

  • 在不修改原有代码的基础上,为程序添加新的功能。
  • 将多个模块相同的代码集中写在一个类里面,方便代码的维护。

监听器

servlet规范当中定义的一种特殊的组件,
用来监听容器产生的事件并进行相应的处理。

容器会产生两大类事件

  • 生命周期相关的事件
    容器创建或者销毁request,session,servlet上下文产生的事件。
    ServletRequestListener
    HttpSessionListener
    ServletContextListener
  • 绑订数据相关的事件
    调用了request,session,servlet上下文的setAttribute,removeAttribute产生的事件。
    ServletRequestAttributeListener
    HttpSessionAttributeListener
    ServletContextAttributeListener

编写监听器步骤

  • step1. 写一个java类,依据监听的事件类型来实现相应的接口。
    比如,要监听session对象的创建和销毁,可以实现
    HttpSessionListener接口。
  • step2. 在监听器接口方法当中,实现监听处理逻辑。
public class CountListener implements HttpSessionListener{/**     * session对象创建之后,会执行此方法     *  arg0:事件对象     */    public void sessionCreated(HttpSessionEvent arg0) {        System.out.println("sessionCreated()");        //获得Servlet上下文        HttpSession session = arg0.getSession();        ServletContext sc = session.getServletContext();        //获取Servlet上下文上绑订的人数        Integer count = (Integer)sc.getAttribute("count");        if(count == null){            //第一个用户            count = 1;        }else{            //非第一个用户,累加            count ++;        }        sc.setAttribute("count", count);        }    /**     * session对象销毁之后,会执行此方法。     */    public void sessionDestroyed(HttpSessionEvent arg0) {        System.out.println("sessionDestroyed()");        ServletContext sc = arg0.getSession().getServletContext();        Integer count = (Integer) sc.getAttribute("count");        count --;        sc.setAttribute("count", count);    }}
  • step3. 配置监听器
    web.xml中
<!-- 配置监听器 -->  <listener>    <listener-class>web.CountListener</listener-class>  </listener>

应用场景

  • 在contextDestroyed方法中对应用级别的资源进行释放
  • 统计在线人数可以通过HttpSessionListener监听器的sessionCreated方法监听session的创建动作

容器处理异常

这里写图片描述

这里写图片描述

jsp标签和el表达式

jsp标签

jsp标签类似于html标签,用来替换jsp中的java代码。
因为直接在jsp文件中写java代码,不利于jsp文件的维护(比如,将包含有大量java代码的jsp交给美工去修改就很不方便),所以,sun公司制订了jsp标签技术规范。使用jsp标签代替java代码之后,jsp文件变得简洁,便于维护。而且便于代码的复用。

el表达式

是一套运算规则,用于给jsp标签的属性赋值,也可以直接输出。

使用

  • 访问bean的属性 (e1.jsp)
    • 方式一
    • ${user.name} : 容器依次pageContext,request,session,application中查找绑订名为”user”的对象(getAttribute),找到之后,会调用该对象的”getName”方法,然后输出;如果找不到,会输出”“。
      • 依次,指的是先从pageContext上去查找,如果没有,再查找request,如果找到,则不再向下查找了。
      • 如果值为null,会转换成”“输出。如果要指定查找范围,可以使用pageScope,requestScope,sessionScope,applicationScope。
        比如:${requestScope.user.name}。
    • 方式二 ${user['name']} 等价于${user.name}
      • []可以使用绑订名。
      • []可以使用从0开始的下标,用来读取数组中的某个元素。
<body style="font-size:30px;">        <%            User user = new User();            user.setName("Sally");            user.setAge(22);            user.setInterest(new String[]{"cooking","snooker"});            request.setAttribute("user", user);            User user2 = new User();            user2.setName("Tom");            user2.setAge(33);            session.setAttribute("user", user2);        %>        name:<%            //User user1 = (User)request.getAttribute(            //      "user");            //out.println(user1.getName());        %>        <br/>        name:${user.name}<br/>        name:${sessionScope.user.name} <br/>        name:${user['name']}<br/>        <%            request.setAttribute("prop", "age");        %>        ${user[prop]}<br/>         ${user.interest[0]}            </body>
  • 做一些简单的运算
    • 算术运算 +,-,*,/,% : + 只能求和。
    • 关系运算 >,>=,<,<=,==,!=
    • 逻辑运算 && || !
    • empty运算 empty
<body style="font-size:30px;">        1 + 1 = ${1 + 1} <br/>        "a"  + "b" = ${"1" + "1" } <br/>        1 < 2吗? ${1 < 2} <br/>        <%            request.setAttribute("s1", "abc");        %>        ${sesionScope.s1 == 'abc'}        ${1 < 2 && 2 > 3}        empty运算: <br/>        <%            request.setAttribute("s2", "");            List list1 = new ArrayList();            request.setAttribute("list1", list1);        %>        空字符串:${empty s2}<br/>        空的集合:${empty list1} <br/>        null值: ${empty null}        找不到任何数据:${empty a}         </body>
            用来判断集合是否为空,或者是否为一个空字符串。 

- 读取请求参数值

    ${param.username}等价于request.getParameter("username");    ${paramValues.city}等价于request.getParameterValues("city");    <body style="font-size:30px;">            username:${param.username}<br/>            city:${paramValues.city[0]}    </body>

jstl(java standard taglib)标签

apache开发的一套标签,后来捐献给了sun。
1)如何使用jstl标签。
step1.导包。(jstl.jar)
step2.使用taglib指令,导入要使用的标签。

核心标签

  • if标签
        <c:if test="" var="" scope="">            标签体        </c:if>

a1. c是命名空间的前缀(别名)。
命名空间(namespace): 为了区分同名的元素而添加的一个 限定。
a2. 如果test属性值为true,则执行标签体的内容。
test属性可以使用el表达式来计算。
a3. var属性指定一个绑订名,scope属性指定绑订的
范围(“page”,”request”,”session”,”application”)

<body style="font-size:30px;">        <%            User user = new User();            user.setName("花千骨");            user.setGender("f");            request.setAttribute("user", user);        %>        姓名:${user.name}        性别:        <c:if test="${user.gender == 'm'}">男</c:if>        <c:if test="${user.gender == 'f'}">女</c:if>        <br/>        性别:        <c:if test="${user.gender == 'm'}">男</c:if>            <c:if test="${user.gender != 'm'}">女</c:if>        性别:        <c:if test="${user.gender == 'm'}"         var="rs" scope="page">男</c:if>        <c:if test="${!rs}">女</c:if>    </body>
  • choose标签
        <c:choose>            <c:when test="">            </c:when>            <c:otherwise>            </c:otherwise>        </c:choose>

b1.when表示一个分支,如果test属性值为true,
则执行该分支。(可以出现1次或者多次)
b2.otherwise表示例外,可以出现0次或者1次。

<body style="font-size:30px;">        <%            User user = new User();            user.setGender("x");            request.setAttribute("user", user);        %>        性别:        <c:choose>            <c:when test="${user.gender == 'm'}"></c:when>            <c:when test="${user.gender == 'f'}"></c:when>            <c:otherwise>保密</c:otherwise>        </c:choose>
  • forEach标签
        <c:forEach items="" var="" varStatus="">        </c:forEach>

c1.用来遍历集合或者数组。
c2.items属性用来指定要遍历的集合或者数组,
可以使用el表达式。
c3.var属性用来指定绑订名(绑订范围是pageContext)。
c4.varStatus属性用来指定绑订名(绑订范围是pageContext),绑订值是一个特殊的对象(由该标签
创建,作用是用来获得当前遍历的状态,比如getIndex
方法:获得当前被遍历的元素的下标。getCount方法用
来获得当前是第几次遍历) 。

<c:forEach items="${users}" var="u"             varStatus="s">                <tr class="row${s.index % 2 + 1}">                    <td>${u.name}</td>                    <td>${u.gender}</td>                    <td>${s.index}</td>                    <td>${s.count}</td>                </tr>            </c:forEach>

自定义jsp标签

(1)编程步骤

  • step1. 写一个java类,继承SimpleTagSupport类。

step2. override doTag方法,在该方法里面,写处理逻辑。

package tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.SimpleTagSupport;public class HelloTag extends SimpleTagSupport{    private String msg;    private int qty;    public HelloTag() {        System.out.println("HelloTag()");    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        System.out.println("setMsg() " + msg);        this.msg = msg;    }    public int getQty() {        return qty;    }    public void setQty(int qty) {        System.out.println("setQty() " + qty);        this.qty = qty;    }    @Override    public void doTag() throws JspException, IOException {        System.out.println("doTag()");        /* 可以通过继承自SimpleTagSupport类提供的方法         * 来获得pageContext。         * pageContext提供了获得其它所有隐含对象的         * 方法。         */        PageContext pc =                 (PageContext)getJspContext();        JspWriter out = pc.getOut();        for(int i = 0; i < qty; i ++){            out.println(msg + "<br/>");        }    }}

step3. 在.tld文件当中描述标签。
<body-content>的值可以是emtpy,scriptless,JSP
empty:标签没有标签体。
scriptless:标签可以有标签体,但是标签体的内容不能够
出现java代码(<% %>,<%= %>,<%! %>)。
JSP:标签可以有标签体,标签体的内容可以出现java代码。但是,只有复杂标签技术才支持。

<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"    version="2.1">    <tlib-version>1.1</tlib-version>    <short-name>t1</short-name>    <uri>test</uri>    <tag>    <name>hello</name>    <tag-class>tag.HelloTag</tag-class>    <body-content>empty</body-content>    <attribute>        <name>msg</name>        <!-- true表示该属性必选 -->        <required>true</required>        <!-- true表示该属性可以动态赋值 -->        <rtexprvalue>false</rtexprvalue>    </attribute>    <attribute>            <name>qty</name>            <required>true</required>            <rtexprvalue>true</rtexprvalue>    </attribute>  </tag></taglib>
  • 使用
<%@page pageEncoding="utf-8" contentType="text/html; charset=utf-8" %><%@ taglib uri="test" prefix="t1" %><html>    <head></head>    <body style="font-size:30px;">        <t1:hello msg="Hello World" qty="${1 + 3}"/>    </body></html>
原创粉丝点击