过滤器和监听器

过滤器和监听器
一、Servlet过滤器
1、什么是过滤器
Servlet过滤器和Servlet十分相似,但它具有拦截客户端请求的功能,Servlet过滤器可以改变请求中的内容,来满足实际开发中的需要。对于开发人员而言,过滤器实际上就是在Web应用服务器上的Web组件,用于拦截客户端(浏览器)与目标资源的请求,并对这些请求进行一定过滤处理再发送给目标资源。
如果一个Web应用中使用一个过滤器不能解决实际中的业务需要,那么可以部署多个过滤器,对业务请求进行多次处理,这样就组成了过滤链。
2、过滤器核心对象
过滤对象是放置在javax.servlet包中,其名称为Filter,它是一个接口。除了这个接口后,与过滤器相关的对象还有FilterConfig对象与FilterChain对象,这两个对象也是接口对象,位于javax.servlet包中,分别为过滤器的配置对象与过滤器的传递工具。在实际的开发中,定义过滤器对象只需要直接或间接的实现Filter接口即可。
Filter接口:
每个过滤器对象只需要直接或间接的实现Filter接口,在Filter接口中定义了3个方法,分别为init()方法、doFilter()方法和destroy()方法,其方法声明及说明如下:
public void init(FilterConfig config)throws ServletException:过滤器初始化方法,该方法在过滤器初始化时调用。
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException:对请求进行过滤处理
public void destroy():销毁方法,以便释放资源。
FilterConfig接口
FilterConfig接口由Servlet容器进行实现,主要用于获取过滤器的配置信息,其方法声明及说明如表:
public String getFilterName():获取过滤起的名字。
public ServletContext getServletContext():获取Servlet上下文。
public String getInitParameter(String name):获取过滤器的初始化参数值。
public Enumeration getInitParameterNames():获取过滤器的所有初始化参数值。
FilterChain接口
FilterChain仍然由Servlet容器进行实现,在这个接口中有只有一个方法,其方法声明如下:
public void doFilter(ServletRequest request,ServletResponse response):该方法用于将过滤后的请求传递给下个过滤器,如果此过滤器已经是个过滤器链中的最后一个过滤器,那么,请求将传送给目标资源。
3、过滤器的的创建于配置
创建一个过滤器对象需要实现javax.servlet.Filter接口,同时实现接口的三个方法。
使用过滤器并不一定将请求传递给下个过滤器或目标资源,如果业务需要,也可以在过滤处理后,直接回应客户端。
过滤器与Servlet十分相似,在创建之后同样需要对其进行配置,过滤器的配置主要分为两步骤,分别为声明过滤器和创建过滤器映射。
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>con.lyt.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>标签用于声明过滤器对象,在这个标签中必须配置两个字元素,分别为过滤器的名称和过滤器完整类名。<filter-mapping>标签用于创建过滤器的映射,它的主要作用就是指定Web应用中,哪些URL应用哪一个过滤器去处理。
4、字符编码过滤器
在Java Web开发中,由于Web容器内部使用的编码格式并不支持中文字符集,所以,处理浏览器请求中的中文数据会出现乱码现象,Web容器使用了ISO-8859-1的编码格式,所以Web应用的业务处理中也会使用ISO-8859-1的编码格式,虽然浏览器提交的请求使用的是中文编码UTF-8,但经过业务处理中的ISO-8859-1编码,仍然会出现中文乱码现象。解决此问题很简单,在业务处理中重新指定中文字符集进行编码即可解决。
例子:
@WebFilter(filterName = "CharactorFilter",urlPatterns ="/*",initParams = {@WebInitParam(name="encoding",value="UTF-8")})
public class CharactorFilter implements Filter {
    String encoding=null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        encoding=filterConfig.getInitParameter("encoding");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        if(encoding!=null){
            request.setCharacterEncoding(encoding);
            response.setContentType("text/html;charset="+encoding);
        }
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {
        encoding=null;
    }
}
@WebServlet(name = "AddServlet",urlPatterns="/AddServlet")
public class AddServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//处理POST请求
        PrintWriter out = response.getWriter();
        String id=request.getParameter("id");
        String name=request.getParameter("name");
        String author=request.getParameter("author");
        String price=request.getParameter("price");
        out.println("<h2>图书信息添加成功<h2><hr>");
        out.println("图书编号:"+id);
        out.println("图书名称:"+name);
        out.println("作  者:"+author);
        out.println("价  格:"+price);
        out.flush();//刷新流
        out.close();//关闭流
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>添加图书信息</title>
</head>
<body>
     <form action="../AddServlet" name="form1" method="post"><!--action路径要加“/工程名称"+Servlet的url-->
         <table align="center" border="1" width="350">
             <tr>
                 <td class="2" colspan="2" align="center">
                    <h2> 添加图书信息</h2>
                 </td>
             </tr>
             <tr>
                 <td align="right">图书编号:</td>
                 <td>
                     <input type="text" name="id">
                 </td>
             </tr>
             <tr>
                 <td align="center">图书名称:</td>
                 <td>
                     <input type="text" name="name">
                 </td>
             </tr>
             <tr>
                 <td align="right">作  者:</td>
                 <td>
                     <input type="type" name="author">
                 </td>
             </tr>
             <tr>
                 <td align="right">价  格:</td>
                 <td>
                     <input type="text" name="price">
                 </td>
             </tr>
             <tr>
                 <td align="center" colspan="2" class="2">
                     <input type="submit" value="添加">
                 </td>
             </tr>
         </table>
     </form>
</body>
</html>
在此程序中,不需要再在web.xml文件中对Servlet或过滤器配置了,用上面的@WebServlet注解和@WebFilter注解即可完成它们的配置。

二、Servlet监听器
在Servlet技术中已经定义了一些事件,并且可以针对这些事件编写相关的事件监听器,从而对事件作出相应的处理。例如,想要在Web应用程序启动或关闭时来执行一些任务(如数据库连接的建立和释放),或者想要监控session的创建和销毁,那么就可以通过监听器来实现。
1、Servlet监听器
监听器的作用是监听Web容器的有效事件,因此它是由容器管理的。利用Listener接口监听在容器中的某个执行程序,并且根据其应用程序的需求做出适当的响应。以下是Servlet和JS中的8个Listener和6个Event类。
    Listener接口:                         Event类:
ServletContextListener                  ServletContextEvent
ServletContextAttributeListener         ServletContextAttributeEvent
HttpSessionListener                     HttpSessionEvent
HttpSessionActivationListener           HttpSessionEvent
HttpSessionAttributeListener            HttpSessionBindingEvent
HttpSessionBindingListener              HttpSessionBindingEvent
ServletRequestListener                  ServletRequestEvent
ServletRequestAttributeListener         SWervletRequestAttributeEvent
2、Servlet监听器的原理
Servlet监听器是当今Web应用开发的一个重要组成部分。它在Servlet2.3规范和Servlet过滤器一起引入的,并且在Servlet2.4规范中对其进行了较大的改进,主要就是用来Web应用进行监听和控制的。
3、Servlet上下文监听
Servlet上下文监听可以监听ServletContext对象的创建、删除以及属性添加、删除和修改操作,该监听器需要用到两个接口。
(1)ServletContextListener接口:该接口存放在javax,servlet包内,它主要监听ServletContext的创建和删除,提供了2个方contextInitalized(ServletContextEvent event)方法和contextDestroy(ServletContextEvent event)方法。
(2)ServletContextAttributeListener接口:该接口存放在javax.servlet包内,主要实现监听ServletContext属性的增加、删除和修改,提供了3个方法,分别为:attributeAdded(ServletContextAttributeEvent event)方法、attributeReplaced(ServletContextAttributeEvent event)方法和attributeRemoved(ServletContextAttributeEvent event)方法。
启动监听器需要在web.xml中使用<listener>元素来配置监听器类。
4、HTTP会话监听
HTTP会话监听信息,有四个接口可以监听。
(1)HttpSessionListener接口:HttpSessionListener接口实现监听会话的创建、销毁。提供了2个方法,分别为:sessionCreated(HttpSessionEvent event)方法和sessionDestroy(HttpSessionEvent event)方法。
(2)HttpSessionAttributeListener接口:该接口实现监听HTTP会话中属性的设置要求,提供了3个方法,分别为:attributeAdded(HttpSessionBindingEvent event)方法、attributeReplaced(HttpSessionBindingEvent event)方法。
(3)HttpBindingListener接口:实现了监听HTTP会话中对象的绑定信息。它是个唯一不需要在web.xml中设定Listener的,提供了2个方法,分别为:valueBound(HttpSessionBindingEvent event)方法和valueUnBound(HttpSessionBindingEvent event)方法。
(4)HttpSessionActivationListener接口:该接口实现坚挺了HTTP会话active和passivate,提供了2个方法,分别为:sessionDidActivate(HttpSessionEvent event)方法和sessionWillPassivate(HttpSWessionEvent event)方法。
5、Servlet请求监听
在Servlet2.4规范中新增加了一个技术,就是可以监听客户端的请求。一旦能够在监听程序中获取客户端的请求,就可以就请求进行统一处理。
(1)ServletRequestListener接口:该接口提供了2个方法,分别为:requestInitalized(ServletRequestEvent event)方法和requestDestroy(ServletRequestEvent event)方法。
(2)ServletRequestAttributeListener接口:该接口提供了3个方法,分别为:attributeAdded(ServletRequestAttributeEvent event)方法、attributeReplaced(ServletRequestAtrributeEvent event)方法和attributeRemoved(ServletRequestAttributeEvent event)方法。

三、Servlet3.0新特性
1、新增注释
新增注释是Servlet3.0中的重大改革之一,通过使用注解就无需在web.xml文件中对Servlet或者过滤器进行配置。Servlet3.0新增的注释有@WebServlet、@WebFilter、@WebListener和@WebInitParam等。
(1)@WebServlet:定义在Servlet类声明之前,用于定义Servlet组件。使用该注释,就无需在web.xml文件中对Servlet进行配置。主要属性如下:
name:Servlet的name属性,等价于<servlet-name>
urlPatterns:指定一组Servlet的URL匹配模式,等价于<url-pattern>标签
initParams:指定一组Servlet初始化参数,等价于<init-param>标签
asyncSupported:声明Servlet是否支持异步操作模式,等价于<async-support>标签
例子:
@WebServlet(name = "RegisterServlet",urlPatterns = "/RegisterServlet")
public class RegisterServlet extends HttpServlet {
    Connection conn=null;
    PreparedStatement ps=null;
    ResultSet rs=null;

    public void init(ServletConfig config)throws ServletException{
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/itcast","root","123");
            if(conn!=null){
                System.out.println("数据库连接成功!");
            }
        }  catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String name=request.getParameter("name");
        String password=request.getParameter("password");
        String sex=request.getParameter("sex");
        String question=request.getParameter("question");
        String answer=request.getParameter("answer");
        String email=request.getParameter("email");
        if(conn!=null){
            String sql="insert into info (name,password,sex,question,answer,email) values(?,?,?,?,?,?)";
            try {
                ps=conn.prepareStatement(sql);
                ps.setString(1,name);
                ps.setString(2,password);
                ps.setString(3,sex);
                ps.setString(4,question);
                ps.setString(5,answer);
                ps.setString(6,email);
                ps.execute();
                PrintWriter out = response.getWriter();//获取PrintWriter对象
                out.print("<h1 aligh='center'>");
                out.print("注册成功!!");
                out.print("</h1>");
                out.flush();//刷新流
                out.close();//关闭流
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                if (rs!=null){
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (ps!=null){
                    try {
                        ps.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn!=null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }else{
            System.out.println("连接失败!!");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse    response) throws ServletException, IOException {
        doPost(request,response);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册用户信息</title>
</head>
<body>
   <form action="../RegisterServlet" method="post" οnsubmit="return reg(this)">
       <table align="center" border="1" width="500">
           <tr>
               <td colspan="2" align="center"><b>用户注册</b></td>
           </tr>
           <tr>
               <td align="right" width="30%">用户名:</td>
               <td>
                   <input type="text" name="name">
               </td>
           </tr>
           <tr>
               <td align="right">密  码:</td>
               <td>
                   <input type="password" name="password">
               </td>
           </tr>
           <tr>
               <td align="right">确认密码:</td>
               <td>
                   <input type="password" name="repassword">
               </td>
           </tr>
           <tr>
               <td align="right">性  别:</td>
               <td>
                   <input type="radio" name="sex" value="女" checked="女"><input type="radio" name="sex" value="男"></td>
           </tr>
           <tr>
               <td align="right">密码找回问题:</td>
               <td>
                   <input type="text" name="question" class="box">
               </td>
           </tr>
           <tr>
               <td align="right">密码找回答案:</td>
               <td>
                   <input type="text" name="answer">
               </td>
           </tr>
           <tr>
               <td align="right">邮  箱:</td>
               <td>
                   <input type="text" name="email" class="box">
               </td>
           </tr>
           <tr>
               <td colspan="2" align="center" height="40">
                   <input type="submit" value="注册">
                   <input type="reset" value="重置">
               </td>
           </tr>
       </table>
   </form>
</body>
</html>
(2)@WebFilter:用于声明过滤器,该注解会在部署是被容器处理,容器根据具体的属性配置将相应的类部署为过滤器。其属性也包含很多属性如下:
filterName:指定过滤器的name的属性,等价于<filter-name>标签
urlPatterns:指定一组Servlet的URL匹配模式,等价于<url-pattern>标签
initParams:指定一组Servlet初始化参数,等价于<init-param>标签
asyncSupported:声明Servlet是否支持异步操作模式,等价于<async-support>标签
ServletNames:指定过滤器将应用于哪些Servlet。等价于<servlet-name>标签
(3)@WebListener该注释用于声明监听器,还可以用于充当给定Web应用上下文中各种Web应用事件的监听器的类,可以使用@WebListener来标注一个实现的ServletContextListener、ServletContextAttributeListener、ServletRequestListener、ServletRequestAttributeListener、HttpSessionListener和HttpSessionAttributeListener的类。@WebListener注释有一个value属性,该属性为可选属性,用于描述监听信息。使用该注释就不需要在web.xml文件里配置<Listener>标签了。
(4)@WebInitParam:该注释等价于web.xml文件中的<servlet>和<filter>的<init-param>子标签,该注释通常不单独使用,而是配合@WebServlet或者@WebFilter使用,,常用属性如下:
name:指定参数的名字,等价于<param-name>
value:指定参数的值,等价于<param-value>
description:关于参数的描述,等价于<description>
@WebFilter(filterName = "CharactorFilter",urlPatterns ="/*",initParams = {@WebInitParam(name="encoding",value="UTF-8")})
2、对文件上传的支持
在Servlet3.0出现之前,处理文件上传是一件非常麻烦的事,因为需要借助第三方组件,例如:commons.fileupload等。实现文件上传需要以下两项内容:
(1)需要添加@MultipartConfig注释
(2)从request对象中获取Part文件对象。
@MultipartConfig注释需要标注在@WebServlet之上,其具有属性如下:
fileSizeThreshold:当数据量大于该值时,内容将写入文件。
location:存放生成文件的地址。
maxFileSize:允许上传的文件最大值。默认值为-1,表示没有限制。
maxRequestSize:针对该multipart/form-data请求的最大数量,默认值为-1,表示没有限制。
例子:
@MultipartConfig(location = "d:/myfile1.txt")
@WebServlet(name = "UploadServlet",urlPatterns = "/UploadServlet")
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out=response.getWriter();
        String path = this.getServletContext().getRealPath("/");//获取服务器的地址
        Part p = request.getPart("file1");//获取用户选择上传的文件
        if(p.getContentType().contains("image")){//仅处理上传的图片文件
            ApplicationPart ap = (ApplicationPart) p;
            String fname1=ap.getFileName();
            int path_idx=fname1.lastIndexOf("\\")+1;
            String fname2=fname1.substring(path_idx,fname1.length());
            p.write(path+"/upload"+fname2);
            out.write("文件上传成功");
        }else{
            out.write("请选择文件!!!");
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
    }
}
<body>
    <form action="../UploadServlet" method="post" name="form1" enctype="multipart/form-data">
        选择文件<input type="file" name="file1" id="file1">
        <input type="submit" name="upload" value="上传">
    </form>
</body>
</html>


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值