学习Spring MVC,我们只需要掌握以下3个功能:
- 1.连接的功能︰将用户(浏览器)和 Java 程序连接起来,也就是访问一个地址能够调用到我们的Spring程序。
- 2.获取参数的功能︰用户访问的时候会带一些参数,在程序中要想办法获取到参数。
- 3.输出数据的功能︰执行了业务逻辑之后,要把程序执行的结果返回给用户。
1、回顾MVC
1.1、什么是MVC
-
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
-
是将业务逻辑、数据、显示分离的方法来组织代码。
-
MVC主要作用是降低了视图与业务逻辑间的双向偶合。
-
MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。0
Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。
也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
最典型的MVC就是JSP + servlet + javabean的模式。
1.2、Model1时代
-
在web早期的开发中,通常采用的都是Model1。
-
Model1中,主要分为两层,视图层和模型层。
Model1优点:架构简单,比较适合小型项目开发;
Model1缺点:JSP职责不单一,职责过重,不便于维护;
1.3、Model2时代
Model2把一个项目分成三部分,包括视图、控制、模型。
-
用户发请求
-
Servlet接收请求数据,并调用对应的业务逻辑方法
-
业务处理完毕,返回更新后的数据给servlet
-
servlet转向到JSP,由JSP来渲染页面
-
响应给前端更新后的页面
职责分析:
Controller:控制器
-
取得表单数据
-
调用业务逻辑
-
转向指定的页面
Model:模型
-
业务逻辑
-
保存数据的状态
View:视图
-
显示页面
比较:
Model2这样不仅提高的代码的复用率与项目的扩展性,且大大降低了项目的维护成本。
Model 1模式的实现比较简单,适用于快速开发小规模项目,Model1中JSP页面身兼View和Controller两种角色,将控制逻辑和表现逻辑混杂在一起,从而导致代码的重用性非常低,增加了应用的扩展性和维护的难度。
Model2消除了Model1的缺点。
1.4、回顾Servlet
- 新建一个Maven工程当做父工程!pom依赖!
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies>
-
建立一个Moudle:springmvc-01-servlet , 添加Web app的支持!
- 导入servlet 和 jsp 的 jar 依赖
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency>
- 编写一个Servlet类,用来处理用户的请求
package com.zhao.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //实现Servlet接口 public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //取得参数 String method = req.getParameter("method"); if (method.equals("add")){ req.getSession().setAttribute("msg","执行了add方法"); } if (method.equals("delete")){ req.getSession().setAttribute("msg","执行了delete方法"); } //业务逻辑 //视图跳转 req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
- 编写Hello.jsp,在WEB-INF目录下新建一个jsp的文件夹,新建hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
- 在web.xml中注册Servlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.blue.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>hello</url-pattern> </servlet-mapping> </web-app>
- from
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/hello" method="post"> <input type="text" name="method"> <input type="submit"> </form> </body> </html>
- 配置Tomcat,并启动测试
-
localhost:8080/user?method=add
-
localhost:8080/user?method=delete
-
1.2、MVC框架要做哪些事情
- 将url映射到java类或java类的方法
- 封装用户提交的数据 .
- 处理请求–调用相关的业务处理–封装响应数据
- 将响应的数据进行渲染 . jsp / html 等表示层数据
1.3、文档
二、什么是SpringMVC
2.1 SpringMVC框架的基本说明
- SpringMVC是基于Spring的,是Spring中的一个模块,专门用来做web开发使用的。
- SpringMVC 也叫 Spring web mvc。是 Spring 框架的一部分,是在Spring3.0 后发布的。基于 MVC 架构,功能分工明确、解耦合。
- SpringMVC也是一个容器,使用IoC核心技术,管理界面层中的控制器对象。
- SpringMVC的底层就是servlet,以servlet为核心,接收请求、处理请求,显示处理结果给用户。
- 在此之前这个功能是由Servlet来实现的,现在使用SpringMVC来代替Servlet行驶控制器的角色和功能。
其核心Servlet是:DispatcherServlet
2.2 SpringMVC 框架的优点
优点:
- 1. 基于 MVC 架构,功能分工明确。解耦合。
- 2.容易理解,上手快;使用简单。就可以开发一个注解的 SpringMVC 项目,SpringMVC 也是轻量级的,jar 很小。不依赖的特定的接口和类。
- 3.作为 Spring 框架一部分,能够使用 Spring 的 IoC 和 Aop。方便整合Strtus,MyBatis,Hiberate, JPA 等其他框架。
- 4.SpringMVC 强化注解的使用,在控制器,Service,Dao 都可以使用注解。方便灵活。
- 使用@Controller 创建处理器对象,@Service 创建业务对象,@Autowired 或者@Resource 在控制器类中注入 Service, Service 类中注入Dao。
2.3 SpringMVC实现步骤
servlet 的实现方式: jsp发起-----servlet-----jsp显示结果
步骤:
- 1)创建web应用
- 2)加入web依赖 Spring-webmvc(springmvc框架依赖) ,servlet依赖
- 3)声明springmvc核心对象DispatcherServlet
- 1.DispatcherServlet是一个servlet对象
- 2.DispatcherServlet叫做前端控制器(front controller)
- 3.DispatcherServlet作用:在servlet的init()方法中,创建springmvc中的容器对象 作为servlet,接收请求
- 4)创建一个jsp,发起请求
- 5)创建一个普通类,作为控制器使用(代替之前的servlet)
- 1.在注解上面加入@Controller注解
- 2.在类中定义方法,方法上面加入@RequestMapping注解方式处理请求,相当于servlet得doGet,doPost
- 6)创建作为结果得jsp页面
- 7)创建springmvc得配置文件(spring的配置文件一样)
- 1.声明组件扫描器,指定@Controller注解所在的包名
- 2.声明视图解析器对象
三.第一个注解的SpringMVC程序
3.1 IDEA中使用maven创建一个web项目
3.2 在pom.xml中加入相关依赖
<!-- springmvc依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- servlet依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- jsp依赖 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency>
3.3 在web.xml中声明DispatcherServlet对象
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--声明springmvc的核心对象 访问mymvc地址后,报错,文件没有找到。找到文件是/WEB-INF/springmvc-servlet.xml或者myweb-servlet.xml(这个) 错误原因:在Servlet的init()方法中,创建springmvc使用的容器对象WebApplicationContext WebApplicationContext ctx=new ClassPathXmlApplicationContext(配置文件) 配置文件的默认路径:/WEB-INF/<servlet-name>-servlet.xml DispatcherServlet作用: 1.在init()中创建springmvc的容器对象 WebApplicationContext,创建springmvc配置文件的所有Java对象。 java对象就是Controller对象 2.DispatcherServlet 是一个Servlet,能够接受请求。 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 如果是自定义的文件,需要在这写自定义配置文件的位置 和监听器的是一样的--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- 在服务器启动时候创建对象,和容器的顺序 在启动时装载对象 随意给个值要求大于等于0 数值越小,创建的越早--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- url-pattern 作用:把一些请求交给servlet处理 就例如将/mymvc交给springmvc处理 使用中央调度器(DispatcherServlet) 1.使用扩展名方式,格式/*.xxx 例如:xxx.xml表示以xml结尾的都算 --> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
3.4 创建一个发起请求的jsp页面(index.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>第一个springmvc</title> </head> <body> <a href="some.do">发起一个som.do的请求</a> </body> </html>
3.5 创建一个普通的类,作为控制器使用,代替之前的servlet
package com.liuhaiyang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** @Controller: 创建控制器(处理器)对象 * 控制器:叫做后端控制器(back controller),自定义的类处理请求的。 * 位置:在类的上面,表示创建此类的对象,对象放在springmvc的容器中 * */ @Controller public class MyController { /* Springmvc框架使用 ,使用控制器类中的方法,处理请求 方法的特点: 1.方法的形参,表示请求中的参数 2.方法的返回值,表示本次请求的处理请求 */ /** * @RequestMapping :请求映射 * 属性:value 请求中的uri地址,唯一值,以"/"开头 * 位置:1.在方法上面(必须) 2.在类定义的上面(可选) * 作用:指定的请求,交给指定的方法处理,等同于url-pattern(个人理解 相当于可以做doget相关的操作) * 返回值ModelAndView:表示本次请求的处理结果(数据和视图) model:表示数据 view:表示视图 */ //可以在一个类中定义多个方法使用多个@RequestMapping注解 @RequestMapping(value = {"/some.do","/first.do"}) //value是一个数组,可以有多个值,相当于将该方法起一个名字 public ModelAndView doSome(){ //doGet() //使用这个方法处理请求,能够处理请求的方法叫做控制器方法 //调用service对象,处理请求,返回数据 ModelAndView mv=new ModelAndView(); //添加数据 mv.addObject("msg","在ModelAddView中处理了some.do的请求"); mv.addObject("fun","执行了dosome的方法"); //指定视图,setviewName("视图路径") 相当于请求转发request.getRequestDis...("/show.jsp").forward(..) // mv.setViewName("/WEB-INF/view/show.jsp"); //当配置了视图解析器,使用文件名称作为视图名使用,叫做视图逻辑名称 //使用了逻辑名称,框架使用配置文件中视图解析器的前缀和后缀,拼接为完整地视图路径 ,例如/WEB-INF/view/ + show + .jsp mv.setViewName("show"); /* 当框架调用完dosome方法后,得到返回中modelandview 框架会在后续的处理逻辑值,处理mv对象里的数据和视图 对数据执行requert,setAttribute(“msg”,“处理了some.do请求”);把数据放到request作用域中 对视图进行转发操作 */ return mv; } }
3.6 创建显示处理结果的jsp页面(webapp\WEB-INF\view\show.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> /show.jsp,显示request作用域中的数据<br> <h2>msg数据:<%=request.getAttribute("msg")%></h2> <h2>fun数据:${fun}</h2> </body> </html>
3.7 创建springmvc.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--spring的配置文件 声明组件扫描器--> <context:component-scan base-package="com.liuhaiyang.controller"/> <!-- 声明视图解析器;帮助处理视图 主要帮助我们处理重复的多余的冗余路径等--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀:指定试图文件的路径--> <property name="prefix" value="/WEB-INF/view/"/> <!-- 后缀,试图文件的扩展名--> <property name="suffix" value=".jsp"/> <!--表示所有的jsp文件--> </bean> </beans>
2.8 配置Tomcat并且启动测试
http://localhost:8080/springmvc_war/
三,Spring MVC连接
- 在Spring MVC项目中实现连接操作之前,我们需要先解决一个问题:何为路由映射?
- 所谓的路由映射指的是,当用户访问一个url时,将用户的请求对应到程序中某个类的某个方法的过程。
- Spring MVC项目实现连接的操作就与路由映射密切相关,实现路由映射可以使用注解。
- 用来实现注册接口的路由映射的常见注解有@RequestMapping,@PostMapping,@GetMapping。
1,@RequestMapping注解
@RequestMapping注解的基本使用:
@RequestMapping注解的基本用法说明:
- @RequestMapping注解可以修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是类+方法。
- @RequestMapping注解可以处理任何HTTP方法的请求,包括GET、POST、PUT、DELETE等。
- @RequestMapping注解可以使用method属性来进行限定处理请求的HTTP方法。
2,@PostMapping注解
@PostMapping注解的基本使用:
@PostMapping注解的基本用法说明:
- @PostMapping注解通常用于修饰控制器类中的方法,而不是类本身。
- @PostMapping注解只可以处理HTTP POST请求映射到处理方法上。
3,@GetMapping注解
@GetMapping注解的基本使用:
@GetMapping注解的基本用法说明:
- @GetMapping注解通常用于修饰控制器类中的方法,而不是类本身。
- @GetMapping注解只可以处理HTTP GET请求映射到处理方法上。
4,三类注解区别总结
- @RequestMapping是通用的注解,可以修饰类和方法,可用于映射任何类型的HTTP请求。
- @PostMapping是专用的注解,可修饰方法,但不能修饰类,仅用于映射HTTP POST请求。
- @GetMapping是专用的注解,可修饰方法,但不能修饰类,仅用于映射HTTP GET请求。
5,GET请求的映射方式
1)使用@GetMapping
注解
2)使用RequestMapping
注解
3)使用RequestMapping
注解并搭配method
属性
四,Spring MVC参数获取
1,获取单个参数
获取单个参数的操作代码:
获取单个参数注意说明:
1)代码中声明的参数名与请求地址栏中的参数名要完全一致,若不一致则无法获取到地址栏中对应的参数值,会为参数的默认值。
2)如果想明确指定请求中的参数要绑定到处理方法的参数,可以在处理方法的参数前使用@RequestParam注解进行参数重命名操作。
2,获取多个参数
获取多个参数的操作代码:
获取多个参数注意说明:
- 1)进行参数匹配时,后端代码的参数名称要与地址栏中的参数名称要保证完全一致。
- 2)前后端进行参数匹配时,是以参数的名称进行匹配的,因此地址栏中的参数位置是不影响后端获取参数的结果。
3,获取普通对象
实体类UserEntity
创建:
获取普通对象的操作代码:
获取普通对象注意说明:
1)Spring MVC 会根据地址栏中输入的参数列表自动实现参数对象的赋值操作。
4,获取Json对象
获取Json对象的操作代码:
从上述的运行检测中,发现无法接收成功 Json对象,尽管上述代码可以接收获取到普通对象。那怎样才能成功接收Json对象呢?
在Spring MVC 中,提供了 @RequestBody
注解来实现接收 Json 对象的操作。获取 Json对象的操作代码如下:
5,获取基础URL参数
获取基础URL参数注意说明:
- 1)使用@PathVariable 注解进行获取URL中的基础参数操作。
- 2)基础URL里面的参数是 ?之前的参数,而不是 ?之后的参数(参数列表内的参数)。
- 3)进行参数匹配时,后端代码的参数名称要与地址栏中的参数名称要保证一致且其对应的参数值要对应。
6,获取上传文件
获取上传文件的操作代码:
对操作代码进行运行检测:
打开指定的路径进行验证文件是否成功上传,观察到文件成功上传并且文件名为指定的img.png
,说明文件成功上传。
上述操作虽然能够实现获取上传文件,但也存在明显的不足缺陷,那就是指定文件路径中只能有一个文件。为什么会出现这种情况呢?
那是因为文件名已经在代码中确定了,只能为img.png,当上传成功一个文件后,后续成功上传的文件会覆盖之前的文件。
那若想解决这个覆盖问题,实现指定文件路径中有多个文件,该怎么办呢?
出现上述这种情况的原因是文件名确定死了,所以我们就只需要从文件名入手即可,也就是让文件名不确定死。
如果想让文件名不确定死,我们可以使用UUID.randomUUID进行随机生成一组32位数的16进制数字所构成的文件名。
获取上传文件的改进代码:
7,获取Header(http请求头部)
获取Header的操作代码:
获取Header的注意事项:
1)使用@RequestHeader
注解进行获取Header中的参数操作,该注解里的参数的参数名要与Header里面的参数名要一致。
8,获取Cookie
cookie其实就是一些数据信息,类型为“小型文本文件”,存储于电脑上的文本文件中。
获取Cookie的操作代码:
手动构造Cookie操作流程:
获取Cookie的操作代码运行结果:
获取Cookie的注意事项:
1)使用@CookieValue
注解进行获取Cookie的操作,该注解里的参数的参数名要与Cookie列表里面的Cookie名要一致。
9,获取Session
session和cookie的比较
- cookie保存在客户端,session保存在服务端
- cookie作用于他所表示的path中(url中要包含path),范围较小。session代表客户端和服务器的一次会话过程,
- web页面跳转时也可以共享数据,范围是本次会话,客户端关闭也不会消失。会持续到我们设置的session生命周期结束(默认30min)
- 我们使用session需要cookie的配合。cookie用来携带JSESSIONID
- cookie存放的数据量较小,session可以存储更多的信息。
- cookie由于存放在客服端,相对于session更不安全
- 由于session是存放于服务器的,当有很多客户端访问时,肯定会产生大量的session,这些session会对服务端的性能造成影响。
总结
session就是一个存储于服务器的特殊对象,通过session可以实现数据共享,session有一个JSESSIONID,这个是session的唯一标识,使用它可以查找到session。session是会话级别的,对于每一个客户端来说是独享它所拥有的session的,我们使用session在进行页面跳转时,服务端可以利用session进行数据共享。session由服务器进行控制。session的创建和销毁都是服务器进行管理的。服务器会为每一个客户端创建一个session。
获取Session的操作代码:
存储Session的操作代码运行检测:
获取Session的操作代码运行检测:
获取Session的注意事项:
- 1)使用@SessionAttribute 注解进行获取Session的操作,该注解里的参数的参数名要与Session列表里面的Session名要一致。
- 2)存储Session操作没有与之对应的注解,只有获取Session操作才有对应的注解@SessionAttribute 进行简便获取。
- 3)Cookie能通过手动添加,但Session不能手动添加,只能通过代码进行Session创建后添加,故可知Session比Cookie更安全。
五,Spring MVC数据输出
1,返回静态页面
静态页面代码:
返回静态页面操作代码:
注意说明:如果index.html不加/
,表示在当前目录下查找该文件,如果加了/
,表示在根目录下查找该文件。
操作代码运行后,具进行查看输出数据是否为静态网页。
2,返回文本数据
返回文本数据操作代码:
3,返回Json对象
返回Json对象操作代码:
六、拦截器和过滤器
1、Filter过滤器介绍
(一)定义过滤器 filter 主要是依赖于servlet,针对用户的请求进行预处理,再交给servlet进行处理并生成响应,接着再对服务器的响应进行后处理。
(二)作用
它可以改写请求或响应的请求头或响应头信息以及携带的参数数据; 也可以对特殊请求进行日志记录,还可以进行用户授权认证处理,防止非法访问;还可以对请求做一些特殊处理,以springMVC 自带的过滤器为例简单介绍下,比如编码格式过滤器 CharacterEncodingFilter,专门用来处理请求参数和返回参数中中文参数乱码的问题;再比如针对rest请求设置处理过滤器 HiddenHttpMethodFilter,针对页面的post请求,结合隐藏域参数_method将post请求转化为put或delete请求。
(三)代码演示
/** * @Description: 自定义过滤器 */ /*@WebFilter("/auth/*") // 注解的方式*/ public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; // 获取会话 HttpSession session = request.getSession(); // 获取用户请求路径 String requestPath = request.getServletPath(); // 验证是否非法访问 if(null==session.getAttribute("user") && !requestPath.endsWith("login")){ // 转发到登录页面进行登录 //request.setAttribute("msg", "请进行登录."); //request.getRequestDispatcher(request.getContextPath()+ "/login").forward(servletRequest, servletResponse); // 重定向到登录页面 response.sendRedirect(request.getContextPath()+"/login"); }else { chain.doFilter(request, response); } } @Override public void destroy() { Filter.super.destroy(); } }
如果使用注解的方式,把注释的注解放开。否则还需要在web.xml中加入filter的配置
<!--自定义认证过滤器--> <filter> <filter-name>authFilter</filter-name> <filter-class>com.hubeijinghan.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>authFilter</filter-name> <url-pattern>/auth/*</url-pattern> </filter-mapping>
需要注意的是我本地用的jsp页面来测试的,mvc配置文件中配置了视图的前缀和后缀,同时对于login页面的访问路径,需要根据资源目录结果视图前缀,配置静态资源映射~
2、拦截器介绍
(一)、定义拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。它采用AOP的设计思想,在方法之前之后提供了三个跟主功能没有关系的拓展接口。
(二)、作用它和过滤器的作用相似,可以用来记录日志、控制权限、记录异常和检查接口的性能,等等。
(三)、代码演示
/** * 自定义拦截器 */ public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 执行请求方法前执行的方法 System.out.println("第一个方法拦截器 preHandle....."); // 获取session HttpSession session = request.getSession(); // 获取用户请求地址 String servletPath = request.getServletPath(); if(null==session && !servletPath.endsWith("login")){ // 转发到登录页面 request.getRequestDispatcher(request.getContextPath()+ "/login").forward(request, response); // 重定向到登录页面 // response.sendRedirect(request.getContextPath()+"/login"); return false; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 执行请求方法后,页面视图渲染前,执行的方法 System.out.println("第一个方法拦截器 postHandle....."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 执行请求方法后,页面视图渲染后,执行的方法 System.out.println("第一个方法拦截器 afterCompletion....."); } } /** * @Description: 第二个拦截器 */ public class MySecondInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("第二个拦截器 preHandle....."); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){ System.out.println("第二个拦截器 postHandle......"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex){ System.out.println("第二个拦截器 afterCompletion....."); } } <!--自定义拦截器配置--> <mvc:interceptors> <bean class="com.hubeijinghan.interceptors.MyInterceptor"></bean> <bean class="com.hubeijinghan.interceptors.MySecondInterceptor"></bean> </mvc:interceptors>
注意: 拦截器配置是加在mvc的配置中的。如果配置了多个拦截器拓展方法的执行顺序是有区别的,preHandle 根据配置文件中的顺序是正序执行,postHandle、afterCompletion 则是逆序执行~
3、过滤器和拦截器的区别
- ①、过滤器是基于函数回调的,拦截器是基于java反射机制的;
- ②、过滤器依赖于sevlet容器,而拦截器不依赖servlet,拦截器依赖SpringMVC;
- ③、过滤器几乎对所有的请求都起作用,而拦截器只能对springMvc请求起作用;
- ④、拦截器可以访问处理方法的上下文,而过滤器不行
附一张过滤器、拦截器请求的链路图:
标签:请求,SpringMVC,视图,session,参数,注解,servlet From: https://www.cnblogs.com/zhao-ke-ming/p/18357916