入门JavaWeb之 MVC、Filter 过滤器和监听器

MVC 三层架构:

Model(模型)、View(视图)、Controller(控制器)

**控制器:Controller,**可以理解成 Servlet

1.接收用户的请求(req:请求参数、Session 信息等)

2.响应给客户端内容(业务层)

3.重定向或转发(视图跳转)

**Model:**控制业务操作,保存数据、修改数据、删除数据、查询数据

1.业务处理:业务逻辑(Service)

2.数据持久层:CRUD(Dao)

**View:视图层,**可以理解成 JSP

1.展示数据

2.提供链接发起 Servlet 请求(a、form、img 等)

Servlet 专注于处理请求和控制视图跳转

JSP 专注于显示数据

举个例子:

用户登录

接收用户的登录请求

处理用户的请求,获取用户登录的参数,username、password

交给业务层处理登录业务(判断用户名和密码是否正确:事务)

Dao 层查询用户名和密码是否正确

查数据库

都对上了再逐一返回上述步骤

Filter 过滤器:用来过滤网站的数据

pom.xml 导入连接数据库的包

XML 复制代码
    <!-- 连接数据库 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.33</version>
    </dependency>

实现 Filter 接口

重写对应的方法

初始化:web服务器启动,就开始初始化,随时等待过滤对象出现

filterChain.doFilter(servletRequest,servletResponse); 固定写法,让过滤器执行

销毁:web服务器关闭时,过滤销毁

代码如下:

java 复制代码
package com.demo.filter;

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

//implements接口
public class CharacterEncodingFilter implements Filter{

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

    /*
    1.过滤中的所有代码,在过滤特定请求时都会执行
    2.必须要让过滤器继续执行 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");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    //销毁:web服务器关闭时,过滤销毁
    @Override
    public void destroy() {
        //Filter.super.destroy();
        System.out.println("销毁");
    }
}

再写个能在页面上显示中文的类

不加 setCharacterEncoding 是乱码,数据多就不适用了,所以用过滤器一步到位

java 复制代码
package com.demo.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 Demo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("过滤");
    }

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

web.xml 注册和映射:

Filter 与 Servlet 配置的写法相似

<filter-mapping> 下的 <url-pattern> 路径一般会加个其他自己设置的路径

比如 /admin/*、/servlet/*,表示这个路径下的全部都会走过滤器

XML 复制代码
    <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>com.demo.servlet.Demo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>filter</filter-name>
        <filter-class>com.demo.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

运行后,地址栏添加后缀,页面显示中文

如果需要实现权限拦截(比如用户注销),可以在监听器里设置 Session 值不匹配进入错误页面

但需要强转成 HttpServletRequest、HttpServletResponse

监听器:

例:统计在线人数

java 复制代码
package com.demo.listener;

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

//统计网站在线人数,实则统计Session
public class OnlineCountListener implements HttpSessionListener {

    //创建Session监听
    @Override
    public void sessionCreated(HttpSessionEvent se) {

        ServletContext servletContext = se.getSession().getServletContext();

        Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");

        if(onlineCount==null){
            onlineCount = new Integer(1);
        }else{
            int i = onlineCount.intValue();
            onlineCount = new Integer(i+1);
        }

        servletContext.setAttribute("OnlineCount",onlineCount);

    }

    //销毁Session监听
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {

        ServletContext servletContext = se.getSession().getServletContext();

        System.out.println(se.getSession().getId());

        Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");

        if(onlineCount==null){
            onlineCount = new Integer(0);
        }else{
            int i = onlineCount.intValue();
            onlineCount = new Integer(i-1);
        }

        servletContext.setAttribute("OnlineCount",onlineCount);
    }
}

index.jsp 添加一行

html 复制代码
<h1>当前有<span><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在线</h1>

web.xml 注册监听器

XML 复制代码
    <!-- 注册监听器 -->
    <listener>
        <listener-class>com.demo.listener.OnlineCountListener</listener-class>
    </listener>

手动销毁监听器:se.getSession().invalidate();

自动销毁监听器:时间自己设置

XML 复制代码
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

监听器在 GUI 图形用户界面中经常使用,小窗体,可以监听用户操作,关闭、缩小、放大等

相关推荐
IronMurphy1 分钟前
SSM拷打第二讲!!!
java·spring·mybatis
小江的记录本9 分钟前
【JVM虚拟机】类加载机制:类加载全流程:加载→验证→准备→解析→初始化(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·算法·安全·spring·面试
千纸鹤の脉搏17 分钟前
多线程的初步了解---进程与线程
java·开发语言·学习·线程
许彰午35 分钟前
状态模式实战——Row对象的状态机
java·ui·状态模式
搬石头的马农1 小时前
Claude Code SpringBoot开发:从0到1搭建企业级项目的6个核心Skill
java·人工智能·spring boot·后端·ai编程
西安邮电大学1 小时前
Redis为什么快?
java·redis·后端·其他·面试
折哥的程序人生 · 物流技术专研1 小时前
《Java 100 天进阶之路》第39篇:Java泛型方法的定义和使用
java·开发语言·后端·面试·求职招聘
土狗TuGou1 小时前
SQL内功笔记 · 第6篇:窗口函数的使用ROW_NUMBER等
java·数据库·后端·sql·mysql
Chase_______1 小时前
【Java基础核心知识点全解·09】Java 内存布局与垃圾回收详解:栈、堆、栈帧、GC Roots 与对象回收
java·开发语言
武子康1 小时前
Java-11 深入浅出 MyBatis 一级缓存详解:从原理到失效场景 Executor
java·后端