Servlet、Filter、Listener

Servlet:

Servlet就是运行在服务器端的程序,用来处理客户端的请求并且响应数据给回浏览器的动态web资源技术

Servlet相对于普通Java类程序:

普通Java类需要main方法才能调用运行,而Servlet是由Tomcat服务器调用,不需要main方法

Servlet可以接受用户的请求数据和响应数据给浏览器传输数据

 

Servlet3.0相较于Servlet2.5优化了在web.xml文件作配置的繁琐步骤,只需在Servlet实现类上加上注解@WebServlet即可配置

@WebServlet 的两个参数:

name:别名,可以省略

url-pattern:servlet的访问路径

@WebServlet(name = "TestServlet", urlPatterns = "/test")
public class testServlet implements Servlet {

    public void init(ServletConfig servletConfig) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

 

Servlet的生命周期:

init():初始化方法

service():处理请求和响应数据的主方法

destory():销毁当前Servlet方法

 

Servlet的设计采用的是单例设计模式,servlet对象在内存中只有一个对象

浏览器第一次向此路径的Servlet发送请求时,服务器会调用1次构造方法

然后执行1次init()初始化Servlet的方法

再执行一次service()方法,传入request,response对象,执行完将response对象返回给浏览器

下次再次访问此Servlet路径时,只会调用n次service()方法,无需再初始化

最后关闭服务器时,会调用1次destory()销毁创建的Servlet对象

Servlet、Filter、Listener_第1张图片

Servlet接口有一个子类GenericServlet类

该类简化了Servlet的初始化与销毁等方法,所以继承此类的Servlet仅需重写service()方法即可

弊处:此方法和Servlet接口一样,都会将get方法和post方法统一使用service来处理

 

所以有了GenericServlet的子类HttpServlet类

该类相较于父类的优点,再次优化了service()方法,分为doGet()和doPost()方法

让浏览器中使用不同的提交方式,也能有不同的处理方式

@WebServlet(name = "UserServlet", urlPatterns = "/user")
public class UserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

 

 

Fileter拦截器:

一个类实现了Filter并重写init()、doFilter()、destory()方法,且在类上使用@WebFilter注解修饰

@WebFilter(filterName = "Test2Filter")
public class Test2Filter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }
}

 

拦截器的处理流程:

Servlet、Filter、Listener_第2张图片

拦截器的生命周期:

过滤器部署到服务器后,只要服务器一开启就会执行1次init()初始化方法

浏览器发送n次请求,只要拦截器路径相同,则会调用n次doFilter()拦截方法

当服务器关闭时,就会调用1次destory()销毁拦截器方法

 

@WebFilter注解其中有2个较重要的属性

urlPatterns:表示需要过滤的路径地址,可以写精确的路径,也可以写/*表示拦截所有资源

dispatcherTypes:表示拦截的方式,可以指定多个值用数组的形式表示

                DispatcherType.FORWARD:过滤转发跳转访问的方式

                 DispatcherType.REQUEST:过滤直接在url地址上访问资源的方式

 

譬如使用post提交请求中文数据时,会出现乱码,和响应中文数据到浏览器时也会出现乱码

就可以使用拦截器Filter统一设置解码类型解决乱码问题

@WebFilter(filterName = "TestFilter", urlPatterns = "/*", dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.REQUEST})
public class TestFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //将ServletRequest和ServletResponse对象强转为
        // HttpServletRequest和HttpServletResponse 以获得可调用的方法
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        //解决post方式请求的数据出现中文乱码
        if ("post".equalsIgnoreCase(request.getMethod().trim())) {
            request.setCharacterEncoding("utf-8");
        }
        //解决response中文数据出现乱码
        response.setContentType("text/html;charset=utf-8");
        chain.doFilter(request, response);
    }

    public void init(FilterConfig config) throws ServletException {

    }
}

 

Listener监听器:

实现ServletContextListener,HttpSessionListener,HttpSessionAttributeListener接口的类,通常称为监听器

顾名思义,监听器是用来监听ServletContext全局共享域对象和Session会话域对象的变化的

 

接口中就有其中两个方法,用于监听全局共享域的创建与销毁状态

void contextDestroyed(ServletContextEvent  sce)                     监听servletcontext销毁

void contextInitialized(ServletContextEvent  sce)                       监听servletcontext创建

 

由于服务器一启动就会自动创建ServletContext对象,所以有了监听器

可以让服务器启动时调用contextInitialized方法,在关闭服务器时调用contextDestroyed方法

 

void attributeAdded(ServletContextAttributeEvent scab)                 监听属性添加到servletcontext中

void attributeRemoved(ServletContextAttributeEvent scab)           监听属性从servletcontext中移除

void attributeReplaced(ServletContextAttributeEvent scab)           监听属性从servletcontext中被替换

Added方法中使用参数调用getName()和getValue()方法就能获取存数据进全局域时候的数据

Removed则为删除数据时,Replaced则为替换数据时

 

void sessionCreated(HttpSessionEvent  se )

void sessionDestroyed(HttpSessionEvent se)

则为监听Session对象的创建和删除的方法

实际开发中,常用作监听统计当前在线人数的总数:

当前session会话被创建,当前在线用户+1

每当session会话被销毁,当前在线用户-1。

 

你可能感兴趣的:(Servlet,Filter)