JavaWeb重点笔记

文章目录

  • 一、开发工具
    • 1.1 JDK安装
    • 1.2 Tomcat 安装
    • 1.3 IDEA创建JavaWeb项目
    • 1.4 IDEA集成Tomcat
  • 二、Servlet
    • 2.1 Servlet 语法格式
    • 2.2 Servlet执行过程
    • 2.3 Servlet 生命周期
    • 2.4 Servlet继承体系
    • 2.5 使用HttpServlet
    • 2.6 ServletContext
      • 2.6.1 获取全局配置参数
      • 2.6.2 获取web项目的资源
      • 2.6.3 在Servlet间共享数据域对象
      • 2.6.4 Servlet解决web乱码问题
    • 2.7 ServletConfig
    • 2.8 HttpServletRequest
      • 解决request请求数据中文乱码问题
    • 2.9 HttpServletResponse
      • 解决response响应数据中文乱码问题
    • 2.10 重定向和请求转发
      • 2.10.1 重定向(完全的跳转)
      • 2.10.2 请求转发(内部转发)
    • 2.11 Cookie
    • 2.12 Session
  • 三、Listener
    • 3.1 监听三个作用域创建和销毁
      • 3.1.1 ServletContextListener
      • 3.1.2 ServletRequestListener
      • 3.1.3 HttpSessionListener
    • 3.2 监听三个作用域属性状态变更
      • 3.2.1 ServletContextAttributeListener
      • 3.2.2 ServletRequestAttributeListener
      • 3.2.3 HttpSessionAttributeListener
    • 3.3 监听HttpSession存值状态变更
      • 3.3.1 HttpSessionBindingListener
      • 3.3.2 HttpSessionActivationListener
  • 四、Filter
    • 4.1 Filter概述
    • 4.2、Filter生命周期
    • 4.3、Filter语法
    • 4.4 Filter匹配规则
    • 4.5 Filter拦截类型
    • 4.6 Filter统一编码
  • 五、Servlet3.0
    • 5.1 注解开发
      • 5.1.1 servlet注解
      • 5.1.2 Filter注解
      • 5.1.3 listener注解
      • 5.1.4 注解与XML两种配置同时存在的说明
      • 5.1.5 如何禁用注解组件
    • 5.2 文件上传

一、开发工具

1.1 JDK安装

第一步:打开官网进行下载

JavaWeb重点笔记_第1张图片
第二步:运行程序进行安装

注意:如果自己会配置JDK,可以更改它的安装路径,那相应的环境变量也需要修改!

第三步:系统环境变量配置

此电脑 》 右键 》 属性 》 高级系统设置 》 环境变量 》 系统变量 》 新建(需要新建两个,然后修改一个)

新建两个:JAVA_HOME代表Java的安装目录、CLASSPATH代表程序运行的时候,优先加载当前目录中的类,然后再加载指定的类库

变量名 变量值
JAVA_HOME C:\Program Files\Java\jdk1.8.0_261
CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

修改一个:编辑PATH环境变量,它会打开一个窗口,新添两条路径,如下图所示

  • %JAVA_HOME%\bin
  • %JAVA_HOME%\jre\bin
    JavaWeb重点笔记_第2张图片
    第四步:测试JDK是否安装成功
    打开一个cmd命令行窗口,输入以下两个命令查看,如果有内容输出则证明已经配置成功!
  • java -version
  • javac -version

JavaWeb重点笔记_第3张图片

1.2 Tomcat 安装

第一步:打开官网进行下载和安装
JavaWeb重点笔记_第4张图片
JavaWeb重点笔记_第5张图片
第二步:系统环境变量配置
此电脑 》 右键 》 属性 》 高级系统设置 》 环境变量 》 系统变量 》 新建(需要新建两个,然后修改三个)

新建两个:CATALINA_BASE和CATALINA_HOME均代表Tomcat的安装目录

变量名 变量值
CATALINA_BASE C:\DevTools\apache-tomcat-8.5.57(输入自己解压的Tomcat目录,不要照抄我的)
CATALINA_HOME C:\DevTools\apache-tomcat-8.5.57 输入自己解压的Tomcat目录,不要照抄我的)

修改一个:编辑CLASSPATH环境变量,它会打开一个窗口,具体修改,如下所示

  • 未修改前:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
  • 修改以后:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\lib\servlet-api.jar;

修改两个:编辑PATH环境变量,它会打开一个窗口,新添两条路径,如下所示

  • %CATALINA_HOME%\bin
  • %CATALINA_HOME%\lib
    JavaWeb重点笔记_第6张图片
    第三步:测试Tomcat是否安装成功

打开一个cmd命令行窗口,输入以下一个命令查看,如果有内容输出则证明已经配置成功!

  • catalina run

JavaWeb重点笔记_第7张图片

  • 打开浏览器,输入:http://localhost:8080/

JavaWeb重点笔记_第8张图片

1.3 IDEA创建JavaWeb项目

  1. File->new-Project-Java

JavaWeb重点笔记_第9张图片
JavaWeb重点笔记_第10张图片
2. 在项目目录下的WEB-INF中,创建lib文件夹存放jar文件的
JavaWeb重点笔记_第11张图片
3. FIle->Project Structure…进行项目配置

JavaWeb重点笔记_第12张图片
4. 配置jar文件的路径

JavaWeb重点笔记_第13张图片

1.4 IDEA集成Tomcat

第一步:打开配置
JavaWeb重点笔记_第14张图片
第二步:添加tomcat服务器
JavaWeb重点笔记_第15张图片
检查添加是否成功:
JavaWeb重点笔记_第16张图片

第三步:运行tomcat
JavaWeb重点笔记_第17张图片

二、Servlet

2.1 Servlet 语法格式

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

第一步:创建包(com.caochenlei.servlet.demo)

第二步:创建类(com.caochenlei.servlet.demo.MyServlet),并且需要实现Servlet接口中的所有方法

package com.caochenlei.servlet.demo;

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

public class MyServlet implements Servlet {
     
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
     
        System.out.println("MyServlet init ...");
    }

    @Override
    public ServletConfig getServletConfig() {
     
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) 
            throws ServletException, IOException {
     
        System.out.println("MyServlet service ...");
    }

    @Override
    public String getServletInfo() {
     
        return null;
    }

    @Override
    public void destroy() {
     
        System.out.println("MyServlet destroy ...");
    }
}

方法介绍:

  • init:Servlet初始化时调用的方法
  • getServletConfig:获取当前Servlet的配置信息
  • service:调用Servlet真正去处理逻辑的方法
  • getServletInfo:它提供有关Servlet的信息,如作者、版本、版权
  • destroy:Servlet销毁时调用的方法

第三步:配置映射(web.xml中新增以下代码)

    <servlet>
        <servlet-name>MyServletservlet-name>
        <servlet-class>com.caochenlei.servlet.demo.MyServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>MyServletservlet-name>
        <url-pattern>/MyServleturl-pattern>
    servlet-mapping>

配置介绍:

servlet标签用于配置Servlet的基本信息

  1. servlet-class:代表当前Servlet的具体类路径,注意最后不包含.java
  2. servlet-name:代表当前Servlet的别名,可以和原Servlet名称一样,也可以不一样,一般我们就一样就行了

servlet-mapping标签用于配置请求路径与具体处理Servlet的对应关系

  1. url-pattern:这里写你要匹配的地址路径
  2. servlet-name:如果匹配到请求,该交给哪一个Servlet处理,这里的servlet-name其实就是一个Servlet的别名

第四步:启动应用,然后浏览器输入地址访问(http://localhost:8080/myJavaWebDemo_war_exploded/MyServlet)

JavaWeb重点笔记_第18张图片

第五步:正常关闭Tomcat服务器,我们会看到调用销毁方法,如下图所示:
JavaWeb重点笔记_第19张图片

2.2 Servlet执行过程

JavaWeb重点笔记_第20张图片

2.3 Servlet 生命周期

Servlet的生命周期通过javax.servlet.Servlet接口中的init()、service()和destroy()方法来表示。

Servlet的生命周期包含了下面4个阶段:

  1. 类加载和实例化
  2. 初始化:init()
  3. 请求处理:service()
  4. 销毁:destroy()

2.4 Servlet继承体系

子类HttpServlet,我们只要继承这个类重写GET、POST方法就能实现一个简单的Servlet请求处理,Servlet的继承体系如下图:
JavaWeb重点笔记_第21张图片

2.5 使用HttpServlet

第一步:创建类(com.caochenlei.servlet.demo.MyHttpServlet),并且需要继承HttpServlet实现doPost、doGet方法。

package com.caochenlei.servlet.demo;

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

public class MyHttpServlet extends HttpServlet {
     
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
     
        System.out.println("doPost method 执行...");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
     
        System.out.println("doGet method 执行...");
    }
}

第二步:配置映射(在web.xml文件中新增以下代码)

<servlet>
        <servlet-name>MyHttpServletservlet-name>
        <servlet-class>com.caochenlei.servlet.demo.MyHttpServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>MyHttpServletservlet-name>
        <url-pattern>/MyHttpServleturl-pattern>
    servlet-mapping>

** 第三步:重启应用,然后浏览器访问(http://localhost:8080/myJavaWebDemo_war_exploded/MyHttpServlet),观察控制台 **
JavaWeb重点笔记_第22张图片
我们注意url-pattern它可以有多种拦截形式:

  • 全路径匹配:/a
  • 前半段匹配:/a/b/c/*
  • 扩展名匹配:*.action

2.6 ServletContext

每个web工程都只有一个ServletContext对象,它用来获取Servlet的上下文,在服务器启动的时候,会为托管的每一个web应用程序,创建一个ServletContext对象,当从服务器移除托管或者是关闭服务器时,ServletContext将会被销毁。它主要有以下几方面作用:

  • 获取全局配置参数
  • 获取web工程中的资源
  • 在servlet间共享数据域对象

2.6.1 获取全局配置参数

第一步:在web.xml中新增以下代码

    <context-param>
        <param-name>usernameparam-name>
        <param-value>zhangsanparam-value>
    context-param>
    <context-param>
        <param-name>passwordparam-name>
        <param-value>123456param-value>
    context-param>

第二步:在MyHttpServlet的doGet方法中新增以下代码

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
     
    System.out.println("doGet method invoke ...");

    // 获取全部初始化对象的名称和其对应内容
        Enumeration<String> initParameterNames = getServletContext().getInitParameterNames();
        //判断对象是否能获取
        while(initParameterNames.hasMoreElements()){
     
            //获取当前对象的名称
            String initParameterName = initParameterNames.nextElement();
            //根据当前对象的名称,获取对应的内容
            String initParameterValue = getServletContext().getInitParameter(initParameterName);
            System.out.println(initParameterName+":"+initParameterValue);
        }
}

第三步:重启Tomcat服务器,在浏览器中访问(http://localhost:8080/myJavaWebDemo_war_exploded/MyHttpServlet)
JavaWeb重点笔记_第23张图片

2.6.2 获取web项目的资源

第一步:在项目的 web 文件夹中右键创建 a.txt 文件
JavaWeb重点笔记_第24张图片
第二步:在MyHttpServlet的doGet方法中新增以下代码

       protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        System.out.println("doget 方法");

        // 获取全部初始化名称和其对应的内容
        Enumeration<String> initParameterNames = getServletContext().getInitParameterNames();
        //判断是否获取对象
        while(initParameterNames.hasMoreElements()){
     
            //获取当前对象的名称
            String initParameterName = initParameterNames.nextElement();
            //根据当前对象的名称,获取对应的内容
            String initParameterValue = getServletContext().getInitParameter(initParameterName);
            System.out.println(initParameterName+":"+initParameterValue);
        }

		//++++++++++++++++++++++++++++++以下是新增代码++++++++++++++++++++++++++
        // 获取web工程中的资源的绝对路径
        String realPath = getServletContext().getRealPath("a.txt");
        System.out.println(realPath);

        // 获取web工程中的资源的输入流对象
        InputStream resourceAsStream = getServletContext().getResourceAsStream("a.txt");
        System.out.println(resourceAsStream);
    }

第三步:重启Tomcat服务器,在浏览器中访问
JavaWeb重点笔记_第25张图片

2.6.3 在Servlet间共享数据域对象

第一步:创建 LoginServlet类并配置请求映射
LoginServlet:

package com.caochenlei.servlet.demo;

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

public class LoginServlet extends HttpServlet {
     
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
     
        doGet(request, response);
    }

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

    }
}

XML:

    <servlet>
        <servlet-name>LoginServletservlet-name>
        <servlet-class>com.caochenlei.servlet.demo.LoginServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>LoginServletservlet-name>
        <url-pattern>/LoginServleturl-pattern>
    servlet-mapping>

第二步:在 LoginServlet的 doGet 中实现登录次数的修改,默认为1

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
     
    // 获取当前登录次数
    Integer count = (Integer) getServletContext().getAttribute("count");
    // 如果当前登录为null,则设置默认值为1
    if (count == null) {
     
        getServletContext().setAttribute("count", 1);
    } else {
     
        getServletContext().setAttribute("count", count + 1);
    }
    System.out.println("当前登录次数是"+count);
}

第三步:在 MyHttpServlet 的 doGet 中新增以下查看代码,用于查看当前登录次数

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
     
    System.out.println("doGet method invoke ...");

    // 获取全部初始化名称和其对应的内容
    Enumeration<String> initParameterNames = getServletContext().getInitParameterNames();
    while (initParameterNames.hasMoreElements()) {
     
        String initParameterName = initParameterNames.nextElement();
        String initParameterValue = getServletContext().getInitParameter(initParameterName);
        System.out.println(initParameterName + ":" + initParameterValue);
    }

    // 获取web工程中的资源的绝对路径
    String realPath = getServletContext().getRealPath("a.txt");
    System.out.println(realPath);

    // 获取web工程中的资源的输入流对象
    InputStream resourceAsStream = getServletContext().getResourceAsStream("a.txt");
    System.out.println(resourceAsStream);
    
//+++++++++++++++++++++++++++++++++以下是新增代码+++++++++++++++++++++++++++++++
    // 查看当前网站登录次数,这个数据是保存在ServletContext中的
    Integer count = (Integer) getServletContext().getAttribute("count");
    // 判断是否登录过,如果没有登录过,提示未登录,如果已经登录过,显示登录次数
    if (count == null) {
     
            resp.getWriter().write("没有登录,登录次数为:" + count);
    } else {
     
            resp.getWriter().write("登录次数为:" + count);
    }
}

第四步:重启Tomcat服务器
访问LoginServlet(/LoginServlet):
JavaWeb重点笔记_第26张图片
访问MyHttpServlet(/http):
JavaWeb重点笔记_第27张图片

2.6.4 Servlet解决web乱码问题

如上例中,修改MyHttpServlet添加文本类型与编码格式在这里插入图片描述

JavaWeb重点笔记_第28张图片

2.7 ServletConfig

通过ServletConfig对象可以获取servlet在配置的时候一些信息。
第一步:创建类(MyServletConfig)

public class MyServletConfig extends HttpServlet {
     

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        super.doPost(req, resp);
    }
}

第二步:在web.xml中配置映射关系

    <servlet>
        <servlet-name>MyServletConfigservlet-name>
        <servlet-class>com.servlet.demo.MyServletConfigservlet-class>
        
        <init-param>
            <param-name>driveparam-name>
            <param-value>com.mysql.jdbc.Driverparam-value>
        init-param>
        <init-param>
            <param-name>urlparam-name>
            <param-value>jdbc:mysql://localhost:3306/mysqlparam-value>
        init-param>
        <init-param>
            <param-name>usernameparam-name>
            <param-value>rootparam-value>
        init-param>
        <init-param>
            <param-name>passwordparam-name>
            <param-value>rootparam-value>
        init-param>

        
        <load-on-startup>2load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>MyServletConfigservlet-name>
        <url-pattern>/MyServletConfigurl-pattern>
    servlet-mapping>

第三步:在MyServletConfig的doGet方法中新增以下代码

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        //获取全部初始化名称和其对应的内容
        Enumeration<String> initParameterNames = getServletConfig().getInitParameterNames();
        //判断是否获取对象
        while (initParameterNames.hasMoreElements()) {
     
            获取当前对象的名称
            String initParameterName = initParameterNames.nextElement();
            //根据当前对象的名称,获取对应的内容
            String initParameterValue = getServletConfig().getInitParameter(initParameterName);
            System.out.println(initParameterName + ":" + initParameterValue);
        }
    }

第四步:重启Tomcat服务器,在浏览器中访问http://localhost:8080/java_war_exploded/MyServletConfig
JavaWeb重点笔记_第29张图片

2.8 HttpServletRequest

HttpServletRequest这个对象封装了客户端提交过来的一切数据。

第一步:修改 index.jsp

<form action="RequestServlet" method="get">
    账户:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
         <input type="submit" value="注册">
form>

第二步:创建类(RequestServlet)

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        // 获取客户端传递过来的头部信息
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
     
            String headerName = headerNames.nextElement();
            String headerValue = req.getHeader(headerName);
            System.out.println(headerName + ":" + headerValue);
        }
        System.out.println("============================================================");

        // 获取客户端传递过来的参数信息
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
     
            String parameterName = parameterNames.nextElement();
            String parameterValue = req.getParameter(parameterName);
            // 如果值有多个请使用:request.getParameterValues(parameterName)
            System.out.println(parameterName + ":" + parameterValue);
        }
        System.out.println("=================================================");

        // 获取客户端传递过来的参数信息(以Map集合的形式)
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> names = parameterMap.keySet();
        for (String name : names) {
     
            String[] value = parameterMap.get(name);
            System.out.println(name + ":" + Arrays.toString(value));
        }
        System.out.println("========================================================");

        // 获取一些其它地址、查询等信息
        StringBuffer requestURL = req.getRequestURL();      //获取请求的URL
        String requestURI = req.getRequestURI();            //获取请求的URI
        String servletPath = req.getServletPath();          //获取
        String queryString = req.getQueryString();


        System.out.println("requestURL:" + requestURL);
        System.out.println("requestURI:" + requestURI);
        System.out.println("servletPath:" + servletPath);
        System.out.println("queryString:" + queryString);

    }

第三步:在web.xml中新增映射信息

 <servlet>
        <servlet-name>RequestServletservlet-name>
        <servlet-class>com.servlet.demo.RequestServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>RequestServletservlet-name>
        <url-pattern>/RequestServleturl-pattern>
    servlet-mapping>

第四步:重启Tomcat服务器,在浏览器中访问
JavaWeb重点笔记_第30张图片
控制台输出内容:
JavaWeb重点笔记_第31张图片

解决request请求数据中文乱码问题

  • GET方式
// 先用原来的编码解码再用UTF—8重新编码。
String newUsername = new String(username.getBytes("ISO-8859-1"), "UTF-8");
  • POST方式
// 这行设置一定要写在getParameter之前。
request.setCharacterEncoding("UTF-8");

2.9 HttpServletResponse

HttpServletResponse这个对象负责返回数据给客户端。

第一步:创建类(ResponseServlet)

public class ResponseServlet extends HttpServlet {
     
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        /**
         * 注意:以下两种方式一次只能使用一种,我们就用字符流方式了,另一种自己演示
         */
        // 以字符流的方式写数据
        resp.getWriter().write("

hello response 111 ...

哈哈哈"
); // 以字节流的方式写数据 // response.getOutputStream().write("hello response 222 ...".getBytes()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }

第二步:在web.xml文件中新增以下映射信息

    <servlet>
        <servlet-name>ResponseServletservlet-name>
        <servlet-class>com.servlet.demo.ResponseServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>ResponseServletservlet-name>
        <url-pattern>/ResponseServleturl-pattern>
    servlet-mapping>

第三步:重启Tomcat服务器,在浏览器中访问
http://localhost:8080/java_war_exploded/ResponseServlet
JavaWeb重点笔记_第32张图片

解决response响应数据中文乱码问题

  • 字符流输出:response.getWriter()
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("你好,世界!");
  • 字节流输出:response.getOutputStream()
response.setContentType("text/html;charset=UTF-8");
response.getOutputStream().write("你好,世界!".getBytes("UTF-8"));

2.10 重定向和请求转发

1、重定向是客服端两次请求;请求转发是客服端只有一次请求;重定向会生成两个不同的request对象,请求转发只有一个。
2、重定向是客服端的跳转,请求转发是服务器的跳转。
3、重定向的URL拦会发生变化,而请求转发不会发生变化。
4、重定向:response.sendRedirect(“/URL地址”)方法
请求转发:request.getRequestDispatcher(“/URL地址”)方法
5、重定向是前一个请求结束了,一个新的请求发出来了;请求转发是同一个人请求,由最后一个转发页面向浏览器相应页面。
6、请求转发的转发者与接收者之间共享相同的request对象,response对象,他们属于同一个访问请求和响应过程;重定向的调用者与被调用者使用各自的request对象和response对象,他们属于多个独立的访问请求和响应过程

2.10.1 重定向(完全的跳转)

response.sendRedirect("/URL地址")

处理流程:

  • 客户端发送请求,Servlet做出业务逻辑处理。
  • Servlet调用response.sendReadirect()方法,把要访问的目标资源作为response响应头信息发给客户端浏览器。
  • 客户端浏览器重新访问服务器资源xxx.jsp,服务器再次对客户端浏览器做出响应。
    JavaWeb重点笔记_第33张图片

2.10.2 请求转发(内部转发)

request.getRequestDispatcher("/URL地址").forward(request, response)

处理流程:

  • 客户端发送请求,Servlet做出业务逻辑处理。
  • Servlet调用forword()方法,服务器Servlet把目标资源返回给客户端浏览器。
    JavaWeb重点笔记_第34张图片

2.11 Cookie

Cookie其实是一份小数据,它是服务器给客户端并且存储在客户端上的一份小数据。

第一步:创建类(CookieServlet)

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        // 获取Cookie ============================================================
        Cookie[] cookies = req.getCookies();
        if (cookies.length == 1) {
     
            System.out.println("没有其它Cookie存在,只有JSESSIONID这个Cookie存在!");

            // 创建Cookie ============================================================
            // 创建Cookie对象
            Cookie cookie = new Cookie("username", "zhangsan");
            // 添加Cookie描述
            cookie.setComment("用户账号Cookie");
            // 正值:表示在这个数字过后,cookie将会失效。
            // 负值:关闭浏览器,那么cookie就失效,默认值是 -1。
            // 注意:Cookie是没有删除方法的,想让要Cookie失效或清除,就只要让当前值为0就可以了。
            cookie.setMaxAge(60 * 60 * 24 * 7);
            // 重新为当前的这个Cookie赋值
            cookie.setValue("lisi");
            // 只有访问域名 localhost 才会带上该Cookie
            cookie.setDomain("localhost");
            // 只有访问请求 /java_war_exploded/CookieServlet 才会带上该Cookie
            //cookie.setPath("/java_war_exploded/CookieServlet");
            // 创建Cookie ============================================================

            // 使用响应对象给浏览器响应的时候带上该Cookie
            resp.addCookie(cookie);
        } else {
     
            for (Cookie cookie : cookies) {
     
                if ("username".equals(cookie.getName())) {
     
                    System.out.println(cookie.getName() + "====" + cookie.getValue());
                }
            }
        }
        // 获取Cookie ============================================================
    }

第二步:在web.xml中新增映射信息

    <servlet>
        <servlet-name>CookieServletservlet-name>
        <servlet-class>com.servlet.demo.CookieServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>CookieServletservlet-name>
        <url-pattern>/CookieServleturl-pattern>
    servlet-mapping>

第三步:重启Tomcat服务器在浏览器中访问
http://localhost:8080/java_war_exploded/CookieServlet
JavaWeb重点笔记_第35张图片

2.12 Session

Session是数据存放在服务器端上。而Cookie是服务器返回一小份数据给客户端,并且存放在客户端上。
常见用法:

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

// 获取SessionID
String id = session.getId();

//存值
session.setAttribute(name, value);

//取值
session.getAttribute(name);

//删值
session.removeAttribute(name);

生命周期:

  • 创建:如果有在servlet里面调用了 request.getSession()
  • 销毁:关闭服务器或者session会话时间过期。默认有效期: 30分钟。

三、Listener

Listener是监听器,监听Servlet某一个事件的发生或者状态的改变,它的内部其实就是接口回调。

3.1 监听三个作用域创建和销毁

3.1.1 ServletContextListener

监听对象:

ServletContextListener用于监听ServletContext对象作用域创建和销毁,利用它可以完成自己想要的初始化工作。

生命周期:

servletcontext创建:

  • 1、启动服务器的时候

servletContext销毁:

  • 1、关闭服务器
  • 2、从服务器移除项目

如何创建:
创建ServletContextListener类:

public class MyContextListener implements ServletContextListener {
     
    @Override
    public void contextInitialized(ServletContextEvent sce) {
     
        System.out.println("MyContextListener 创建.......");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
     
        System.out.println("MyContextListener 销毁.......");
    }
}

如何配置XML:

    <listener>
        <listener-class>com.servlet.demo.MyContextListenerlistener-class>
    listener>

3.1.2 ServletRequestListener

监听对象:

ServletRequestListener用于监听ServletRequest对象作用域创建和销毁,利用它可以判断当前受否存在请求。

生命周期:

request创建:
1、访问服务器上的任意资源都会有请求出现。
访问 html :会
访问 jsp :会
访问 servlet :会

request销毁:
1、服务器已经对这次请求作出了响应。

如何创建:
创建MyRequestListener 类:

public class MyRequestListener implements ServletRequestListener {
     
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
     
        System.out.println("requestDestroyed。。。。。。销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
     
        System.out.println("requestInitialized。。。。。。初始化");
    }
}

如何配置XML:

    <listener>
        <listener-class>com.servlet.demo.MyRequestListenerlistener-class>
    listener>

3.1.3 HttpSessionListener

监听对象:

HttpSessionListener用于监听HttpSession对象作用域创建和销毁,利用它可以统计在线人数。

生命周期:

session的创建:
1、只要调用getSession()方法。
html :不会
jsp :会
servlet :会

session的销毁:
1、会话超时30分钟。
2、非正常关闭服务器。
3、正常关闭服务器(序列化)

如何创建:
创建MySessionListener 类:

public class MySessionListener implements HttpSessionListener {
     
    @Override
    public void sessionCreated(HttpSessionEvent se) {
     
        System.out.println("sessionCreated。。。。。。创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
     
        System.out.println("sessionCreated。。。。。。销毁");
    }
}

如何配置XML:

    <listener>
        <listener-class>com.servlet.demo.MySessionListener listener-class>
    listener>

3.2 监听三个作用域属性状态变更

3.2.1 ServletContextAttributeListener

主要作用:

监听ServletContext存值状态变更。

如何创建:

package com.caochenlei.servlet.demo;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyContextAttributeListener implements ServletContextAttributeListener {
     
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
     
        System.out.println("attributeAdded ...");
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
     
        System.out.println("attributeRemoved ...");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
     
        System.out.println("attributeReplaced ...");
    }
}

3.2.2 ServletRequestAttributeListener

主要作用:

监听ServletRequest存值状态变更。

如何创建:

package com.caochenlei.servlet.demo;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

public class MyRequestAttributeListener implements ServletRequestAttributeListener {
     
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
     
        System.out.println("attributeAdded ...");
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
     
        System.out.println("attributeRemoved ...");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
     
        System.out.println("attributeReplaced ...");
    }
}

3.2.3 HttpSessionAttributeListener

主要作用:

监听HttpSession存值状态变更。

如何创建:

package com.caochenlei.servlet.demo;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MySessionAttributeListener implements HttpSessionAttributeListener {
     
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
     
        System.out.println("attributeAdded ...");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
     
        System.out.println("attributeRemoved ...");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
     
        System.out.println("attributeReplaced ...");
    }
}

3.3 监听HttpSession存值状态变更

3.3.1 HttpSessionBindingListener

主要作用:

监听对象与session绑定和解除绑定的动作。

如何创建:

package com.caochenlei.servlet.demo;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class MySessionBindingListener implements HttpSessionBindingListener {
     
    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
     
        System.out.println("valueBound ...");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
     
        System.out.println("valueUnbound ...");
    }
}

如何配置:

这一类监听器不用注册。

3.3.2 HttpSessionActivationListener

主要作用:

用于监听现在session的值是钝化(序列化)还是活化(反序列化)的动作。

钝化(序列化)  :把内存中的数据存储到硬盘上。
活化(反序列化):把硬盘中的数据读取到内存中。

如何钝化

1. 在tomcat的 conf/context.xml 里面配置
		对所有的运行在这个服务器的项目生效。

2. 在tomcat的 conf/Catalina/localhost/context.xml 里面配置
		对localhost生效。

3. 在自己的web工程项目中的 META-INF/context.xml 里面配置
		只对当前的工程生效。

具体配置信息如下:
	maxIdleSwap 	: 1分钟不用就钝化。
	directory 		: 钝化后的那个文件存放的目录位置。

	<Context>
		<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
			<Store className="org.apache.catalina.session.FileStore" directory="D:/Passivate"/>
		</Manager>
	</Context>

如何创建:

package com.caochenlei.servlet.demo;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;

public class MySessionActivationListener implements HttpSessionActivationListener {
     
    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
     
        System.out.println("sessionWillPassivate ...");
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
     
        System.out.println("sessionDidActivate ...");
    }
}

如何配置:

这一类监听器不用注册。

四、Filter

4.1 Filter概述

Filter是过滤器,就是对客户端发出来的请求进行过滤。浏览器发出请求,然后服务器派servlet处理。在中间就可以过滤,其实过滤器起到的是拦截的作用。使用过滤器可以对一些敏感词汇进行过滤、统一设置编码、实现自动登录等功能。

4.2、Filter生命周期

  • 创建:在服务器启动的时候就创建。
  • 销毁:在服务器停止的时候就销毁。

4.3、Filter语法

如何定义:

public class MyFilter implements Filter {
     
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
     
        System.out.println("MyFilter init ...初始化");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
     
        System.out.println("MyFilter foFilter ...执行过滤");

        // 放行,让请求到达下一个目标。
        filterChain.doFilter(req, resp);
    }

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

如何配置:

    <filter>
        <filter-name>MyFilterfilter-name>
        <filter-class>com.caochenlei.servlet.demo.MyFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>MyFilterfilter-name>
        <url-pattern>/*url-pattern>
        <dispatcher>REQUESTdispatcher>
    filter-mapping>

注意:init方法的参数 FilterConfig , 可以用于获取Filter在注册的名字以及初始化参数,其实这里的设计的初衷与ServletConfig是一样的。

4.4 Filter匹配规则

  • 全路径匹配:/a
  • 前半段匹配:/a/b/c/*
  • 扩展名匹配:*.action

4.5 Filter拦截类型

注意:针对 dispatcher 设置的选项。

  • REQUEST : 只要是请求过来都拦截,默认就是REQUEST。
  • FORWARD : 只要是转发过来都拦截。
  • ERROR : 页面出错发生跳转。
  • INCLUDE : 包含页面的时候就拦截。

4.6 Filter统一编码

public class EncodingFilter implements Filter {
     
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
     

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
     
        // 1.强转
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        // 2.放行
        filterChain.doFilter(new MyRequest(request), response);
    }

    @Override
    public void destroy() {
     

    }


    // 增强了所有的获取参数的方法request.getParameter("name");
    // 增强了所有的获取参数的方法request.getParameterValues("name");
    // 增强了所有的获取参数的方法request.getParameterMap();
	
	//内部类MyRequest 
    public class MyRequest extends HttpServletRequestWrapper {
     

        private HttpServletRequest request;
        private boolean flag = true;

        /**
         * 初始化构造函数
         * @param request(请求对象)
         */
        public MyRequest(HttpServletRequest request) {
     
            super(request);
            this.request = request;
        }

        @Override
        public String getParameter(String name) {
     
            if (name == null || name.trim().length() == 0) {
     
                return null;
            }
            String[] values = getParameterValues(name);
            if (values == null || values.length == 0) {
     
                return null;
            }
            return values[0];
        }

        @Override
        public String[] getParameterValues(String name) {
     
            if (name == null || name.trim().length() == 0) {
     
                return null;
            }
            Map<String, String[]> map = getParameterMap();
            if (map == null || map.size() == 0) {
     
                return null;
            }
            return map.get(name);
        }

        @Override
        public Map<String, String[]> getParameterMap() {
     
            String method = request.getMethod();
            if ("post".equalsIgnoreCase(method)) {
     
                try {
     
                    request.setCharacterEncoding("utf-8");
                    return request.getParameterMap();
                } catch (UnsupportedEncodingException e) {
     
                    e.printStackTrace();
                }
            } else if ("get".equalsIgnoreCase(method)) {
     
                Map<String, String[]> map = request.getParameterMap();
                if (flag) {
     
                    for (String key : map.keySet()) {
     
                        String[] arr = map.get(key);
                        for (int i = 0; i < arr.length; i++) {
     
                            try {
     
                                arr[i] = new String(arr[i].getBytes("utf-8"), "utf-8");
                            } catch (UnsupportedEncodingException e) {
     
                                e.printStackTrace();
                            }
                        }
                    }
                    flag = false;
                }
                return map;
            }
            return super.getParameterMap();
        }
    }
}

五、Servlet3.0

5.1 注解开发

5.1.1 servlet注解

如何创建:

@WebServlet(
        name = "AnnotationServlet",//代表servlet名称
        value = {
     "/AnnotationServlet"},//代表servlet映射地址,可以写多个,value与urlPatterns一样,二者不能同时出现
        loadOnStartup = 2,//代表servlet初始化顺序
        initParams = {
     @WebInitParam(name = "user",value = "zhangsan")},//代表servlet初始化参数,可以写多个
        asyncSupported = false//代表servlet是否支持异步,默认为false
)
public class AnnotationServlet extends HttpServlet {
     
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        System.out.println("doGet ...AnnotationServlet 注释");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        System.out.println("doPost ...");
    }
}

使用servlet注解后,不在需要配置xml文件

属性列表:

属性名 类型 描述
name String 指定 Servlet 的 name 属性,如果没有显式指定,则该 Servlet 的取值即为类的全限定名
value String[] 该属性等价于 urlPatterns 属性,两个属性不能同时使用
urlPatterns String[] 指定一组 Servlet 的 URL 匹配模式
loadOnStartup int 指定 Servlet 的加载顺序
initParams WebInitParam[] 指定一组 Servlet 初始化参数
asyncSupported boolean 声明 Servlet 是否支持异步操作模式
description String 该 Servlet 的描述信息
displayName String 该 Servlet 的显示名,通常配合工具使用

如何测试:

打开浏览器输入:http://localhost:8080/java_war_exploded/AnnotationServlet

检测控制台输出:
JavaWeb重点笔记_第36张图片

5.1.2 Filter注解

如何创建:

@WebFilter(
        filterName = "AnnotationFilter",//代表filter名称
        value = {
     "/*"},//代表filter映射路径,可以写多个,value与urlPatterns一样,二者不能同时出现
        dispatcherTypes = {
     DispatcherType.REQUEST},//代表filter拦截类型
        initParams = {
     @WebInitParam(name = "user", value = "zhansan")},//代表filter初始化参数,可以写多个
        asyncSupported = false,//代表filter是否支持异步,默认为false
        servletNames = {
     "AnnotationServlet"}//代表filter指定拦截哪几个servlet
)
public class AnnotationFilter implements Filter {
     
    @Override
    public void init(FilterConfig config) throws ServletException {
     
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws ServletException, IOException {
     
        System.out.println("doFilter ...AnnotationFilter");
        chain.doFilter(req, resp);
    }

    @Override
    public void destroy() {
     
    }
}

属性列表:

属性名 类型 描述
filterName String 指定过滤器的 name 属性
value String[] 该属性等价于 urlPatterns 属性,但是两者不应该同时使用
urlPatterns String[] 指定一组过滤器的 URL 匹配模式
servletNames String[] 指定过滤器将应用于哪些 Servlet
dispatcherTypes DispatcherType 指定过滤器的转发模式具体取值包括: ASYNC、ERROR、FORWARD、INCLUDE、REQUEST
initParams WebInitParam[] 指定一组过滤器初始化参数
asyncSupported boolean 声明过滤器是否支持异步操作模式
description String 该过滤器的描述信息
displayName String 该过滤器的显示名,通常配合工具使用

如何测试:

打开浏览器输入:
http://localhost:8080/java_war_exploded/AnnotationFilter
检测控制台输出:
JavaWeb重点笔记_第37张图片

5.1.3 listener注解

如何创建:

@WebListener()
public class AnnotationListener implements ServletContextListener {
     
    @Override
    public void contextInitialized(ServletContextEvent sce) {
     
        System.out.println("contextInitialized ...AnnotationListener");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
     

        System.out.println("contextDestroyed ...AnnotationListener");
    }
}

如何测试:
JavaWeb重点笔记_第38张图片

5.1.4 注解与XML两种配置同时存在的说明

对于servlet来说:

  • 若两种配置方式的url-pattern值相同,则应用无法启动。
  • 若两种配置方式的url-pattern值相同,那么相当该servlet具有两个映射url-pattern。

对于filter来说:

  • 无论两种配置方式的url-pattern值是否相同,其都是作为独立的filter出现的。

对于listener来说:

  • 如果两种配置方式都进行了同一个listener注册,那么也只能算一个listener。

5.1.5 如何禁用注解组件

metadata-complete=“false”:表示web.xml配置和注解配置同时生效,默认是false。

metadata-complete=“true”:表示web.xml配置有效,而注解配置则被忽略。


<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" metadata-complete="false">
web-app>

5.2 文件上传

前台页面:

  <form action="uploadServlet" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="myfile" /> <br />
    上传文件:<input type="submit" value="上传" />
  form>

前端的核心代码:

  • enctype=“multipart/form-data” //form中的数据用二进制数据传输,可以传文字,图片,。。
  • type=“file” //type 设成“file”就是文件选择按钮,自动产生一个 文本框+选择按钮
  • name=“myfile” //用于后台获取文件对象

后端上传模块:

@WebServlet(name = "UploadFileServlet", urlPatterns = "/uploadFileServlet")
@MultipartConfig
public class UploadFileServlet extends HttpServlet {
     
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        //解决request乱码问题
        req.setCharacterEncoding("UTF-8");
        //解决response乱码问题
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType( "text/html;charset=UTF-8");
        
        //(通过请求的input标签tpye为file类型的name属性)获取请求文件对象
        Part part = req.getPart("myfile");  
        String fileName=part.getSubmittedFileName();    // 获取文件名称
        String lastName=fileName.substring(fileName.lastIndexOf('.'),fileName.length());  // 获取文件后缀
        part.write("D:/xxx"+lastName);     //将文件对象写入指定的全路径

        resp.getWriter().println("文件上传成功!");
    }
}

后台核心代码:
JavaWeb重点笔记_第39张图片
运行报错:

此错误是因为没有加注解@MultipartConfig

JavaWeb重点笔记_第40张图片

@MultipartConfig注解:

属性名 类型 是否可选 描述
fileSizeThreshold int 当数据量大于该值时,内容将被写入文件
location String 存放生成的文件地址
maxFileSize long 允许上传的文件最大值。默认值为-1,表示没有限制
maxRequestSize long 针对该multipart/form-data请求的最大数量,默认值为-1,表示没有限制

如何测试:
http://localhost:8080/java_war_exploded/
JavaWeb重点笔记_第41张图片

你可能感兴趣的:(JAVA笔记,java)