Java Web07:MVC、过滤器和监听器

MVC三层架构

Servlet和JSP都可以写Java代码,但为了易于维护和使用:Servlet专注于处理请求,以及控制视图跳转;JSP专注于显示数据

Model:

  • 业务处理层(Service)
  • 数据持久层(Dao)

View:

  • 展示数据
  • 提供链接,发起Servlet请求

Controller:

  • 接受用户请求
  • 交给业务层处理
  • 控制视图跳转

image

过滤器

实现Filter接口,重写三个方法

实现过程和Servlet类似

案例一:统一设置编码

请求

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

public class test extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {

        res.getWriter().println("你好,世界");
    }

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

过滤器

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

public class CharacterFilter implements Filter {


    /**
     * Web服务器启动时就会初始化
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化");
    }

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

        /**
         * 在过滤器中统一处理乱码
         */
        response.setContentType("text/html;charset=utf-8");

        System.out.println("过滤器执行前");

        /**
         * 过滤器链
         * 1、过滤器中所有代码,在过滤特定请求时都会执行
         * 2、必须要执行chain对象的doFilter()方法,才能让过滤后的请求继续往下执行
         */
        chain.doFilter(request, response);

        System.out.println("过滤器执行后");
    }

    /**
     * Web服务器停止时被销毁
     */
    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
    }
}

配置web.xml

<!--对指定目录下的请求进行过滤-->
<!--只有/filter/test会被过滤,而/test不会被过滤-->
<filter>
    <filter-name>CharacterFilter</filter-name>
    <filter-class>CharacterFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterFilter</filter-name>
    <url-pattern>/filter/*</url-pattern>
</filter-mapping>

<servlet>
        <servlet-name>filterTest</servlet-name>
        <servlet-class>test</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>filterTest</servlet-name>
    <url-pattern>/filter/test</url-pattern>
</servlet-mapping>

案例二:登录才能访问

登录页面

<%--设置浏览器页面编码格式--%>
<%@page contentType="text/html; charset=utf-8"%>
<html>

<body>

<form action="./login" method="post">
    <p>用户名:<input type="text" name="username"></p>
    <p>密码:<input type="password" name="password"></p>
    <p><input type="submit"></p>
</form>

</body>
</html>

登录请求

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 Login extends HttpServlet {

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

        String username = req.getParameter("username");

        if (username.equals("admin")){

            /**
             * 如果用户名是admin,则记录Session的ID,跳转到登录成功的页面
             */
            req.getSession().setAttribute("USER_SESSION", req.getSession().getId());
            resp.sendRedirect("./login_success.jsp");
        }
        else {

            /**
             * 登陆失败跳转到500
             */
            resp.sendRedirect("./error/error500.jsp");
        }
    }

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

登录成功页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陆成功</title>
</head>
<body>

<h1>登陆成功!</h1>

<%--登陆成功以后,可以注销,注销以后必须要再次登录才能访问--%>
<p><a href="./logout">注销</a></p>

</body>
</html>

注销请求

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 Logout extends HttpServlet {

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

        Object user_session = req.getSession().getAttribute("USER_SESSION");

        /**
         * 注销后返回登录页面
         */
        if (user_session != null){
            req.getSession().removeAttribute("USER_SESSION");
        }

        resp.sendRedirect("./login.jsp");
    }

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

权限过滤

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

public class AuthorityFilter implements Filter {

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

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

        /**
         * 转换Filter接口中方法参数的类型
         */
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        /**
         * 权限验证
         * 如果注销以后,再访问login_success.jsp页面会报错
         */
        if (req.getSession().getAttribute("USER_SESSION") == null){
            resp.sendRedirect("./error/error404.jsp");
        }

        chain.doFilter(request, response);
    }

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

配置Web.xml

<servlet>
    <servlet-name>Login</servlet-name>
    <servlet-class>Login</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Login</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Logout</servlet-name>
    <servlet-class>Logout</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Logout</servlet-name>
    <url-pattern>/logout</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>AuthorityFilter</filter-name>
    <filter-class>AuthorityFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthorityFilter</filter-name>
    <url-pattern>/login_success.jsp</url-pattern>
</filter-mapping>

监听器

实现监听器接口,不同对象接口不一样,如监听Session的接口是HttpSessionListener

重写两个方法

监听器

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

public class Listener implements HttpSessionListener {

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

        /**
         * 获取OnlineCount属性
         */
        ServletContext servletContext = se.getSession().getServletContext();

        /**
         * 创建时输出当前Session的ID
         */
        System.out.println(se.getSession().getId());

        Integer num = (Integer) servletContext.getAttribute("OnlineNum");

        if (num == null){
            num = new Integer(1);
        }
        else {

            int count = num.intValue();
            num = new Integer(count + 1);
        }

        servletContext.setAttribute("OnlineNum", num);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {

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

        /**
         * 销毁时输出当前Session的ID
         */
        System.out.println(se.getSession().getId());

        Integer num = (Integer) servletContext.getAttribute("OnlineNum");

        if (num == null){
            num = new Integer(0);
        }
        else {

            int count = num.intValue();
            num = new Integer(count - 1);
        }

        servletContext.setAttribute("OnlineNum", num);
    }
}

JSP页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>当前在线人数为 <span style="color: red"><%=application.getAttribute("OnlineNum")%></span></h1>

</body>
</html>

配置web.xml

<!--注册监听器-->
<listener>
    <listener-class>Listener</listener-class>
</listener>

<!--销毁监听器-->
<session-config>
    <session-timeout>1</session-timeout>
</session-config>
posted @   振袖秋枫问红叶  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示