Spring MVC 复盘录前言

前言

在还没有使用 Spring MVC 之前,我们 WEB 应用可能是这样操作的:

  • 先创建一个 maven web 项目:

  • 导入必要的依赖后,在 java 目录下新建两个 Servlet :

    package org.example;

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

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("自定义的重定向 Servlet 运行了");

    // 将这个重定向给另一个 Servlet
    resp.sendRedirect("/redirect");
    }
    }

    上面这个是重定向 Servlet ,下面那个是请求转发 Servlet:

    package org.example;

    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletContext;
    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 TestRedirectServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("自定义的请求转发 Servlet 运行了");

    // 获取请求转发器
    ServletContext servletContext = req.getServletContext();
    RequestDispatcher dispatcher = servletContext.getRequestDispatcher(servletContext.getContextPath() + "/jsp/login.jsp");

    // 转发请求
    dispatcher.forward(req, resp);
    }
    }

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

  • 打开 web.xml ,配置这个 Servlet:


    Archetype Created Web Application


    forwardServlet
    org.example.TestForwardServlet


    forwardServlet
    /test


    redirectServlet
    org.example.TestRedirectServlet


    redirectServlet
    /redirect

    启动一个WEB项目的时候,WEB容器会去读取它的配置文件 web.xml。

  • 再在 WEB-INF/jsp (无则创建) 目录下创建一个简单的 login.jsp 页面:

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


    登录


    登陆页面

    上述步骤完成后,即可运行,在地址栏输入 http://localhost:8080/test 进入后,运行结果:

    后台打印结果:
    自定义的重定向 Servlet 运行了
    自定义的请求转发 Servlet 运行了

  • 添加两个监听器,一个是请求监听器:

    package org.example.listener;

    import javax.servlet.ServletRequestEvent;
    import javax.servlet.ServletRequestListener;
    import javax.servlet.http.HttpServletRequest;

    public class WebRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {

    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
    HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
    System.out.println("监听到一条请求: " + request.getRequestURI());
    }
    }

    另一个是Servlet 上下文监听器:

    package org.example.listener;

    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;

    // Servlet 上下文监听器
    public class WebServletListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
    System.out.println("Servlet 上下文已初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    System.out.println("Servlet 上下文已销毁了");
    }
    }

  • 再添加两个过滤器:

    package org.example.filter;

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

    public class MyFilter2 implements Filter {

    private String param;

    // 初始化方法在 WEB 应用启动时会被调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    // 可以获取到在 web.xml 中配置的初始化参数,注意名字的一致性
    param = filterConfig.getInitParameter("test");
    System.out.println("配置在 web.xml/filter/init-param 下的初始化参数" + param);
    }

    // 在访问 filter-mapping 中指定的 url 时才会被调用
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("filter-1 过滤到了一条请求: " + ((HttpServletRequest)servletRequest).getRequestURI());

    // 如果初始化参数 test 允许离开,就放行
    if (param.equals("exit")){
    filterChain.doFilter(servletRequest, servletResponse);
    }
    }

    @Override
    public void destroy() {

    }
    }

    第二个过滤器用来测试是否放行的问题:

    package org.example.filter;

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

    public class MyFilter2 implements Filter {

    private String param;

    // 初始化方法在 WEB 应用启动时会被调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    // 可以获取到在 web.xml 中配置的初始化参数,注意名字的一致性
    param = filterConfig.getInitParameter("test");
    System.out.println("配置在 web.xml/filter/init-param 下的初始化参数" + param);
    }

    // 在访问 filter-mapping 中指定的 url 时才会被调用
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("filter-2 过滤到了一条请求: " + ((HttpServletRequest)servletRequest).getRequestURI());

    // 如果初始化参数 test 允许离开,就放行
    if (param.equals("exit")){
    filterChain.doFilter(servletRequest, servletResponse);
    }
    }

    @Override
    public void destroy() {

    }
    }

    在请求和响应对象在Servlet处理之前和之后,可以通过过滤器对这两个对象进行处理。

  • 最后在 web.xml webapp 标签内中配置这两个监听器和过滤器:


    org.example.listener.WebRequestListener


    org.example.listener.WebServletListener


    filter-1
    org.example.filter.MyFilter

    test
    exit1



    filter-1
    forwardServlet


    filter-2
    org.example.filter.MyFilter2

    test
    exit



    filter-2
    forwardServlet

    从运行结果中可以发现,listener 和 filter 在 WEB 容器启动时就被加载了,重点是过滤器的问题,多个过滤器会组合成一条过滤链,一旦哪里出现中断,对应的 Servlet 就不会被执行。

posted @ 2022-03-30 17:31  lizhpn  阅读(34)  评论(0)    收藏  举报