JavaWeb-Servlet学习笔记

这是菜狗学习Servlet的一些笔记


什么是Servlet?

Servlet就是一种技术,用于开发动态Web
Servlet是一种接口
Servlet就是一种实现了Servlet接口的Java程序

如果你想开发一个动态Web,你需要:1. 编写一个类,实现Servlet接口;2. 将这个类部署到Web服务器中


Hello Servlet

构建Maven父子项目

首先构建一个普通的Maven项目,删除src目录,称其为主工程
在主工程里新建模块,称其为子工程
例如构建主工程为Root_Servlet,子工程为Servlet_01,这二者的pom.xml中会加入父子关系的描述,如下:
父项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>org.example</groupId>
   <artifactId>Root_Servlet</artifactId>
   <packaging>pom</packaging>
   <version>1.0-SNAPSHOT</version>
   <modules>
       <module>Servlet_01</module>
   </modules>

   <properties>
       <maven.compiler.source>15</maven.compiler.source>
       <maven.compiler.target>15</maven.compiler.target>
   </properties>

</project>

子项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
       <artifactId>Root_Servlet</artifactId>
       <groupId>org.example</groupId>
       <version>1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>

   <artifactId>Servlet_01</artifactId>

   <properties>
       <maven.compiler.source>15</maven.compiler.source>
       <maven.compiler.target>15</maven.compiler.target>
   </properties>

</project>

另外,子项目可以使用父项目的Maven依赖,而父项目则不能使用子项目的

然后同样的,我们把子项目中web.xml的内容换成与Tomcat的webapps里web.xml一致的,并删除冗余部分
在这里插入图片描述

写一段代码

接着在java目录下新建一个java文件(或者先新建一个软件包再新建一个java文件),然后令你的类继承HttpServlet接口,注意:这里继承时需要先通过Maven导入包(如果本地仓库没有,可以去Maven仓库找),而通过Maven导包时配置的是子项目的pom.xml文件,如果不想重复导入,可以把相关的依赖剪切到父项目的pom.xml下

这些完成后需要重写方法,现阶段需要掌握的只有doGetdoPost方法,因此只重写这两个
在这里插入图片描述
因为这两个方法通常没什么不同,所以我们习惯在一个方法里调用另一个,然后所有代码就写在另一个方法里面
简单写两句:

//响应流
PrintWriter writer = resp.getWriter();
//输出
writer.println("Hello Servlet!");

编写Servlet映射

  1. 注册Servlet

    在web.xml中添加<servlet>标签,在此标签下添加<servlet-name>标签(一般自动添加),在这个标签下写Servlet的名字,比如hello
    然后在<servlet>下添加<servlet-class>,在这个标签下写Java类的包名+简单类名

  2. 编写Servlet的请求路径

    在web.xml中添加<servlet-mapping>标签,其下自动生成两个标签,<servlet-name>和<url-pattern>,即名字(与<servlet>的<servlet-name>相同)和请求路径

完成后如图
在这里插入图片描述

Tomcat,启动!

添加Tomcat配置,启动程序
出现报错500
我麻了
重新来
经过亿系列试错,找到了解决方法:
tomcat10 带来的报错:jakarta.servlet.ServletException: 类com.kang.servlet.HelloServlet不是Servlet
原来是Tomcat10的锅(包名改了)
修改之后pom.xml文件依赖长这样在这里插入图片描述
导入的包长这样在这里插入图片描述
(是的,为了解决这个错误我重新下了IDEA专业版,社区版完全就是****)
启动成功‍✿ヽ(°▽°)ノ✿‍
在这里插入图片描述
在这里插入图片描述


自定义404界面

原理:指定固有映射路径的优先级最高

同样的,新建一个error类

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * <p>
 * 创建日期:2021-04-16 21:43
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class Error404 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print("<h1>404 NOT FOUND</h1>");
    }

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

接着去web.xml注册Servlet和编写访问路径,要想达到404的效果,需要用到通配符*

<servlet>
        <servlet-name>error</servlet-name>
        <servlet-class>Error404</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>error</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

式中/*表示任意路径(包括空),但其优先级低于已编写的其他访问路径
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通配符*还可用于指定后缀

例如改一下Error404的servlet-mapping:

<servlet>
        <servlet-name>error</servlet-name>
        <servlet-class>Erroe404</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>error</servlet-name>
        <url-pattern>*.error</url-pattern>
    </servlet-mapping>

在这里插入图片描述


通过全局唯一的ServletContext获取不同Servlet的信息

ServletContext:
 WEB容器在启动时,它会为每个Web应用程序都创建一个对应d的ServletContext,它代表当前Web应用。并且它被所有客户端共享
 ServletContext对象可以通过ServletConfig.getServletContext()方法获得对ServletContext对象的引用,也可以通过this.getServletContext()方法获得其对象的引用。
 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。公共聊天室就会用到它。
 当web应用关闭、Tomcat关闭或者Web应用reload的时候,ServletContext对象会被销毁
(引用自博客Servlet——ServletContext 对象

例子:在一个Servlet中写入username信息,让另一个Servlet读取

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * <p>
 * 创建日期:2021-04-17 09:13
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class Hello extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        PrintWriter writer = resp.getWriter();
        writer.print("Hello");
        //得到ServletContext
        ServletContext servletContext = this.getServletContext();
        //添加指定的属性,并为其赋指定的值,如果已有该属性,则修改之
        servletContext.setAttribute("Username", "Hoppinging");
    }

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

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * <p>
 * 创建日期:2021-04-18 08:31
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String username = (String) servletContext.getAttribute("Username");
        //设置编码格式
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().print("Username:" + username);
    }

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

记得配置web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0"
         metadata-complete="true">
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>Hello</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>getUsername</servlet-name>
        <servlet-class>GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getUsername</servlet-name>
        <url-pattern>/gu</url-pattern>
    </servlet-mapping>
</web-app>

来看效果:
第一次请求:在这里插入图片描述很明显,获取到了个寂寞
这是因为还没写入属性
这就hello一下在这里插入图片描述
重新获取在这里插入图片描述


转发与重定向

简单的理解:转发url不会发生变化,请求只能转发到相同Web应用的项目资源,不可以跨应用或者服务器;重定向url会发生变化,可以跨Web应用和服务器来重新定位资源,但是不可以直接重定向到WEB-INF中的资源
具体的理解:在这里插入图片描述
图片来自博客转发与重定向

转发

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * <p>
 * 创建日期:2021-04-18 10:08
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class ServletDispatcher extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //转发的请求路径设为/hello
        servletContext.getRequestDispatcher("/hello").forward(req, resp);
    }

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

配置xml

	<servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>ServletDispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/dispatcher</url-pattern>
    </servlet-mapping>

效果在这里插入图片描述

重定向

简单的一句话

resp.sendRedirect("/XXXX/XXX");

显然XXXX是服务器部署路径,比如完整请求路径为http://localhost:8081/Servlet_01_war/random,则XXXX就是Servlet_01_war,XXX就是random

完整代码Demo如下

import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * <p>
 * 创建日期:2021-04-26 16:49
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class Redirect extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.sendRedirect("/Servlet_01_war/random");
    }

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

注册web.xml

	<servlet>
        <servlet-name>random</servlet-name>
        <servlet-class>Demo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>random</servlet-name>
        <url-pattern>/random</url-pattern>
    </servlet-mapping>

通过ServletContext获取资源文件

一般的,先在resources目录下新建一个资源文件,比如info.properties
在这里插入图片描述
写一些键值对
在这里插入图片描述
注意,放在resources目录下的资源文件默认会导出,但在java下的不会,这时需要在pom中添加配置

	<resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>

接着写获取资源的类

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * <p>
 * 创建日期:2021-04-18 13:54
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class GetProperties extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取ServletContext
        ServletContext servletContext = this.getServletContext();
        //通过target中的info.properties的路径获取资源文件并转换成输入流,注意,用到的路径是以/WEB-INF开头的
        InputStream resourceStream = servletContext.getResourceAsStream("/WEB-INF/classes/info.properties");
        //new一个资源对象
        Properties properties = new Properties();
        //加载输入流到对象
        properties.load(resourceStream);
        //输出
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().print("用户名:" + properties.getProperty("username") + "密码:" + properties.getProperty("password"));
    }

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

在这里插入图片描述

添加web.xml

	<servlet>
        <servlet-name>getProperties</servlet-name>
        <servlet-class>GetProperties</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getProperties</servlet-name>
        <url-pattern>/prop</url-pattern>
    </servlet-mapping>

效果:
在这里插入图片描述


通过HttpServletResponse下载文件

步骤

  1. 确定文件的下载路径(一般为绝对路径);
  2. 确定文件名;
  3. 编写文件头(让浏览器支持下载);
  4. 获取输入流;
  5. 创建缓冲区;
  6. 创建输出流;
  7. 将输入流写入缓冲区,用输出流输出到客户端。

如下所示

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * <p>
 * 创建日期:2021-04-17 09:13
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class Download extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 确定文件的下载路径;
        String path = this.getServletContext().getRealPath("/WEB-INF/classes/233.jpg");
        // 2. 确定文件名;
        String filename = path.substring(path.lastIndexOf("/") + 1);
        // 3. 编写文件头(让浏览器支持下载)
        resp.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename,"UTF-8"));
        // 4. 获取文件输入流
        FileInputStream inputStream = new FileInputStream(filename);
        // 5. 创建缓冲区
        int len;
        byte[] buffer = new byte[1024];
        // 6. 创建响应输出流
        ServletOutputStream outputStream = resp.getOutputStream();
        // 7. 将输入流写入缓冲区,用输出流输出到客户端
        while((len = inputStream.read(buffer)) != -1){
            outputStream.write(buffer, 0, len);
        }
        inputStream.close();
        outputStream.close();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

不用要忘了配置web.xml

	<servlet>
        <servlet-name>download</servlet-name>
        <servlet-class>Download</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>download</servlet-name>
        <url-pattern>/download</url-pattern>
    </servlet-mapping>

然后启动Tomcat
在这里插入图片描述
按回车
在这里插入图片描述
在这里插入图片描述

没错下载是成功了,但是还需要解决的问题是:

  1. 没有下载的提示框
  2. 不支持迅雷下载

通过HttpServletRequest获取前客户端的信息和请求转发

1. 获取前端传参

比如一个这样的前端:

<%--
  Created by IntelliJ IDEA.
  User: hoppi
  Date: 2021/4/27
  Time: 16:07
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Login</title>
</head>
<body>
<h1>Login</h1>
<div style="text-align: center">
    <form action="${pageContext.request.contextPath}/login" method="post">
        username:<input type="text" name="username"><br>
        password:<input type="password" name="password"><br>
        hobbies:
        <input type="checkbox" name="hobbies" value="Game"> Games
        <input type="checkbox" name="hobbies" value="Sleep"> Sleep
        <input type="checkbox" name="hobbies" value="Eating"> Eating
        <input type="checkbox" name="hobbies" value="Bilibili"> Bilibili
        <br>
        <input type="submit">
    </form>
</div>

</body>
</html>

显然,它传递了6个参数,而要读取这些参数,需要用到HttpServletRequest的方法比如getParametergetParameterValues

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.Arrays;

/**
 * <p>
 * 创建日期:2021-04-27 16:09
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobbies");
        System.out.println("============================");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("============================");
    }

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

2. 请求转发的衔接

通常的,比如上面那个login前端,当login完成后,想要跳转到另一个界面告诉客户login成功了,这时候就需要用到请求转发
在doGet方法中加上一句req.getRequestDispatcher("/success.jsp").forward(req, resp);,其中"success.jsp"是另一个界面,就像这样:

<%--
  Created by IntelliJ IDEA.
  User: hoppi
  Date: 2021/4/27
  Time: 16:22
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Success</title>
</head>
<body>
<h1>
    Login success!
</h1>
</body>
</html>

配置web.xml之后就可以运行了:
在这里插入图片描述
在这里插入图片描述


Cookies

什么是Cookies

 Cookies,可以简单理解为服务器给你发的凭证,当你重新登陆一个网站时,如果你持有该网站的Cookies,就会被网站识别(大概,如果这个网站有这种功能的话),Cookies具有持续时间,当你的某网站的Cookies过期之后,再次登陆需要重新验证。
 大多数需要登录的网站在用户验证成功之后都会设置一个 cookie,只要这个 cookie 存在这个用户,他就可以就可以自由浏览这个网站的任意页面

简单的Cookies应用Demo

import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

/**
 * <p>
 * 创建日期:2021-04-29 17:14
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class cookiesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //防止中文乱码
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        Cookie[] cookies = req.getCookies();
        boolean cookie_exist = false;
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals("LoginTime")){
                writer.write("Your last login time was:");
                long loginTime = Long.parseLong(cookie.getValue());
                Date date = new Date(loginTime);
                writer.write(date.toLocaleString());
                cookie_exist = true;
                break;
            }
        }
        if (!cookie_exist){
            writer.write("Welcome to here for the first time!");
        }
        //向客户端发送Cookies
        Cookie cookie = new Cookie("LoginTime", System.currentTimeMillis() + "");
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

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

	<servlet>
        <servlet-name>cookies</servlet-name>
        <servlet-class>cookiesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cookies</servlet-name>
        <url-pattern>/cookies</url-pattern>
    </servlet-mapping>

效果:
在这里插入图片描述


Session

Session,意为会话

来一个简单的SessionDemo

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

/**
 * <p>
 * 创建日期:2021-05-01 19:44
 *
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class SessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //防止乱码
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到session
        HttpSession session = req.getSession();
        //为session置入属性
        session.setAttribute("name", "Hoppinging");
        //获取session的Id
        String sessionId = session.getId();
        //显示
        resp.getWriter().write("session的Id为:" + sessionId);
        //事实上,这里还有一步默认进行,建立一个cookie,JSESSIONID=sessionId
    }

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

    <servlet>
        <servlet-name>setSession</servlet-name>
        <servlet-class>SessionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>setSession</servlet-name>
        <url-pattern>/session</url-pattern>
    </servlet-mapping>

略微修改一下,可以显示session中包含的属性。在显示的时候加一句resp.getWriter().write((String) session.getAttribute("name"));,显示名为"name"的Attribute值,当然最好加一个换行符,否则name会和sessionId连在一起‍_(:з」∠)_
在这里插入图片描述

观察得,两次请求的SessionId是不同的,这是因为session是存在于服务器中的,重启服务器会清除session

Session属性的移除与Session的注销

移除指定名称的属性:removeAttribute(String var1)
注销session:invalidate()

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

/**
 * <p>
 * 创建日期:2021-05-02 17:05
 * Session属性的移除与Session的注销
 * @author Hoppinging
 * @version 1.1
 * @since 1.0
 */
public class SessionInvalidateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //防止乱码
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到session
        HttpSession session = req.getSession();
        //移除session的指定属性
        session.removeAttribute("name");
        //获取session的Id
        String sessionId = session.getId();
        //显示
        resp.getWriter().write("session的Id为:" + sessionId);
        resp.getWriter().write("<br>" + session.getAttribute("name") + "<br>");
        //注销session
        session.invalidate();
        //第二次显示
        resp.getWriter().write("session的Id为:" + sessionId);
        resp.getWriter().write("<br>" + session.getAttribute("name") + "<br>");
    }

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

ps:这里<br>起到换行的作用,因为servlet中\n无法起到换行的作用

web.xml:

    <servlet>
        <servlet-name>invalidateSession</servlet-name>
        <servlet-class>SessionInvalidateServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>invalidateSession</servlet-name>
        <url-pattern>/invalidate</url-pattern>
    </servlet-mapping>

在这里插入图片描述
点击刷新
在这里插入图片描述

session的id在刷新前后不一致,这说明session确实是被清掉了
另外,第一次显示时name为null,第二次显示直接就没有了,这是因为第一次getAttribute找到的name值为null,toString之后是字符串null,第二次是因为invalidate完session就失效了,虽然会生成一个新的session,但getAttribute指向的对象还是原来那个session,故会导致NullPointerException,所以就输出了个寂寞,然后根据某大佬的研究在这里插入图片描述
(U•ェ•*U狗头‍保命)


Session的自动注销

当然,上面的那种是手动注销
自动注销是在web.xml中编辑<session-config>的<session-timeout>属性,单位是分钟

    <!--设置session的默认失效时间-->
    <session-config>
        <!--十五分钟过期-->
        <session-timeout>15</session-timeout>
    </session-config>

大概就这些了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值