JavaWeb入门到实战[狂神]-2

Cookie和Seesion

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;从打开浏览器到关闭浏览器的过程
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话

一个网站,怎么证明你来过?
客户端
服务端
1.服务端给客户端一个 信件,客户端下次访问服务端带上信件就可以了; cookie
2.服务器登记你来过了,下次你来的时候我来匹配你;seesion

保存会话的两种技术
cookie
客户端技术(响应,请求)。
session
服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在Session中!。

package com.cjj.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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.Date;

public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务器告诉你,你来的时间,把这个时间封闭成为一个信件,下次你带来,我就知道你来了
        //解决中文乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=UTF-8");
        PrintWriter out = resp.getWriter();
        //服务器从客户端获取cookie
        Cookie[] cookies = req.getCookies();//返回数组,可能有多个cookie
        if (cookies != null) {
            out.write("你上次登录的时间是:");
            for(int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if(cookie.getName().equals("lastLoginTime")) {
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.println(date.toString());
                }
            }

        }else{
            resp.setContentType("text/html; charset=UTF-8");
            out.println("这是你第一次访问,没有cookie");
        }
        //服务维客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
        //cookie设置有效期为1天,否则浏览器关闭后就失效
        cookie.setMaxAge(60 * 60 * 24);

        resp.addCookie(cookie);
    }
}


一个网站cookie是否存在上限!
一个Cookie只能保存一个信息(键值对)
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie,
Cookie大小有限制4kb;
300个cookie浏览器上限

删除Cookie;
不设置有效期,关闭浏览器,自动失效;
设置有效期时间为0;

Seesion

-服务器会给每一个用户(浏览器)创建一个seesion对象(注意这个对象是存在于服务器端)
-一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
-用户登录之后,整个网站它都可以访问---》保存用户的信息,保存购物车的信息
第一步,可以创建一个person类

package pojo;

public class Person {
   private String name;
    private int age;
    public Person() {

    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

访问第一个页面,服务器配置好session对象的键及值,浏览器第一次访问后获得session对象,访问第二页面时,第二个页面可以通过取session对象的值,来判断是否允许访问,以及做个性化

package com.cjj.servlet;

import pojo.Person;

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

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //得到session对象
        HttpSession session = req.getSession();
        //设置session属性
        session.setAttribute("name", new Person("张四", 20));//可以提前设置一个person对象,第一个页面获得session对象后,后面的页面都是可以直接共享访问这个session对象,后面页面通过获得session的name属性的值,来判断是否允许进入及个性化
        //获取session的ID
        String id = session.getId();
        //判断session是否新创建
        if (session.isNew()) {
            resp.getWriter().write("新创建的session ID为:" + id);
        }else{
            resp.getWriter().write("session已经存在,ID为:" + id);
            }

        //session创建的时候做了什么事情
        //cookie cookie = new Cookie("JSESSIONID", id);
        //resp.addCookie(cookie);
        //session id本质还是cookie,只是名字叫做JSESSIONID,还是存在于浏览器端,不同是在session.setAttribute("name", "张三");可以在服务端提前设置好键值-session对象,第一个页面获得session对象后,后面的页面都是可以直接共享访问这个session对象。(这个session对象是存在于服务器端的)

    }
}

配置第二个页面

package com.cjj.servlet;

import pojo.Person;

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

public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //得到session对象
        HttpSession session = req.getSession();
        //设置session属性
        Person person = (Person)session.getAttribute("name");
        System.out.println(person.toString());
    }
}

如果让session失效,一种是手动配置程序,就像关闭浏览器,一种是在web.xml配置

package com.cjj.servlet;

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

public class SessionDemo03 extends HttpServlet {
    @Override


    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        //手动注销session
        session.invalidate();//注销session就和关闭浏览器一样,session中的数据也会被清空,session对象相当存在浏览器中,清空后就读不到了
        

    }
}
<!--设置session失效时间-->
    <session-config>
      <!-- 设置session失效时间为15分钟 -->
      <session-timeout>15</session-timeout>
    </session-config>

session和cookie的区别
--cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
--session把用户的数据 写到用户独占的session中,服务端保存(保存重要的信息,减少服务器资源的浪费)
--session对象由服务端创建的

重点重点:理解cookie和session

cookie是每个浏览器请求都会带上cookie信息
session虽然是服务器的对象,但是在客户端第一次请求时(没有sessionid),服务器会创建一个session对象,同时这个session会有唯一的sessionid,同时服务器会把cookie-键值为session:sessionid传给浏览器,所以浏览器每次请求都会带上这个cooike,凭借这个cookie来找到这个session对象
所以当前面注销session对象时,那个sessionid也就没用了。

使用场景
-保存一个登录用户的信息
--购物车信息
--在整个网站中经常使用的数据,会保存在session中

JSP

java server pages:java服务器端页面,也和servlet一样,用于动态页面
最大的特点:
--写Jsp就像写html
--区别:html只给用户提供静态数据/jsp页面可以加入java代码,为用户提供动态数据

jsp原理

--代码层面没有任何不一样,和html代码
--在服务器内部,在tomcat中,有一个work目录(在idea使用tomcat会生成work目录),每次启动tomcat,都会重新生成一次work目录

这个路径才能看到jsp对应生成的java文件:
C:\Users\60237\AppData\Local\JetBrains\IntelliJIdea2024.3\tomcat\90b89559-7ed3-437a-8d26-dd422d50d3b4\work\Catalina\localhost\ROOT\org\apache\jsp

有一个class文件,和java文件

页面转变成了java程序,所以浏览器向服务器发送请求,不管访问什么资源,其实都是在访问servlet
jsp最终也会被转化为java类,jsp本质就是一个servlet,继承了servlet类

Jsp文件中有
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
//servlet的方法

//最后将html输出
 out.write("<html>\r\n");
      out.write("<body>\r\n");
      out.write("<h2>Hello World!</h2>\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");

Tomcat补充
maven会自动把文件打包成war,然后编辑时选对应的war包,如果不改变路径的话,默认是放到tomcat的webapp下的root目录

jsp对应的java文件补充
Tomcat 中 JSP 文件对应的 Java 文件存放在 Tomcat 安装目录下的work文件夹中。具体路径的一般格式为:{TOMCAT_HOME}/work/Catalina/localhost/{项目名}/org/apache/jsp。例如,Tomcat 安装在D:\Develop\Tomcat 8.5,项目名为Demo,则对应的路径为D:\Develop\Tomcat 8.5\work\Catalina\localhost\Demo\org\apache\jsp。
如果是在 IDE 中使用 Tomcat,例如 Eclipse,其路径可能类似.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work/Catalina/localhost/(项目名)/org/apache/jsp。

jsp基础语法和指令

先导入maven包

 <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api jstl表达式-->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/taglibs/standard,standard标签库 -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
  </dependencies>

任何语言都有自己的语法,jsp作为java技术的一种应用,它拥有一些自己扩充的语法(了解即可)

语法

JSP表达式

<head>
    <title>Title</title>
</head>
<body>
<%--jsp表达式
作用:用来将程序的输出,输出到客户端--%>
<%=new java.util.Date()%>
</body>
</html>

JSP脚本片段

<%--jsp脚本片段
作用:用来将程序的输出,输出到客户端--%>
<%
    int sum = 0;
    for(int i=1;i<=100;i++){
        sum += i;
    }
    out.print("<h1>sum"+sum+"</h1>");
%>

脚本片段的再实现

<%--在代码中嵌入html代码--%>
<%
    for(int i=1;i<=10;i++){
        %>
<h1>hello jsp </h1>
<%
    }
    %>

JSP声明

<%!
    static{
        System.out.println("static block");
    }
    private int globalVar = 0;
    public void printGlobalVar(){
        System.out.println("进入了方法瞄瞄");
    }
%>

JSP声明:会被编译到JSP生成的JAVA类中,其它的,会被生成到JSPService方法中
JSP的注释,不会在客户端显示 ,HTML会

指令

<%--
  Created by IntelliJ IDEA.
  User: 60237
  Date: 2025/4/27
  Time: 22:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error/500.jsp" %>
<html>
<!--报错就跳到自定义的404页面-->
<!--定制错误页面,上面的路径用webapp下的路径,page还有很多指令,例如导包等-->
<head>
    <title>Title</title>
</head>
<body>
<%
    int x=1/0;
%>
</body>
</html>

同时404页面也可以在web-xml中配置

    <error-page>
      <error-code>500</error-code>
      <location>/error/500.jsp</location>
    </error-page>
  </web-app>

其它指令

适合于有些是通用的样式
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>

9大内置对象

-pagecontext 存东西
-request 存东西
-response
-session 存东西
-application[serlvetcontext] 存东西
-config[serlvetconfig]
-out
-exception

<%--
  Created by IntelliJ IDEA.
  User: 60237
  Date: 2025/4/27
  Time: 22:55
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    pageContext.setAttribute("name1", "Tom");//保存的数据只在一个页面有效
    request.setAttribute("name2", "Jerry");//保存的数据只在一次请求有效,请求转发会携带这个数据
    session.setAttribute("name3", "Mike");//保存的数据在一次会话有效,关闭浏览器失效
    application.setAttribute("name4", "Lily");//保存的数据只在服务器有效,服务器重启失效
    %>
<%
    String name1 = (String) pageContext.getAttribute("name1");
    String name2 = (String) request.getAttribute("name2");
    String name3 = (String) session.getAttribute("name3");
    String name4 = (String) application.getAttribute("name4");

%>
<%--使用EL表达式获取属性值--%>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>

</body>
</html>

为了证明pagecontext,request,session,application的区别
建立多一个jsp页面

<html>
<head>
    <title>Title</title>
</head>
<body>

<%
    String name1 = (String) pageContext.getAttribute("name1");
    String name2 = (String) request.getAttribute("name2");
    String name3 = (String) session.getAttribute("name3");
    String name4 = (String) application.getAttribute("name4");

%>
<%--使用EL表达式获取属性值--%>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>

</body>
</html>

先访问上面的页面,再访问下面的页面,只会显示name3和name4的值

pageContext.setAttribute("name1", "Tom");//保存的数据只在一个页面有效
request.setAttribute("name2", "Jerry");//保存的数据只在一次请求有效,请求转发会携带这个数据
session.setAttribute("name3", "Mike");//保存的数据在一次会话有效,关闭浏览器失效
application.setAttribute("name4", "Lily");//保存的数据只在服务器有效,服务器重启失效

request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的

session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车

application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据

JSP标签,JSTL标签,EL表达式

el表达式分别都用于jsp标签和jstl标签中
EL表达式:${}
--获取数据
--执行运算
--获取web开始的常用对象

jsp标签
页面1

<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="Tom"/>
    <jsp:param name="age" value="25"/>
</jsp:forward>
</body>
</html>

页面2

<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>This is a JSP Tag Example</h1>
<%--取出参数--%>
<%= request.getParameter("name") %>
<%= request.getParameter("age") %>

</body>
</html>

JSTL表达式
jstl标签库的使用就是为弥补HTML标签的不足,它自定义许多标签,可以供我们使用,标签的功能和java代码一样
--核心标签
--格式化标签
--SQL标签
--XML标签

标签使用步骤
--引入对应的taglib
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
--使用其中的方法

<%--
  Created by IntelliJ IDEA.
  User: 60237
  Date: 2025/4/28
  Time: 23:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--引入自定义标签文件,core就是jstl标签的其中一个库,如果引入xml标签库,则标签前缀为x--%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h4>if测试</h4>
<hr>
<form action="coreif.jsp" method="get">
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="提交">
</form>

<%--判断用户名是否管理员,则登陆成功--%>
<c:if test="${param.username == 'admin'}">
    <h3>登陆成功!欢迎管理员${param.username}!</h3>
</c:if>
</body>
</html>

另一个案例

<%@ page import="java.util.ArrayList" %><%--
  Created by IntelliJ IDEA.
  User: 60237
  Date: 2025/4/28
  Time: 23:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--引入自定义标签文件,core就是jstl标签的其中一个库,如果引入xml标签库,则标签前缀为x--%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h4>if测试</h4>
<%

    ArrayList<String> list = new ArrayList<>();
    list.add("apple");
    list.add("banana");
    list.add("orange");
    list.add("pear");
    request.setAttribute("list",list);
%>

<c:forEach items="${list}" var="fruit">
    <c:out value="${fruit}"/>
</c:forEach>
</body>
</html>

JavaBean-jsp-和数据库联动

实体类
javaBean有特定的写法
--要有一个无参构造
--属性要私有化
--有对应的get/set方法
--一般和数据库的字段做映射 ORM
ORM:对象关系映射
表--类
字段--属性
行记录--对象

建立一个实体类,和数据库对应

package pojo2;
//实体类 我
public class People {
    private int id;
    private String name;
    private int age;
    private String address;

    public People() {
    }

    public People(int id, String name, int age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
};

jsp中javabean的用法

<%--
  Created by IntelliJ IDEA.
  User: 60237
  Date: 2025/5/3
  Time: 16:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<jsp:useBean id="people" class="pojo2.People" scope="page"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="Tom"/>
<jsp:setProperty name="people" property="age" value="25"/>
<jsp:setProperty name="people" property="address" value="China"/>
姓名:<jsp:getProperty name="people" property="name"/><br>
年龄:<jsp:getProperty name="people" property="age"/><br>
地址:<jsp:getProperty name="people" property="address"/><br>
</body>
</html>

MVC三层架构

什么是MVC:Model view controller 模型,视图,控制器 javabean实体类 \jsp \servlet
早些年-servlet和jsp是混在一起,随用户访问

现在MVC

Model
--业务处理:业务逻辑(service)
--数据持久层:CRUD(Dao)

view
--展示数据
--提供链接发起servlet请求(a,form,img。。。)

controller(servlet)(servlet翻译(尤指 Java 语言中在服务器上运行的)小型应用程序;小服务程序)
--接收用户的请求(req:请求参数,Session信息..)
--交给业务层处理对应的代码
--控制视图的跳转

MVC流程:登录--接收用户的登录请求--处理用户的请求(获取用户登录的参数,username,password)--交给业务层处理登录业务(判断用户名密码是否正常,事务)--DAO层查询用户名密码是否正确--数据库

Filter(其实就是加一层)

过滤器和servlet一样,只是继承不同的接口

filter的实现
1、导包
2、编写过滤器

package filter;

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

public class CharacterEncodingFilter implements Filter {
//初始化
    //web服务器启动时,就开始执行了,随时等待过滤对象出现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter init初始化了");
    }
//chain:链接

    /**
     *在过滤特定的请求时都会执行
     * filterChain.doFilter(servletRequest, servletResponse);一定要写
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
     servletRequest.setCharacterEncoding("utf-8");
     servletResponse.setCharacterEncoding("utf-8");
     servletResponse.setContentType("text/html;charset=utf-8");
     System.out.println("CharacterEncodingFilter 执行前");
     filterChain.doFilter(servletRequest, servletResponse);//让我们的请求继续往下执行,如果不写这句话,那么请求就不会继续往下执行
     System.out.println("CharacterEncodingFilter 执行后");
    }
//服务器关闭时,才会执行destroy方法
    @Override
    public void destroy() {
        System.out.println("CharacterEncodingFilter destroy销毁了");
    }
}

3、配置web.xml,指定访问路径,都会经过这个过滤器

 <servlet>
      <servlet-name>showservlet</servlet-name>
      <servlet-class>com.cjj.servlet.ShowServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>showservlet</servlet-name>
      <url-pattern>/servlet/show</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
      <servlet-name>showservlet</servlet-name>
      <url-pattern>/show</url-pattern>
    </servlet-mapping>
    <filter>
      <filter-name>Character</filter-name>
      <filter-class>filter.CharacterEncodingFilter</filter-class>
    </filter>
    <!--只要是servlet下的所有的请求,都会经过CharacterEncodingFilter过滤器-->
    <filter-mapping>
      <filter-name>Character</filter-name>
      <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

监听器

1、编写一个监听器,实现监听器的接口
下面的案例是创建监听session对象的接口

package lister;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//统计在线人数的类:统计session
public class OnlineCountLister implements HttpSessionListener {
//创建session监听,看你的一举一动
    //session创建时触发
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("onlineCount");
                if (onlineCount == null) {
                    onlineCount = new Integer(1);

                }else {
                    int oldCount = onlineCount.intValue();
                    onlineCount = new Integer(oldCount + 1);
                }
                ctx.setAttribute("onlineCount", onlineCount);


    }

    //session销毁时触发
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("onlineCount");
        if (onlineCount == null) {
            return;
        }
        int oldCount = onlineCount.intValue();
        if (oldCount > 0) {
            onlineCount = new Integer(oldCount - 1);
            ctx.setAttribute("onlineCount", onlineCount);
        }

    }
}

2、web注册监听器

<!--注册监听器-->
    <listener>
            <listener-class>lister.OnlineCountLister</listener-class>
    </listener>

3、JSP展示出现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>当前有<span><%=this.getServletConfig().getServletContext().getAttribute("onlineCount")%></span></h1>
</body>
</html>

过滤器和监听器的常见应用

1、监听器:GUI编程中经常使用(关闭窗口等)

2、用户登录之后进入主页,用户注销后不能进入主页
现在设置admin才能成功进入,其它账号跳转到500,但如果别人知道了跳转后的成功页面,那就大家都可以登陆了,所以要设置过滤器,进入成功页前要经过过滤器判断是否允许进入

3、通过过滤器指向不同等级用户的页面

实现步骤:
1、编写登录页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="LoginServlet" method="post">
    <input type="text"  name="username"><br>
    <input type="submit">
</form>
</body>
</html>

2、跳转到对应的servlet,然后实现定向转发到成功的页面

package com.cjj.servlet;

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 {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取前端请求的参数
        String username = req.getParameter("username");
        if (username.equals("admin")) {
            req.getSession().setAttribute("USER_SESSION", req.getSession().getId());
            resp.sendRedirect("/success.jsp");
        }else {
            resp.sendRedirect("/error.jsp");
    }
}
}

3、成功页面退出,跳转到对应的servlet页面,目的为了清除session对象及重定向到登陆页面

<%--
  Created by IntelliJ IDEA.
  User: 60237
  Date: 2025/5/4
  Time: 14:00
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>Success主页了哈哈</h1>

<p><a href="/Logout">注销</a></p>
</body>
</html>
package com.cjj.servlet;

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 LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object userSession = req.getSession().getAttribute("USER_SESSION");
        if (userSession != null) {
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/Login.jsp");
        }
    }
}

4、配置过滤器,在进入成功页面时,如果没有session对象,就转到400页面,有才能进入成功页面,防止别人直接通过链接进入成功页面

package filter;

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

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

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if (request.getSession().getAttribute("USER_SESSION") == null) {
            response.sendRedirect("/error.jsp");
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

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

5、配置web.xml文件

   <servlet>
      <servlet-name>Loginservlet</servlet-name>
      <servlet-class>com.cjj.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>Loginservlet</servlet-name>
      <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>
    <servlet>
      <servlet-name>Logoutservlet</servlet-name>
      <servlet-class>com.cjj.servlet.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>Logoutservlet</servlet-name>
      <url-pattern>/Logout</url-pattern>
    </servlet-mapping>
    <filter>
      <filter-name>sysFilter</filter-name>
      <filter-class>filter.SysFilter</filter-class>
    </filter>
    <!--只要是servlet下的所有的请求,都会经过CharacterEncodingFilter过滤器-->
    <filter-mapping>
      <filter-name>sysFilter</filter-name>
      <url-pattern>/success.jsp</url-pattern>
    </filter-mapping>
posted @ 2025-04-22 23:16  乘加法  阅读(27)  评论(0)    收藏  举报