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 就不会被执行。



浙公网安备 33010602011771号