Servlet从零开始的生活:三大域对象、过滤器、监听器

servlet生命周期

初识interface Servlet接口
public interface Servlet {
    //初始化调用(只会调用一次)
    void init(ServletConfig var1) throws ServletException;
	//获取ServletConfig域
    ServletConfig getServletConfig();
	//每次请求会调用service方法
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    //销毁时调用(只会调用一次)
    void destroy();
}

在这里插入图片描述

HttpServlet抽象方法(GenericServlet imp Servlet)
//5 注意 你的sevlet尽量只对do*方法进行重写,例如doGet、doPost方法, 不去重写service方法,HttpServlet中的service方法对Get资源请求做了时间的限定,让客户端不用每次Get请求都进行资源的加载,对于大量静态资源的情况节省了客户端相应时间,也对服务器资源消耗做到一定上减少
public abstract class HttpServlet extends GenericServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    }
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            //1.获得Last-Modified上次修改时间
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                //2.If-Modified-Since 最后可能修改资源的时间
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    //3.请求的资源在If-Modified-Since时间之后情况下才会将资源返回
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    //4.如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的  304  响应
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        }
    }
}

一个Servlet

继承HttpServlet

public class servlet_dome extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }

访问方式

XML方式
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
   <!-- servlet:
		servlet—name=servlet的名称
		servlet-class=servlet类路径
		servlet-mapping:servlet映射路径
		servlet—name=servlet的servlet-nmae
		url-pattern= the URL patterns of the servlet
	-->
    <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>com.test.servletdome.servlet_dome</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <url-pattern>/servlet_01.do</url-pattern>
    </servlet-mapping>
</web-app>
注解方式
import javax.servlet.annotation.WebServlet;
@WebServlet(name = "servlet_dome02",urlPatterns = "/servlet_02.do")
//name=servlet-name,urlPatterns=vlue=url-pattern
public class servlet_dome02 extends HttpServlet {

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().print("Hi! this is servlet_dome02");
        }
}

三大域对象

请求对象域

请求对象方法
以下对域对象操作方法
方法名作用传入参数返回参数实现类
getParameter获取前端请求的参数。(Get时获取url上?后的键值对,Post时获取请求体中的键值对)String keyString valueServletRequestWrapper
parameterNames获取前端所有请求参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数)EnumerationServletRequestWrapper
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("name","小明");
        System.out.println("获取req域中属性值:name:"+req.getAttribute("name"));
    }
以下对请求参数获取
方法名作用传入参数返回参数实现类
setAttribute向req域中添加属性String var1, Object var2ServletRequestWrapper
getAttribute获取req域中添加 的属性String var1ObjectServletRequestWrapper
getAttributeNames获取req域中所有属性的参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数)EnumerationServletRequestWrapper
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String parameter = req.getParameter("username");
        System.out.println("获取前端传入属性值username:"+parameter);
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()){
            System.out.println("获取前端所有属性名:"+parameterNames.nextElement());
        }
    }
以下为获取路径的几个方法
方法名作用传入参数返回参数实现类
getContextPath当前项目根路径StringServletRequestWrapper
getRequestURL请求全路径URLStringBufferServletRequestWrapper
getRequestURI请求路径StringServletRequestWrapper
getServletPathservlet路径名StringServletRequestWrapper
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("当前项目根路径:"+req.getContextPath());
        System.out.println("请求全路径URL:"+req.getRequestURL());
        System.out.println("请求路径:"+req.getRequestURI());
        System.out.println("servlet路径名:"+req.getServletPath());
    }
req其他方法
方法名作用传入参数返回参数实现类
getCookies获取前端传过来的所有cookieCookie[]ServletRequestWrapper
getSession创建一个cookie,名字为JSESSIONID,并返回一个HttpSession对象HttpSessionServletRequestWrapper
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//cookie 操作
        Cookie cookie = new Cookie("cookie","thisiscooki01");
        resp.addCookie(cookie);
        Cookie[] cookies = req.getCookies();
        for (Cookie c:cookies){
            System.out.println("cookie is name :"+c.getName());
            System.out.println("cookis is value:"+c.getValue());
        }
    	//session 操作
        HttpSession session = req.getSession();
    }
响应对象方法
响应头操作
方法名作用传入参数返回参数实现类
setHeader添加响应头String var1, String var2
getHeaderNames过去所有响应头列表Collection
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	resp.setHeader("hname","this is hname");
        resp.setHeader("htype","this is htype");
        System.out.println(resp.getHeader("hname"));
        Collection<String> headerNames = resp.getHeaderNames();
        System.out.println(Arrays.toString(headerNames.toArray()));
}
设置响应编码
方法名作用传入参数返回参数实现类
setCharacterEncoding设置返回响应字符编码String var1
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	resp.setCharacterEncoding("ISO-8859-1");
}
响应类容
方法名作用传入参数返回参数实现类
getWriter返回一个操作流PrintWriterPrintWriter
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	PrintWriter writer = resp.getWriter();
     	writer.print("hello word!");
}
添加cookie操作
方法名作用传入参数返回参数实现类
addCookie在响应头中添加一个cookie,其中对cookie响应做了一定的限制Cookie
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	Cookie cookie = new Cookie("cookie","thisiscooki01");
        resp.addCookie(cookie);
}
请求与转发

session域

cookie and session

什么是cookie:客户端的文本数据,一般和seeion一起使用

什么是session:存储在服务端的文本数据,用来确认用户的真实性(比如不用重复登陆同一个网站)放在响应头cookie中传给客户端

如何获取cookie
//注意:cookie中的key 不能为Comment、Discard、Domain、Expires、Max-Age、Path、Secure、Version、和包含$,且每个字符中不能包含`c < ' ' || c >= 127 || ",; "`,错误为:cookie_name_is_token
 Cookie cookie = new Cookie("cookie","thisiscookie01");//可以添加
//调用resp.addCookie(cookie)添加cookie时value也不能包含空格:以下为错误示范
 Cookie cookie = new Cookie("cookie","this is cookie 01");
 resp.addCookie(cookie);
//添加失败:java.lang.IllegalArgumentException: Cookie值中存在无效字符
如何获取session
HttpSession session = req.getSession();
cookie的方法
方法名作用传入参数返回参数实现类
setMaxAge设置cookie最大保存时间int expiry
getMaxAge获取cookie最大保存时间int
setSecure传入true为只对安全协议发送cookie,如https,ssl,缺省值falseboolean flag
getSecure获取客户端是否是安全协议boolean
session方法
session操作域对象
方法名作用传入参数返回参数实现类
setAttribute在session域中添加对象String var1, Object var2
getAttribute获取session域中的某个对象String var1Object
getAttributeNames获取session域中所有参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数)Enumeration
removeAttribute删除某个对象String var1
session会话时间
方法名作用传入参数返回参数实现类
setMaxInactiveInterval指定servlet容器将使会话失效之前客户机请求之间的时间(以秒为单位)int var1
getMaxInactiveInterval获取指定的失效时间int

context域

如何获取context
ServletContext servletContext = req.getServletContext();
context方法
方法名作用传入参数返回参数实现类
setAttributecontext域中添加对象String var1, Object var2
getAttribute获取context域中对象String var1Object
getAttributeNames获取context域中所有参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数)Enumeration
removeAttribute删除context域中对象String var1

过滤器

初识Filter

public interface Filter {
    //项目启动时触发,且一次
    void init(FilterConfig var1) throws ServletException;
	//每次被过滤的servlet被请求时触发
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
	//项目关闭时触发
    void destroy();
}

一个Filter

实现Filter
public class Filter_dome01 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("invoke filter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("invoke dofilter");
    }

    @Override
    public void destroy() {
        System.out.println("invoke filter destroy");

    }
}
XML方式
 <filter>
        <filter-name>filter02</filter-name>
        <filter-class>com.test.servletdome.filter.Filter_dome02</filter-class>
 </filter>
 <filter-mapping>
        <filter-name>filter02</filter-name>
        <servlet-name>servlet</servlet-name>
        <!-- <url-pattern>/*</url-pattern> -->
 </filter-mapping>
注解方式
@WebFilter(filterName = "filter01",urlPatterns = "/*")
public class Filter_dome01 implements Filter {
}

filter如何放行

了解责任链模式

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("invoke dofilter");
        //调用filterChain方法给下一个filter或servlet
        filterChain.doFilter(servletRequest,servletResponse);
    }

多个filter执行顺序问题

xml方式根据filter书写的排列顺序执行

<filter>
        <filter-name>filter02</filter-name>
        <filter-class>com.test.servletdome.filter.Filter_dome02</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter02</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filter01</filter-name>
        <filter-class>com.test.servletdome.filter.Filter_dome01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter01</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在这里插入图片描述

注解的方式,根据filtername的ASCII码顺序来执行

//类Filter01,filterName=me2
@WebFilter(urlPatterns = "/*",filterName = "me2")
public class Filter01 implements Filter {}
//类Filter02,filterName=me1
@WebFilter(urlPatterns = "/*",filterName = "me1")
public class Filter02 implements Filter {}

在这里插入图片描述

监听器

监听器模式

三大监听对象

对三大域对象进行监听

ServletRequestListener
public interface ServletRequestListener extends EventListener {
    //项目关闭时执行
    void requestDestroyed(ServletRequestEvent var1);
    //servlet执行init方法时执行,一般不配置项目启动时创建servlet,就是servlet第一次访问时执行
    void requestInitialized(ServletRequestEvent var1);
}
HttpSessionListener
public interface HttpSessionListener extends EventListener {
    //每一个会话创建时执行
    void sessionCreated(HttpSessionEvent var1);
    //项目关闭时执行
    void sessionDestroyed(HttpSessionEvent var1);
}
ServletContextListener
public interface ServletContextListener extends EventListener {
    //项目启动时执行
    void contextInitialized(ServletContextEvent var1);
    //项目关闭时执行
    void contextDestroyed(ServletContextEvent var1);
}
一个监听器

实现三大监听对象,下面已ServletRequestListener为例

public class Listener_dome01 implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("Destroyed: this is ServletRequestListener");
    }
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("Initialized: this is ServletRequestListener");
    }
}
监听器与Servlet进行绑定
XML形式
<listener>
        <listener-class>com.test.servletdome.listener.Listener_dome02</listener-class>
</listener>
注释形式
@WebListener
public class Listener_dome03 implements ServletRequestListener{
}

监听器的使用请看这位博主博文

Servlet、Filter、Listener执行顺序

项目启动时执行顺序

  • ServletContextListener init -> Filter init

Initialized: this is ServletContextListener
invoke filter_02 init
invoke filter init

请求servlet 执行顺序

  • Initialized: this is ServletRequestListener -> Servlet init -> doFilter-> servlet doGet/service -> Created: this is HttpSessionListener -> Destroyed: this is ServletRequestListener

Initialized: this is ServletRequestListener
invoke servlet init
invoke dofilter02
invoke dofilter
invoke servlet doGet
Created: this is HttpSessionListener
Destroyed: this is ServletRequestListener

项目关闭时执行顺序

  • Servlet destroy -> Filter destroy -> Destroyed: this is ServletContextListener

invoke servlet destroy
invoke filter_02 destroy
invoke filter destroy
Destroyed: this is ServletContextListener

结语

你好!^ _ ^ 谢谢你能看到这里
如果你对文章类容有不同看发或文章类容存在错误,请在下方评论处指出,谢谢^ _ ^
你好!如果文章符合你的胃口,你是否愿意点个赞呢?
你好!如果文章对你有帮助,你不妨分享出去,让更多人成长!
如果文章让你喜欢,不妨点个关注交个朋友,一起共同学习!
谢谢,你的点赞,关注,分享是对我写文章不小的动力!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值