Servlet

Servlet,第1张

Servlet简单总结
  • 一、创建Servlet
    • 1、 创建Servlet的三种方式
  • 二、Servlet注解和部署
    • 1、部署
    • 2、注解
  • 三、ServletConfig接口
    • 1、获取ServletConfig对象的两种方式
    • 2、ServletConfig接口
    • 3、获取Servlet参数
  • 四、ServletContext
    • 1、获取ServletContext对象
    • 2、三个案例了解ServletContext
      • 2.1、获取上下文初始化参数
      • 2.2、实现Serlvet数据之间共享(网站访问次数)
      • 2.2、读取 Web 应用下的资源文件
  • 五、Request
    • 1、HttpServletRequest接口
      • 1.1、获取请求行数据
      • 1.2、获取请求头数据
      • 1.3、案例:获取from表单数据
  • 六、转发
    • 1、RequestDispatcher接口
    • 2、案例
  • 七、Response
    • 1、响应行方法
    • 1.2、响应体相关的方法
    • 1.3、重定向
      • 1.3.1、response.sendRedirect()
  • 八、Cookie和Session
    • 1、会话技术是什么?
      • 1.1、会话技术
    • 2、Servlet Session
      • 2.1、Session API
      • 2.1、Session域对象
  • 九、Servlet Filter
    • 1、Filter接口
    • 2、Filter工作流程
    • 3、注册与映射 Filter(案例实现)
      • 3.1通过Web.xml进行配置
      • 3.2、通过注解配置Filter
      • 3.3、案例(通过过滤器向网页上输出内容)
    • 4、FilterChain过滤器链
      • 4.1、过滤器链中的执行顺序
    • 4、FilterConfig接口

一、创建Servlet 1、 创建Servlet的三种方式

实现方式:

  1. 实现 javax.servlet.Servlet 接口,重写其全部方法。
  2. 继承 javax.servlet.GenericServlet 抽象类,重写 service() 方法。
  3. 继承 javax.servlet.http.HttpServlet 抽象类,重写 doGet() 或 doPost() 方法。

三者之间的关系:


第一种实现方式(Servlet接口):
  Servlet接口的五个方法:

  实现 javax.servlet.Servlet 接口,重写其全部方法。举例:

package com.cn.zpark;

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class CreateServlet01 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    // 	Servlet 实例化之后,由 Servlet 容器调用,用来初始化 Servlet 对象。该方法只能被调用一次。
        System.out.println("实例化成功,只能调用一次");
    }

    @Override
    //返回 ServletConfig 对象,该对象包含了 Servlet 的初始化参数
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    //每次请求,都会调用一次 service() 方法
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //设置字符集
        servletResponse.setContentType("text/html;charset=utf-8");
        //使用PrintWriter.write()方法向前台页面输出内容
        PrintWriter writer=servletResponse.getWriter();
        writer.println("创建Servlet的第一种方式");
        writer.close();
    }

    @Override
    //返回关于 Servlet 的信息,例如作者、版本、版权等
    public String getServletInfo() {
        return null;
    }
    
    @Override
    //Servelet 被销毁时调用
    public void destroy() {
        System.out.println("Servlet被销毁");
    }
}

第二种实现方式继承抽象类GenericServlet抽象类:

  此抽象类实现了Servlet接口,除了service()方法外,还提供了以下四个方法,用来获得Servlet的配置信息:

示例:
通过继承 GenericServlet 抽象类创建 Servlet,示例代码如下:

package com.cn.zpark;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
import java.io.PrintWriter;


public class CreateServlet02 extends GenericServlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //设置字符集
        servletResponse.setContentType("text/html;charset=utf-8");
        //响应内容
        PrintWriter writer=servletResponse.getWriter();
        writer.println("第二种方式通过继承GenericServlet创建");
        writer.close();
    }
}

第三种实现方式继承抽象类GenericServlet抽象类:
   javax.servlet.http.HttpServlet 继承了 GenericServlet 抽象类,用于开发基于 HTTP 协议的 Servlet 程序。由于 Servlet 主要用来处理 HTTP 的请求和响应,所以通常情况下,编写的 Servlet 类都继承自 HttpServlet。
   其中HttpServlet针对其中请求方式定义了7种方法,如即 doGet()、doPost()、doHead()、doPut()、doDelete()、doTrace() 和 doOptions()。
   HttpServlet 重写了 service() 方法,该方法会先获取客户端的请求方式,然后根据请求方式调用对应 doXxx 方法。
示例:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/lfw3")
public class CreateServlet03 extends HttpServlet {

    //在 HTTP/1.1 协议中共定义了 7 种请求方式,即 GET、POST、HEAD、PUT、DELETE、TRACE 和 OPTIONS。
    //HttpServlet 就是专为 HTTP 协议而量身打造的 Servlet 类。
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer=resp.getWriter();
        writer.println("创建Servlet的第三种方式");
        writer.close();
    }
}

总结:
  以上三种创建方式,在实际开发种我们应该选择的是HttpServlet类。
  一般来说,互联网上都是通过Http协议访问动态网页的,使用最频繁的就是GET()和POST()方法,因此,我们通常基于 HttpServlet 来创建 Servlet 类,这样就省去了处理 HTTP 请求的过程。

二、Servlet注解和部署 1、部署

配置web.xml文件:
  对 webapps\servletDemo\WEB-INF 目录的 web.xml 中进行配置,具体配置代码如下.

<servlet>
        <servlet-name>MySerletDemo01servlet-name>
        <servlet-class>com.cn.zpark.MyServletDemo01servlet-class>
        <load-on-startup>2load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>MySerletDemo01servlet-name>
        <url-pattern>/msd.dourl-pattern>
    servlet-mapping>

web.xml 中各元素含义及用法如下:

: 根元素。 :用于注册 Servlet,即给 Servlet 起一个独一无二的名字。
包含两个主要的子元素 ,分别用于指定 Servlet
的名称和 Servlet 的完整限定名(包名+类名)。
:用于定义 Servlet 与 URL 之间的映射。 包含两个子元素 ,分别用于指定 Servlet 的名称和虚拟路径。

2、注解

  @WebServlet 属于类级别的注解,标注在继承了 HttpServlet 的类之上。常用的写法是将 Servlet 的相对请求路径(即 value)直接写在注解内,如下所示。

@WebServlet(asyncSupported = true, name = "AnnotationServlet",
        description = "指定该Servlet的描述信息", loadOnStartup = 1,
        urlPatterns = {"/lfw1.do", "/lfw2.do"},
        initParams = {
        @WebInitParam(name = "京东", value = "www.jd.com",description = "参数1"),
        @WebInitParam(name="百度",value = "www.baidu.con", description = "参数2")
        } )

各注解含义如下:

属性名类型描述
nameString指定Servlet的name属性
valueString[]相当于urlPatterns属性,但是两者不能同时使用,如果同时使用,则是忽略value的值
urlPatternsString[]指定一组 Servlet 的 URL 匹配模式。
loadOnStartupint指定 Servlet 的加载顺序,取值必须是整数,取值越小,优先级越大。
asyncSupportedboolean生命Servlet是否支持异步 *** 作模式
descriptionString对Servlet描述的信息
displayNameString指定该 Servlet 的显示名。
initParamsWebInitParam[]Servlet初始化参数

注意事项:
  通过实现 Serlvet 接口或继承 GenericServlet 创建的 Servlet 类无法使用 @WebServlet 注解。
   使用 @WebServlet 注解配置的 Servlet 类,不要在 web.xml 文件中再次配置该 Servlet 相关属性。若同时使用 web.xml 与 @WebServlet 配置同一 Servlet 类,则 web.xml 中 的值与注解中 name 取值不能相同,否则容器会忽略注解中的配置。

三、ServletConfig接口

  通过源码我们就可以知道通过ServletConfig对象可以获得Servlet的初始化参数信息:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.servlet;

import java.util.Enumeration;

public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}

1、获取ServletConfig对象的两种方式

第一种:从带参的init()方法种提取,举例:

package com.cn.zpark;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

public class ConfigServlet01 extends HttpServlet {
 	//私有化
    private ServletConfig servletConfig;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//获取Servlet对象并在控制台上打印名字
        String name=servletConfig.getServletName();
        System.out.println(name);
 
    @Override
    //带参的init()方法
    public void init(ServletConfig config) throws ServletException {
        this.servletConfig=config;
    }
    }

第二种:从带参的init()方法种提取,举例:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet(value = "/lfw2.do",initParams = {
        @WebInitParam(name="password", value ="12345"),
        @WebInitParam(name="username",value = "张三")
})
public class ConfigServlet02 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //第二种获取Config对象
        // 调用GenericServlet提供的getServletConfig方法获得的ServletConfig对象
        String password=this.getServletConfig().getInitParameter("password");
        String name=this.getServletConfig().getInitParameter("username");
        System.out.println(name+password);
    }
}
2、ServletConfig接口

  提供了一些ServletConfig方法:

注意:
  这里的参数配置在前面的配置与注解里面配置。ServletConfig对象即可获取里面的参数。

3、获取Servlet参数

创建一个名为ConfigServlet01的类:

package com.cn.zpark;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

public class ConfigServlet01 extends HttpServlet {
    private ServletConfig servletConfig;
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过ServletConfig对象获得Servlet名字
        String name=servletConfig.getServletName();
        System.out.println(name);
        //使用config对象获取初始化参数
        String username=servletConfig.getInitParameter("username");
        String pwd=servletConfig.getInitParameter("pwd");
        System.out.println("username:"+username+"pwd:"+pwd);
        //使用config对象获取初始化的所有参数名
        Enumeration<String> names = servletConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            System.out.println(names.nextElement());
        }
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        this.servletConfig=config;
    }
    }

Web.xml中的配置如下:

 <servlet>
        <servlet-name>ConligServlet01servlet-name>
        <servlet-class>com.cn.zpark.ConfigServlet01servlet-class>
        <init-param>
            <param-name>usernameparam-name>
            <param-value>张三param-value>
        init-param>
        <init-param>
            <param-name>pwdparam-name>
            <param-value>123456param-value>
        init-param>
    servlet>
    <servlet-mapping>
        <servlet-name>ConligServlet01servlet-name>
        <url-pattern>/lfwurl-pattern>
    servlet-mapping>

访问结果如下:

四、ServletContext

  Servlet 容器启动时,会为每个 Web 应用(webapps 下的每个目录都是一个 Web 应用)创建一个唯一的 ServletContext 对象,该对象一般被称为“Servlet 上下文”ServletContext 对象的生命周期从 Servlet 容器启动时开始,到容器关闭或应用被卸载时结束。
  ServletContext 的应用主要有以下 3 个:
  (1)获取上下文初始化参数
  (2)实现 Servlet 之间的数据通讯
  (3)读取 Web 应用下的资源文件

1、获取ServletContext对象

获取ServletContext对象有四种方式:

package com.cn.zpark;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ContextServlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 第一种方式通过GenericServlet的getServletContext方法获取ServletContext对象
        ServletContext servletContext1=this.getServletContext();
        System.out.println("第一种方式获取ServletContext对象:"+servletContext1);

        //第二种通过ServletConfig获取
        ServletContext servletContext2=this.getServletConfig().getServletContext();
        System.out.println("第二种方式获取ServletConfig:"+servletContext2);

        //第三种方式通过通过 HttpSession的 getServletContext方法获取ServletContext对象
        ServletContext servletContext3 = request.getSession().getServletContext();
        System.out.println("第三种方式获得:"+servletContext3);

        //第四种通过 HttpServletRequest的 getServletContext方法获取ServletContext对象
        ServletContext servletContext4= request.getServletContext();
        System.out.println("第四种方式:"+servletContext4);
    }
}
2、三个案例了解ServletContext 2.1、获取上下文初始化参数

配置全局初始化参数:

<context-param>
        <param-name>username</param-name>
        <param-value>小明</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>123456</param-value>
    </context-param>

标签解释:
元素用来声明上下文初始化参数,必须在根元素 内使用。
子元素表示参数名,参数名在整个 Web 应用中必须是唯一的。
子元素表示参数值。

创建个名为ContextServlet02的类:

package com.cn.zpark;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

/*
  1. 获取上下文初始化参数
 */
@WebServlet("/lfw2")
public class ContextServlet02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过ServletContext对象获取上下文初始化参数
        ServletContext servletContext= request.getServletContext();
        String username = servletContext.getInitParameter("username");
        String password = servletContext.getInitParameter("password");
        System.out.println(username+"  "+password);
        //循环遍历所有的参数名
        Enumeration<String> names = servletContext.getInitParameterNames();
        while (names.hasMoreElements()) {
            System.out.println(names.nextElement());
        }
    }
}

访问结果:

2.2、实现Serlvet数据之间共享(网站访问次数)

  在 Servlet 中,调用 ServletContext 接口的 setAttribute() 方法可以创建一些属性,这些属性被存放在 ServletContext 对象中。应用中所有 Servlet 都可以对这些属性进行访问和 *** 作,通过它们可以实现应用内不同 Servlet 之间的数据通讯。
  关于数据通讯中的方法:

创建一个名称为 ContextServlet03和ContextServlet04的 Servlet 类,代码如下:

package com.cn.zpark;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/*
  2.实现 Servlet 之间的数据通讯
 */
@WebServlet("/lfw3")
public class ContextServlet03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  	  //获取ServletContext对象
        ServletContext servletContext=request.getServletContext();
        Integer count =(Integer) servletContext.getAttribute("count");
        ++ count;
        //更新绑定数据
        servletContext.setAttribute("count",count);
        //设置响应格式
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer= response.getWriter();
        writer.println("该网站一共被访问了"+count+"次");
        writer.close();
    }
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        //实例化时, 先获取ServletContext对象(通过ServletConfig对象获取)
        ServletContext servletContext= config.getServletContext();
        //绑定数据在servletContext中,起始站为0
        servletContext.setAttribute("count",0);
    }
}

第二个类ContextServlet04:

package com.cn.zpark;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/lfw4")
public class ContextServlet04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext=request.getServletContext();
        Integer count =(Integer) servletContext.getAttribute("count");
        ++ count;
        //更新绑定数据
        servletContext.setAttribute("count",count);
        //设置响应格式
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer= response.getWriter();
        writer.println("该网站一共被访问了"+count+"次");
        writer.close();

    }
}

访问结果如下:

2.2、读取 Web 应用下的资源文件

  读取Web应用中的资源。首先我们来看一下Servlet接口定义读取Web资源的方法:

  首先在web-app/WEB-INF/下创建一个名为dp.properties的文件:

name=Servlet
url=com.zpark
desc=Beijing

在创建一个名为ContextServlet05的Servlet类:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Properties;

/**
 * @PackageName: com.zpark.context
 * @ClassName: ReadPropertiesServlet
 * @Description: 使用ServletContext读取资源文件
 * @author: RZS
 * @date: 2021/10/6  12:08
 */
@WebServlet("/readProperties.do")
public class ContextServlet05 extends HttpServlet {

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();

        // 获取相对路径中的输入流对象
        InputStream ins = getServletContext().getResourceAsStream("/WEB-INF/db.properties");

        // 获取输入流
        Properties pro = new Properties();

        // 加载, new InputStreamReader(ins, "utf-8")解决中文乱码问题
        pro.load(new InputStreamReader(ins, "utf-8"));

        // 获取文件中的内容
        String name = pro.getProperty("name");
        String url = pro.getProperty("url");
        String desc = pro.getProperty("desc");
        writer.write("用户名:" + name + "
"
+ "地址:" + url + "
"
+ "描述:" + desc + "
"
); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

访问过程如下:

五、Request 1、HttpServletRequest接口

  在 Servlet API 中,定义了一个 HttpServletRequest 接口,它继承自 ServletRequest 接口。HttpServletRequest 对象专门用于封装 HTTP 请求消息,简称 request 对象。
  HTTP 请求消息分为请求行、请求消息头和请求消息体三部分,所以 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法。
  关于请求报文格式如图:

1.1、获取请求行数据

  HttpServlet接口定义了以下获取请求行的方法:

  我们创建一个名为HttpServletRequest01的Servlet的类展示上面的方法:

package com.cn.zpark;


import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/*
 1、获取请求行信息
 */

@WebServlet("/lfw")
public class HttpServletRequest01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer=response.getWriter();
        //获取Http请求方式 get/post
        
        String method = request.getMethod();
        //该方法用于获取请求行中的资源名称部分
        
        String requestURI = request.getRequestURI();
        //方法用于获取请求行中的参数部分,也就是 URL 中“?”以后的所有内容
        
        String queryString = request.getQueryString();
        //返回当前 Servlet 所在的应用的名字(上下文)
        
        request.getContextPath();
        //获取Servlet所映射的路径
        
        String servletPath = request.getServletPath();
        //获取客户端的IP地址
        
        String remoteAddr = request.getRemoteAddr();
        //获取客户端的完整主机名
        
        String remoteHost = request.getRemoteHost();
         writer.println("HTTP请求方式:" +method+"

请求的资源名称:"+requestURI+ "

获取请求行的参数部分:"+queryString+ "

获取Servlet所映射的路径:"+servletPath+"

获取客户端的IP地址:"+remoteAddr+ "获取客户端的完整主机名:"+remoteHost ); writer.close(); } }

访问结果:

1.2、获取请求头数据

  HttpServletRequest 接口定义了一系列获取请求行信息的方法,如下表:

  我们创建一个名为HttpServletRequest02的Servlet类,实现上面方法:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

/*
  2、获取请求头信息
 */
@WebServlet("/lfw2")
public class HttpServletRequest02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应格式
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer=response.getWriter();
        request.setCharacterEncoding("UTF-8");
        String accept = request.getHeader("Accept");
        writer.println(accept);
        //获取请求头所有的头字段
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            //获取所有头字段所对应的值
            String value = request.getHeader(key);
            writer.println(key+": "+value+"

"); } } }

访问结果:

1.3、案例:获取from表单数据

  在webapp下创建一个名为form.html的文件:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<form action="/05_Request_war/lfw3" method="get">
    <label>请输入用户名label>
    <input type="text" name="username">
    <br>
    <label>请输入密码label>
    <input type="password" name="password">
    <input type="submit">
form>

body>
html>

  在创建一个名为HttpServletRequest03的Servlet类:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/*
  获取表单的数据
 */
@WebServlet("/lfw3")
public class HttpServletRequest03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer= response.getWriter();

        //获取表单的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //将参数写入网页
        writer.println("username: "+username+"

"+ "password:"+password+"

"+ queryString); } }

访问结果:

六、转发

  转发流程:

  1. 绑定数据域setAttribute()
  2. 获取转发器getRequestDispatcher(String var),括号中的参数为转发的资源路径。
  3. 调用forward(ServletRequest request,ServletResponse response)
    方法。用于将请求转发给另一个 Web 资源。
1、RequestDispatcher接口

  利用 RequestDispatcher 对象可以把请求转发给其他的 Web 资源
  Servlet 可以通过 2 种方式获得 RequestDispatcher 对象:

  1、调用 ServletContext 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,必须为绝对路径;

  2、调用 ServletRequest 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,可以为绝对路径,也可以为相对路径。
  接口中提供了以下两个方法:

2、案例

  我们创建三个Servlet类,分别为HttpServletRequest04、HttpServletRequest05:
  HttpServletRequest04类代码如下:

package com.cn.zpark;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/lfw4")
public class HttpServletRequest04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("转达之前的请求servletRequest04");

        //将数据绑定域中
        request.setAttribute("name", "转发的测试");
        request.setAttribute("desc","我爱Servlet");

        //获取转发器
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/lfw5");
        //交给下雨给WEB资源或者转发器
        requestDispatcher.forward(request, response);

    }
}

  HttpServletRequest05类代码如下:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/lfw5")
public class HttpServletRequest05 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer=response.getWriter();
        writer.println("转达到HttpServletRequest05");
		//将数据域中的数据取出
        String name =(String) request.getAttribute("name");
        String desc =(String) request.getAttribute("desc");
        writer.println(""+name+desc+"");

    }
}

访问结果如下:

七、Response

  在 Servlet API 中,定义了一个 HttpServletResponse 接口,它继承自 ServletResponse 接口。HttpServletResponse 对象专门用来封装 HTTP 响应消息,简称 response 对象。
  HTTP响应的消息分别有响应行、响应头、响应头三部分组成,如下:

1、响应行方法

当 Servlet 返回响应消息时,需要在响应消息中设置状态码。因此,HttpServletResponse 接口定义了发送状态码的方法,如下:

1.setStatus(int status),返回值 void,用于设置HTTP响应的状态码,并且生成响应状态行。
2.sendError(int sc),返回值 void,用于发送表示错误信息的状态码。

方法示例1:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/*
    设置响应行信息
 */
@WebServlet("/l1.do")
public class ResponseDemo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 用于设置 HTTP 响应消息的状态码,并生成响应状态行.
        response.setStatus(500);

    }
}

访问结果如下:

方法示例2:


package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/l2.do")
public class ResponseDemo02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 用于发送表示错误信息的状态码。
        response.sendError(22250,"发生错误啦");

    }
}

访问结果:

1.2、响应体相关的方法

  由于在 HTTP 响应消息中,大量的数据都是通过响应消息体传递的。因此 ServletResponse 遵循以 I/O 流传递大量数据的设计理念,在发送响应消息体时,定义了两个与输出流相关的方法:

  1. getOutputStream(),返回值 ServletOutputStream,用于获取字节输出流对象
  2. getWriter(),返回值 PrintWriter,用于获取字符输出流对象。
      两个方法不可同时使用。
1.3、重定向

  了解重定向的流程,流程图如下:

  重定向和转发的主要区别:

  1. 重定向浏览器地址栏 URL发生改变,而转发不发生改变。
  2. 重定向支持跨域跳转,而转发不会。
  3. 重定向两次响应和请求,而转发只有一次。
  4. 重定向不共享request和response对象,而转发共享。
  5. 重定向不能通过reque域对象传递数据。
  6. 重定向的相对要慢。
  7. 重定向行为是客户端行为,而重定向是服务器行为。
1.3.1、response.sendRedirect()

  HttpServletResponse接口中的 sendRedirect() 方法用于实现重定向:
  方法:sendRedirect(Strign location),返回值:void,参数location表示重定向的URL。
举例:
  创建一个名为ResponseDemo03的Servlet类:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/l3.do")
public class ResponseDemo03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        // 设置缓冲区的格式
        PrintWriter writer=response.getWriter();
        writer.println("其实天天都时候学习Java");
    }
}

  创建一个实现重定向的名为ResponseDemo05的Servlet类:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/l5.do")
public class ResponseDemo05 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 重定向
        response.sendRedirect("./l3.do");
    }
}

访问过程:


  可以看到URL从/l5.do变成了/l3.do。

八、Cookie和Session 1、会话技术是什么?

  当人们打开浏览器到关闭浏览器的过程,我们称之为一次会话。而会话技术值得是在会话,帮助用户记录用户状态和数据的技术。
  常用的会话技术分为两种:

  1. Cookie: 客户端会话技术
  2. Session:服务端会话技术
1.1、会话技术

  javax.servlet.http 包中定义了一个 Cookie 类,利用它的带参构造方法,可以创建 Cookie 对象。例如:

Cookie cook1 = new Cookie("C1","这就是cook1");
Cookie cook2 = new Cookie("C2","这就是cook2");

  javax.servlet.http.Cookie 类中提供了一系列获取或者设置 Cookie 的方法:

  1. getMaxAge(),返回类型:int,用于获取指定 Cookie 的最大有效时间,以秒为单位。 默认情况下取值为 -1,表示该 Cookie 保留到浏览器关闭为止。
  2. getName(),返回类型:String,获取 Cookie 的名称。
  3. getPath(),返回类型String,获取 Cookie 的有效路径。
  4. getValue(),返回值String,获取Cookie的值。
  5. setMaxAge(int expiry),返回类型:void,设置 Cookie 的最大有效时间,以秒为单位。
  6. setPath(String uri),返回类型:void,指定 Cookie 的路径。
  7. setValue(String newValue),返回类型:void,设置 Cookie 的值。

  我们创建设置和获取Cookie的CookieDemo01、CookieDemo02的Servlet的类:
  CookieDemo01:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/l1.do")
public class CookieDemo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建cookie对象
        Cookie cook1 = new Cookie("C1","这就是cook1");
        Cookie cook2 = new Cookie("C2","这就是cook2");

        // 设置cookie 失效时间,单位秒
        cook1.setMaxAge(60);
        //将Cookie信息添加到响应信息中
        response.addCookie(cook1);
        response.addCookie(cook2);

    }
}

  CookieDemo02:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/l2.do")
public class CookieDemo02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        //循环遍历信息
        for (Cookie cookie : cookies) {
            // 获取Cookie名字
            String name= cookie.getName();
            // 获取Cookies的值
            String value= cookie.getValue();
            System.out.println(name+"   "+ value);
            System.out.println(cookie.getMaxAge());
        }
    }
}

2、Servlet Session

   Session 是服务器端会话技术。当浏览器访问 Web 服务器的资源时,服务器可以为每个用户浏览器创建一个 Session 对象,每个浏览器独占一个 Session 对象。

2.1、Session API

  获取HttpSession对象可以通过:

// 获取Session对象
        HttpSession session=request.getSession();

  HttpSession 接口定义了一系列对 Session 对象 *** 作的方法,如下:

  1. getCreationTime(),返回类型:long,创建Session的时间。
  2. getId(),返回类型:String,返回获取Session的唯一ID。
  3. invalidate(),返回类型:void,让Session失效。
  4. getLastAccessedTime(),返回类型:long,返回客户端上次发送与此Session关联的请求时间。
  5. getServletContext(),返回类型:ServletContext,返回 Session 所属的 ServletContext 对象。
  6. setMaxInactiveInterval(int interval),返回类型:void,指定在无任何 *** 作的情况下,Session 失效的时间,以秒为单位。负数表示 Session 永远不会失效。
    举例:
    我们创建一个名为SessionDemo01的Servliet的类:
package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/l1.do")
public class SessionDemo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取Session对象
        HttpSession session=request.getSession();

        //获取Session的id
        System.out.println(session.getId());

        //获取Session的默认有效时间
        System.out.println(session.getMaxInactiveInterval());

        //返回Session创建的时间
        System.out.println(session.getCreationTime());

        //返回当前系统时间
        System.out.println("当前系统时间:"+System.currentTimeMillis());

        // 返回客户端上一次发送与此 Session 关联的请求的时间
        System.out.println(session.getLastAccessedTime());

        //设置Session的有效时间
         session.setMaxInactiveInterval(100);

        //销毁Session
        session.invalidate();
    }
}

访问过程:

Session 对象在如下 3 种情况下会被销毁:
​ (1)Session 过期;
​ (2)调用 session.invalidate() 方法,手动销毁 Session;
​ (3)服务器关闭或者应用被卸载。

2.1、Session域对象

我们知道域对象包含了一系列的 *** 作属性的方法:

  1. setAttribute(String name, Object o),返回类型:void,把一个 Java 对象与一个属性名绑定,并将它作为一个属性存放到 Session 对象中。 参数 name 为属性名,参数 object 为属性值。

  2. getAttribute(String name),返回类型:void,根据指定的属性名 name,返回 Session 对象中对应的属性值。

  3. removeAttribute(String name),返回类型:void,从 Session 对象中移除属性名为 name 的属性。

  4. getAttributeNames(),返回类型:Enumeration,用于返回 Session 对象中的所有属性名的枚举集合。
    举例:
    创建绑定数据的SessionDemo02的Servlet的类和获取数据的SessionDemo03的Servlet的类。
    SessionDemo02:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/l2.do")
public class SessionDemo02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session=request.getSession();
        //绑定数据到Session域中
        session.setAttribute("uname", "我超级喜欢Java");
    }
}

SessionDemo03:

package com.cn.zpark;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;


@WebServlet("/l3.do")
public class SessionDemo03 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取Session域
        HttpSession session = request.getSession();
        String uname =(String) session.getAttribute("uname");
        System.out.println(uname);

    }
}

访问过程:

九、Servlet Filter

  Servlet Filter 又称 Servlet 过滤器,它是在 Servlet 2.3 规范中定义的,能够对 Servlet 容器传给 Web 资源的 request 对象和 response 对象进行检查和修改。

1、Filter接口

  javax.servlet.Filter 接口提供了一下方法:

1.init (FilterConfig filterConfig),返回类型:void,该方法用于初始化过滤器。
2.doFilter(ServletRequest request,SeivletResponse response, FilterChain chain),返回类型:void,参数 request 和 response 表示请求和响应对象。 参数 chain 代表当前 Filter 链对象,在该方法内部,调用 chain.doFilter() 方法,将请求传给下一个 Filter 或者 Web 资源。
3. destroy(),返回类型:void,释放被 Filter 对象占用的资源。

2、Filter工作流程

流程图:
1.Filter生命周期:

  1. 初始化阶段,init()方法,只执行一次。
  2. 拦截和过滤阶段,doFilter()方法,并调用该方法对请求/响应进行拦截和过滤。
  3. 销毁阶段:在 Filter 的生命周期内,destory() 只执行一次。
3、注册与映射 Filter(案例实现)

注册和映射 Filter 有 2 种方式:

  1. 通过 web.xml 配置
  2. 通过 @WebFilter 注解配置
3.1通过Web.xml进行配置

通过注册过滤器:

<filter>
        <filter-name>LoginFilterTestfilter-name>
        <filter-class>com.cn.zpark.filter.LoginFilterTestfilter-class>
        <init-param>
            <param-name>usernameparam-name>
            <param-value>张三param-value>
        init-param>
        <init-param>
            <param-name>passwordparam-name>
            <param-value>123456param-value>
        init-param>
    filter>
    
    <filter-mapping>
        <filter-name>LoginFilterTestfilter-name>
        <url-pattern>/login1url-pattern>
        <dispatcher>REQUESTdispatcher>
    filter-mapping> 

标签说明:

1、<filter> 注册过滤器
2、<filter-name><filter-calss><filter>的子元素分别指定过滤器的名称和过滤器的完整限定名(类名+包名)
3、<init-param><filter> 元素的子元素,用于为过滤器指定初始化参数,它的子元素 <param-name> 指定参数的名称,<param-value> 指定参数的值。可以配置多个参数
3、<filter-mapping> 元素用于设置 Filter 负责拦截的资源。
4、<filter-name><url-pattern><filter-mapping>的子元素,分别设置filte的注册名和需要拦截的资源路径。
5、<dispatcher>指定 Filter 拦截的资源被 Servlet 容器调用的方式。

其中元素有四个取值:

  1. REQUEST:当用户直接访问页面时,容器将会调用过滤器。如果目标资源是通过 转发器的 include() 或 forward() 方法访问,则该过滤器就不会被调用。
  2. INCLUDE:如果通过转发器的 include() 方法访问,则该过滤器将被调用。除此之外,该过滤器不会被调用。
  3. FORWARD:如果通过转发器的 forward() 方法访问,则该过滤器将被调用,除此之外,该过滤器不会被调用。
  4. ERROR:如果通过声明式异常处理机制访问,则该过滤器将被调用。除此之外,过滤器不会被调用。
3.2、通过注解配置Filter
@WebFilter(filterName = "FilterDemo02", urlPatterns ={"/filter2.do"},
          servletNames = "servlet", dispatcherTypes = {
          DispatcherType.ASYNC, DispatcherType.ERROR,
          DispatcherType.FORWARD, DispatcherType.INCLUDE},
          asyncSupported = true,description = "Filter注解",
          initParams = {@WebInitParam(name= "username",value = "张三"),
                         @WebInitParam(name = "pwd", value = "123")})

以上属性名的含义:

filterName ,类型:String,表示过滤器的name属性,等价于<filter-name>元素。
urlPatterns,类型:String[],表示过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。
value,		 类型:String[],属性等价于 urlPatterns 属性,但是两者不能同时使用。
servletNames,类型:String[],过滤器将应用于哪些 Servlet。
dispatcherTypes,类型:DispatcherType,过滤器拦截的资源被 Servlet 容器调用的方式,上述四种方式。
initParams,类型:WebInitParam[],用于过滤器初始化参数,等价于 <init-param> 标签。
asyncSupported,类型:boolean,声明过滤器是否支持异步 *** 作模式,等价于 <async-supported> 标签。
description,类型:String,表示过滤器的描述信息,等价于 <description> 标签。
displayName,类型:String,表示过滤器的显示名,等价于<display-name> 标签。
3.3、案例(通过过滤器向网页上输出内容)

我们在包为com.cn.zaprk.servlet下创建一个名为ServletDemo01的Servlet的类:

package com.cn.zpark.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/l1.do")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("ServletDemo01处理请求");
    }
}

我们在包为com.cn.zaprk.servlet下创建一个名为FilterDemo01的Filter的类:
package com.cn.zpark.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FilterDemo01 implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化成功");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    //  将请求、响应对象做类型转换 *** 作
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        //设置请求缓冲区编码
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("通过Filter向页面输出内容");
        //转给下一个filtet或者web资源
        chain.doFilter(req, resp);
    }

    @Override
    public void destroy() {
        System.out.println("filter被销毁");
    }
}

访问过程:

4、FilterChain过滤器链

  我们可以部署多个 Filter,如果这些 Filter 都拦截同一目标资源,则它们就组成了一个 Filter 链(也称过滤器链)。每个过滤器都执行 响应的任务,直到传递最终目标资源。

4.1、过滤器链中的执行顺序

  通过 web.xml 配置的 Filter 过滤器,执行顺序由 标签的配置顺序决定。 靠前,则 Filter 先执行,靠后则后执行。通过修改 的顺序便可以修改 Filter 的执行顺序。
  我们创建两个Filter类分别过滤一个Servler类:
  Servlet类:

package com.cn.zpark.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/chain.do")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("ServletDemo01处理请求");
    }
}

  FilterDemo03的Filter类:
package com.cn.zpark.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FilterDemo03 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write(""+"第一个过滤器拦截成功"+"

"); filterChain.doFilter(req,resp); } @Override public void destroy() { Filter.super.destroy(); } }


  FilterDemo04的Filter类:
package com.cn.zpark.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FilterDemo04 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        HttpServletResponse resp=(HttpServletResponse) response;
        HttpServletRequest res=(HttpServletRequest) request;
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write(""+"第二个过滤器拦截成功"+"

"); filterChain.doFilter(res,resp); } }

&emps; 通过Web.xml配置如下:

    
    <filter>
        <filter-name>FilterDemo03filter-name>
        <filter-class>com.cn.zpark.filter.FilterDemo03filter-class>
    filter>
    <filter-mapping>
        <filter-name>FilterDemo03filter-name>
        <url-pattern>/chain.dourl-pattern>
    filter-mapping>

    
    <filter>
        <filter-name>FilterDemo04filter-name>
        <filter-class>com.cn.zpark.filter.FilterDemo04filter-class>
    filter>
    <filter-mapping>
        <filter-name>FilterDemo04filter-name>
        <url-pattern>/chain.dourl-pattern>
   filter-mapping>

  访问过程:

4、FilterConfig接口

   FilterCofig 与 ServletConfig 接口相似,用于在过滤器初始化期间向其传递信息。FilterConfig 接口由容器实现,容器将它作为参数传入过滤器的 init() 方法中。
   通过 filterConfig 对象就可以获得 Filter 的初始化参数。在 FilterConfig 接口中,定义了 4 个方法,如下:

  1. getInitParameter(String name), 返回值类型:String,根据参数名获取相应参数值。
  2. getInitParameterNames(),返回值类型:Enumeration,返回过滤器所有参数名的集合。
  3. getServletContext(),返回值类型:ServletContext,返回 Servlet 上下文对象。
  4. getFilterName(),返回值类型:String,返回过滤器的名称。

案例:
  创建一个名为FilterDemo02的Filter和ServlerDemo01的Servlet的类:
  在com.cn.zpark.servlet包下的ServlerDemo01:

package com.cn.zpark.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/filter2.do")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("通过FilterConfig获取参数");
    }
}

在com.cn.zpark.filter包下FilterDemo02:

package com.cn.zpark.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebFilter( value ={"/filter2.do"},
  initParams = {@WebInitParam(name= "username",value = "张三"),
                         @WebInitParam(name = "pwd", value = "123")})
public class FilterDemo02 implements Filter {
    private  FilterConfig config;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config=filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest) request;
        HttpServletResponse reqs=(HttpServletResponse) response;
        //设置响应格式
        reqs.setContentType("text/html;charset=utf-8");

        //返回过滤器的名称
        String filterName = config.getFilterName();
        response.getWriter().write(""+filterName+"");

        //获取过滤器参数,通过FilterConfig对象
        String username = config.getInitParameter("username");
        String pwd = config.getInitParameter("pwd");
        response.getWriter().write(""+username+": "+pwd+"");

        //获取所有参数名
        Enumeration<String> initParameterNames = config.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            response.getWriter().write(""+initParameterNames.nextElement()+"");
        }
        System.out.println("过滤器过滤");
        filterChain.doFilter(req, reqs);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

访问过程:

  此案例在这只是为了展示以上FilterConfig接口中的方法,在实际开发过程并无作用。
  通过它可以对服务器管理的所有 Web 资源,例如黑名单过滤、过滤敏感词、设置统一编码格式等。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/719726.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存