首页 > 代码库 > SpringMVC
SpringMVC
一 概述
1.什么是SpringMVC?
Model-View-Controller,一种软件设计思想,将软件分为三层:模型层、视图层、控制层。模型层负责具体的业务处理,指的是程序中的业务逻辑。视图层指的是与用户交互的界面。控制层负责请求的分发,将请求分发给指定的业务逻辑。
2.什么是Spring MVC?
Spring MVC是Spring对MVC思想的一种实现,建立在Spring核心功能之上,功能强大,使用方便。
二 Spring MVC执行流程
1.DispatcherServlet
框架的核心,一个Servlet。服务器将符合DispatcherServlet映射路径格式的请求转发给求DispatcherServlet,
DispathcherServlet获得请求以后,调用SpringMVC的各个组件来处理请求。
需要在web.xml文件中配置:
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
⑴DispatcherServlet默认从WEB-INF目录下加载Spring的配置文件,可以通过为属性contextConfigLocation赋值的方式,更改配置文件的位置。这一点同Spring与Web整合时遇到的问题及其处理方式相同。
⑵默认情况下,Servlet在被请求时才实例化初始化,如果希望在服务器启动时创建Servlet对象,可以通过<load-on-startup>标签设定。该标签只接受int类型数据,等于0或者大于0时,服务器启动时创建servlet对象,小于0,请求时创建。在等于或者大于0的情况下,数字越小,优先级越过,越先创建,允许多个Servlet具有相同的值。加载顺序相同时,系统选择其中一个优先执行,不会导致异常。
⑶<url-pattern>:
①请求:一切以从服务器端获取资源为动机的行为都是请求,分为两类:
显式请求:用户在浏览器端通过手动点击或者输入的方式发出的请求。
隐式请求:包含在显示请求内部,不是由用户直接触发的请求,比如用户手动请求一个页面,这个请求就是显式,而页面从服务器加载图片的行为不是用户直接手动触发的,属于隐式请求
②*.do:一般写成*加后缀的形式。
③/*:不能写成这种形式。这种形式会把Web服务器接收到的请求全部转发给DispatcherServlet,而SpringMVC容器中不一定存在对应的Handler,会因找不到对应的资源而报错,比如无法加载HTML、JSP页面。
④/:配置这种形式,无法处理页面中的静态请求,即HTML页面以及JSP页面中的.jsp、.css等静态信息无法加载。
两种处理方法:
第一种方式,在web.xml文件中配置:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
通过匹配静态资源名称的方式将页面中所有静态资源包含进来。
实现原理:
Web服务启动时加载两个web.xml文件,一个在tomcat安装目录下的config文件夹中,称作默认容器,一个是项目中的,称作自定义容器。当两个容器出现冲突信息时,以项目中的为准。在默认容器中,定义了一个DefaultServlet,servlet-name为default。DefaultServlet用于为服务器中的其他程序提供静态资源。
第二种方式,在Spring配置文件中加入:<mvc:default-servlet-handler/>,底层也是调用了DefaultServlet。
采用*.do时不可以添加静态资源的解决方案,否则无法找到目标资源。
2.执行流程:
浏览器发出请求,Web服务器解析该请求,如果匹配DispatcherServlet的映射路径,就将请求转发给DispatcherServlet。DispatcherServlet获的请求以后首先判断该请求是否是文件上传请求,然后将请求转发给HandlerMapping,HandlerMapping根据映射关系找到对应的Handler,并将Handler与HandlerInterceptor封装成一个HandlerExcutionChain对象返回给中央调度器,中央调度器根据Handler获取HandlerAdaptor,HandlerAdaptor调用对应的Handler执行业务逻辑,处理完毕返回一个ModelAndView对象给中央处理器,中央处理器将ModelAndView对象转发给ViewResolver视图解析器,处理完毕返回一个View对象,中央处理器再将View对象转发给View视图渲染器,渲染完毕,中央处理器将视图响应给浏览器。
3.ModelAndView:
一个沟通业务逻辑与视图的类,因为包含最终视图的全部信息,又不是最终视图,被称作逻辑视图。其中既包含早已建好的视图模板,也包含需要传入视图的动态参数Model。
三 配置式开发
1.什么是配置式开发?
由程序员定义SpringMVC各部分具体执行类的开发模式,叫做配置式开发,而不是完全采用系统默认的类。
2.处理器:
⑴Controller实现类。
⑵HttpRequestHandler实现类。
⑶AbstractController继承类:通过supportedMethods限定请求方式。
⑷MultiActionController的子类:可以定义多个处理方法。已过时。
①问题的关键是怎么访问目标资源中的方法,即请求url怎样编写。从请url中解析方法的方式不同,url的编写格式不同。
② InternalPathMethodNameResolver:默认解析方法,请求url语法格式:/xxxx/methodName.do。
③ ParamterMethodNameResolver:请求url语法格式/xxx?action=methodName,action为paramName默认action,可以自定义。
④ PropertiesMethodNameResolver:请求可以采用/*.do的格式,在PropertiesMethodNameResolver中通过属性mappings建立请求url与方法的映射关系。
3.HandlerMapping
访问资源时使用的不是资源的全限定性类名或者其他可以直接确定资源的方式,而是采用url,这样就需要在访问方式与与资源之间建立起一对一的关系,这种关系就是映射关系,HandlerMapping就负责创建与管理这种关系,根据访问方式确定处理器。
⑴概括讲,HandlerMapping的作用就是在请求url与目标资源之间建立起映射关系,根据访问方式确定资源。
⑵HandlerMapping是一个接口,三个常用的实现类:
①BeanNameUrlHandlerMapping:默认的处理器映射器,采用该类作为处理器映射器时,beanName必须以“/”开头。在这种方式下,采用beanName作为访问的Url。
②DefaultAnnotationHandlerMapping:默认注解开发时的处理器映射器。
③SimpleUrlHandlerMapping:非默认处理器映射器,采用简单的url作为访问方式,如“/xxx”。具体实现:
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/simpleUrl.do"value="myController" />
<entry key="/simpleUrl01.do"value="myController" />
</map>
</property>
</bean>
key是访问url,前面的“/”,可以省略,系统自动添加。value是处理器id,这样就在访问url处理器之间建立了映射关系。
④如果显式地配置了处理器映射器,那么默认的映射器不再起作用。
⑤HandlerMapping返回一个封装了Handler与HandlerInterceptor的HandlerExecutionChain给中央调度器。
4.HandlerAdapter
⑴为什么使用Adapter来处理Handler?
Handler有多种类型,中央调度器不能同时处理,而是通过调用对应的适配器来处理,这样分工明确,中央调度器结构清晰。
⑵底层实现过程:
采用适配器模式:根据处理器实现的接口获取对应的适配器,由适配器调用处理器执行其中的方法。
5.ModelAndView
⑴ModelAndView由两部分构成model、view。
①model:数据对象,包含将要自动传入页面中的动态参数。
实例化:作为处理器方法的形参,底层调用时实例化。
作用:主要用于向页面传递参数,在java代码中只能向其中保存数据,无法获取数据。
Model对象最好不要作为异常处理方法的形参,因为系统在向异常处理方法传递Model对象时存在很大的不确定性。
②view视图对象,封装了显示的视图。
⑵视图创建的3种方式:
①ModelAndViewmv=new ModelAndView();
mv.setViewName("内部视图相对于项目的路径");
②使用RedirectView类创建外部视图:
<bean id="taobao"class="org.springframework.web.servlet.view.RedirectView">
<property name="url" value="http://www.taobao.com" />
</bean>
③使用JstlView创建内部视图:
<bean id="innerResource"class="org.springframework.web.servlet.view.JstlView">
<property name="url" value="/WEB-INF/firstDemo/welcome.html" />
</bean>
⑶视图解析器
①不同的视图,即不同定义视图的方式对应不同的视图解析器。
②InternalResourceViewResolver
默认的视图解析器只能根据路径解析项目内部的视图,无法处理其他项目中的视图。
③BeanNameViewResolver
在配置文件中利用RedirectView或者JstlView类封装视图,在java代码中使用beanName返回视图,BeanNameViewResolver根据beanName解析视图。
⑷视图的放置
①如果封装视图较多,可以单独放在一个文件中,SpringMVC提供了两种方式视图对象的文件:xml、properties。
②视图存放的文件类型不同,、解析方式不同。
③XmlViewResolver:
将视图单独放在XML文件中时采用XmlViewResolver解析视图。
具体实现:
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location"value="classpath:com/springmvc/viewResolver/myViews.xml"/>
</bean>
④PropertiesViewResolver:
将视图放在属性文件中时采用PropertiesViewResolver解析视图,属性文件只能放在类路径下。
视图的定义:
viewName.(class)=RedirectView/JstlView
viewName.url=http://xxxxxx
将属性文件加载到配置文件中并解析视图:
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basenames" value="myViews" />
</bean>
baseNames指的是类路径下放置视图的属性文件名,不包括扩展名。
⑸配置多个视图解析器的情况
①允许配置多个视图解析器,默认情况下,在配置文件中上方的优先级高于下方的,默认的视图解析器InternalResourceViewResolver级别最低。
②可以使视图解析器的优先级不受配置顺序的约束:在配置视图解析器时,通过order属性设定优先级,int类型,大于0,值越小,优先级越高。
③InternalResourceViewResolver配在最后。
四 处理器的注解开发
1.Spring注解采用被动加载,必须指明采用注解的组件位置:
<context:component-scan base-package=""/>
2.常用注解:
⑴@Controller:标在类名上,表明该类是一个处理器。
⑵@RequestMapping(""):标在类名上,用作请求url的公共开头部分,可称作命名空间,与方法上的url连接时没有“/”系统自动增加“/”,所以用以连接的“/”可以省略。
①/*:代表一级目录。
②/**:代表任意级目录。
⑶@RequestMapping(value=""):标在方法上,用来定义访问该处理方法的请求url,其他属性:
①method:限定请求方式,如method=RequestMethod.POST。
②params:限定请求必须携带的参数。
params={"paramName01","paramName02"}:请求中必须出现参数paramName01、paramName02。
params={"!paramName01","paramName02"}:请求中不能出现参数paramName01,必须出现参数paramName02。
params={"paramName01=value02"}:请求中必须出现参数paramName01,并且其值必须为value01。
params={"paramName01!=value02"}:请求中必须出现参数paramName01,并且其值不能为value01。
3.自定义处理方法
⑴自定义处理方法没有任何限制,可以有返回值,也可以没有返回值,可以有形参,也可以没有形参。
⑵可以有的形参:
①HttpServletRequest。
②HttpServletResponse。
③HttpSession。
④Model。
⑤请求参数或者请求参数的封装类。
⑥BindingResult。
五 表单输入注入处理方法
1.将表单输入注入到处理方法中有以下几种方式:
⑴分散注入:表单输入分别注入到对应的形参中。
在表单输入名与处理方法名相同的情况下,自动注入,当名称不相同时,需要在表单输入名与形参名之间建立映射关系:
public ModelAndViewdoFirst(@RequestParam("name") String pname, int age) {}
在形参名前通过注解@RequestParam指明对应的请求参数名。
⑵封装注入:将表单输入注入到封装对象中,只需要将处理方法的形参设定为封装类型对象即可。
⑶域属性注入:封装对象中包含域属性,表单在设定输入名称时域属性的属性通过域属性引用的形式给定。
<form action="rph03.do" method="post"> 姓名:<input type="text" name="name"><br> 年龄:<input type="text" name="age"> <br> 学校:<input type="text"name="school.name"><br> 地址:<input type="text" name="school.addr"><br> <input type="submit" value="提交"> </form>
school是域属性,name/addr是域属性的属性。
2.不是所有的表单输入都必须被接收,也不是处理方法中的每一个参数都必须被注入。
3.SpringMVC将接收表单输入的封装对象保存到request作用域中,分散接收变量没有保存到request作用域中。
4.pathVariable
在请求路径中加入变量,处理方法从路径中获取参数值。
@RequestMapping("/{name}/rph04.do")
public ModelAndView doFourth(@PathVariable(name = "pname") String name, int age){}
⑴name不仅作为路径变量,而且为方法的形参name赋值。实质上,就是将请求参数作为路径的一部分,包含在路径当中。
⑵@PathVariable:用来建立路径变量与方法形参之间的映射关系。
六 处理器返回值
1.处理器方法可以有多种返回值:
String、void、Object。
2.String
⑴视图路径。
⑵视图beanName。
3.void
可以向页面响应JSON字符串。
4.Object
将响应内容通过响应体发送给浏览器。
⑴环境搭建:
①在配置加入<mvc:annotation-driven/>。
②在方法上注解@ResponseBody,表示将返回值放入响应体中。
⑵基本数据类型、字符串:解决中文乱码问题,在@RequestMapping中加入属性produces="text/html;charset=UTF-8",限定响应内容类型与编码。
⑶自定义类、Map集合、List集合:通过响应体以JSON字符串的格式返回,需要做如下工作:
①导入jackson架包。
目的是为了在容器初始化时创建HttpMessageConverter转化器,将处理方法返回数据转化为json字符串。
5.返回的字符串类型的数据,默认情况下被当做视图名处理,如果希望保存到响应体中,必须在处理方法上加注解@ResponseBody。
七 请求转发与重定向
1.数据传递
⑴请求转发时,Model中的数据自动保存在request作用域中。
⑵重定向时,Model中的数据自动保存在param环境信息中。
2.转发到页面或者另一个处理方法:
return "forward:/xxx":forward是默认值,可以省略。
3.重定向到页面或者另一处理方法:
return "redirect:/xxxx"。
八 异常处理
1.为异常指定跳转页面
发生异常时,跳转到指定页面,使用内置类SimpleMappingExceptionResolver,只在异常类型与跳转页面间建立
映射关系:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="defaultErrorView" value="/Exception/error.jsp" /> <property name="exceptionMappings"> <props> <prop key="com.springmvc.exception.AgeException">/Exception/ageException.jsp</prop> <prop key="com.springmvc.exception.NameException">/Exception/nameException.jsp</prop> </props> </property> </bean>
⑴defaultErrorView:为没有指定跳转页面的异常类型设定一个异常发生时默认的跳转页面。
⑵exceptionMappings:为异常定制页面。
2.接口式异常处理器
⑴创建:实现HandlerExceptionResolver接口,在配置文件中配置后即可使用。
⑵可处理的异常范围:不仅可以处理方法内部的异常,而且可以处理方法调用时的异常,如类型转化异常。
3.注解式异常处理器
⑴位置:在处理器内部,建立一个方法,在方法上添加注解@ExceptionHandler(MyException.class),这样该方法就可以处理该类中指定的异常了。
⑵可处理的异常范围:不仅可以处理方法内部发生的异常,也可以处理调用处理方法前发生的异常,比如数据转化异常。
⑶有效范围:只对所在处理器中的方法有效。
⑷形参构成:自定义异常处理器方法中不能有Model类型参数, 因为Model只有在作为处理器方法的形参时才被实例化。
⑸一般定义格式:
public ModelAndView handleException(HttpServletRequest request,Exception ex)
4.如果同时创建了接口式异常处理器与注解式异常处理器,优先采用接口式异常处理器。
5.根据作用范围大小,自定义异常处理器有两种:
⑴类范围:注解式异常处理器只对当前类有效。
⑵全局范围:接口式异常处理器对所有类均有效。
6.根据需要对异常进行处理的深度,选择异常处理方式。
⑴如果当异常发生时,仅仅需要输出异常信息,跳转到指定页面,可以采用配置内置的异常处理器的方式。
⑵如果需要进一步处理异常,可以采用接口式或者注解式异常处理器。
7.异常处理器被调用的过程是一个请求转发的过程。
8.异常处理器只能捕获抛出的异常,在方法内部处理的异常无法获取,因为异常已经在方法内部处理了,不需要再处理。
九 数据类型转换
1.数据类型转换问题产生的原因?
数据类型转换问题是由浏览器提交类型与服务器接收类型不一致导致的。浏览器以String[]的形式向服务器提交表单数据,而服务器需要的类型是多样的,比如日期类型,这时就需要将表单提交的字符串转换为日期。
2.底层怎么为表单输入选择类型转换器的?
根据表单输入与处理器方法形参之间的映射关系,将表单输入按照对应的形参类型进行转换。
3.内置转换器的作用
SpringMVC为常见的java类型提供了类型转换器,转化是由框架默认完成的,不需要程序员参与,主要是将字符串转换为基本数据类型,如将字符串转化为int、double等。
4.接口式类型转换器器
⑴创建过程:
①实现Converter接口。
②在SpringMVC中类型转换器统一由ConversionServiceFactoryBean管理,将自定义的类型转换器添加到管理器中:
<bean id="myDateConverter"class="com.springmvc.conversion.MyDateConverter" /> ------------生成的不是工厂对象,而是由工厂类生成转换服务对象----------- <bean id="conversionService"class="org.springframework.context.support.ConversionServiceFactoryBean"> <propert yname="converters"> <set> <ref bean="myDateConverter"/> </set> </property> </bean>
在Spring容器中的对象不总是对应配置类的对象,有时是配置类的管理对象。
③将转换服务对象添加到注解驱动中, 一些不常用的功能统一由注解驱动管理:
<mvc:annotation-drivenconversion-service="conversionService" />
5.注解式类型转换器
⑴创建:
①在处理器内部定义如下方法,返回值void,方法形参WebDataBinder类型:
@InitBinder//表明该方法用作类型转化方法
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class,new MyPropertiesEditor());//自定义属性编辑器
}
②自定义属性编辑器MyPropertiesEditor,继承PropertiesEditor:
提交格式不在可转换格式之列时,必须抛出异常TypeMismatchException,不然无法启动异常处理器。
主要实现同接口式相同,调用setValue方法保存转换结果。
⑵基本原理:创建一个类型转化器,将其与表单输入数据绑定。
⑶注解式类型转化器必须在不可转换时显式抛出异常,才能启动异常处理器。
6.如果同时创建了接口式与注解式类型转换器,注解式优先起作用。
7.数据回显与显示提示信息
⑴什么是数据回显?
当表单输入发生类型转化错误或者其他原因导致验证未通过时,视觉上页面不跳转,用户输入数据不丢失,原样显示。
⑵数据回显与显示提示信息都是利用异常处理机制,当发生类型转化异常或者其他验证异常时,启动异常处理器,经异常处理器跳转到输入页面,同时将输入数据与提示信息显示在输入页面中。
⑶在表单设计时,使用EL表达式插入用于回显的内容。
⑷用于数据回显的异常处理器必须限定类型,如TypeMismatchException,不然发生其他异常时也触发异常处理器,跳转到输入页面。
十 数据验证
1.数据验证是在类型转化成功的基础上对表单输入的进一步验证,如果类型转化未通过,不会进行数据验证。
2.SpringMVC支持多种数据验证实现,目前项目中主要使用Hibernate Validator,使用时需导入Hibernate Validator架包。
3.域模型
Hibernate Validator是基于domain model的,在域模型属性上添加注解约束,虽然在属性上添加了约束,并不意味着使用该模型时约束一定发挥作用,默认情况下不起作用,只要在使用时注解@Validated才起作用,即约束在显示调用时才起作用:
⑴@NotNull(message=""):非空约束,用于约束字符串。
⑵@Size(max="",min=""):约束字符串长度。
⑶@Max(value=""):最大值约束。
⑷@Min(value=""):最小值约束。
⑸@Post:约束日期,表示只能输入相对于当前过去的日期。
⑹@Future:约束日期,表示只能输入相对于当前未来的日期。
⑺@Range(max="",min=""):约束取值范围。
⑻@Pattern(regexp=""):要求输入内容必须匹配给定的正则表达式。
4.配置文件编写:
导入架包以后需要在配置文件注册使用的验证器:
<bean id="validator"class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <propert yname="providerClass"value="org.hibernate.validator.HibernateValidator" /> </bean> <mvc:annotation-driven validator="validator" />
5.处理器方法编写:
⑴处理器采用域模型接收表单输入,形参前添加注解@Validated,表明此处的域模型对象需要验证。
⑵在形参中加入BindingResultresult对象,获取表单数据注入状况,比如类型转化异常、验证未通过。一旦加入了该对象,处理器方法在发生注入异常时也会被执行,因此在方法内部需要进行判断:正确注入,注入异常。
①booleanb=result.getErrors():判断注入过程中是否发生异常。
②FieldErrornameFieldError=result.getFieldError("name"):获取向某个属性注入表单输入时发生的异常。
③Stringmessage=nameFieldError.getDefaultMessage():获取向某个属性注入时发生异常的具体信息。
④发生验证异常时通过getDefaultMessage()获取的是在域模型中定义的异常信息,可以直接输出,而发生类型转换异常时获取的是系统自定义的异常信息,英文,较长,对用户不友好,发生转换异常时需要自定义提示信息,因此就需确定发生的是哪一种异常。
区分依据:异常信息。
一般发生类型转化异常时,异常信息以“Failed to convert property value of type”开头,可以判断异常信息中是否含有该字段,区分异常类型。
⑶一个域模型对象对应一个BindingResult,为了保证对应对象关系,在处理器方法中域模型形参与BindingResult两个形参紧邻,中间不能有其他参数,并且域模型在前。
十一 文件上传
1.文件上传的具体过程
DispatcherServlet获取请求以后,首先判断该请求是否是文件上传请求,如果是则采用文件上传时特有的操作。基本过程与处理非文件上传请求时相同,加入了特有操作。
2.CommonsMultipartResolver类定义了很多实际开发时需要调整的参数,因此该类需要在配置文件中配置,由于由DispatcherServlet调用,引用变量名固定multipartResolver,不能更改。
⑴可以通过属性设定编码方式,解决文件名为中文时的乱码问题。
⑵可以定义单词允许上传的最大文件值。
3.处理方法形参中必须包含一个MultipartFile参数,接收上传的文件,文件名为表单中文件名,多个文件上传时,参数为数组。
⑴文件上传前判断是否选择文件,不然导致虚假上传。
⑵MultipartFile对象即使在没有文件上传时依然被实例化,因此不能根据是否为null判断是否选择上传文件,可以根据文件大小getSize判断。
⑶限定上传类型:不同文件最大的区别之一就是扩展名,可以利用String中的方法endsWith判断文件名是否已固定扩展名结尾来限定上传文件类型。
⑷具体实现:
String filename=mf.getOrginalFilename();//获取文件名getName获取的表单中的文件名 ............................................ mf.transferTo(file);
十二 拦截器
1.SpringMVC框架中的拦截器与Servlet、Struts2的拦截器在功能与用法相同,都是在目标对象方法执行前后做某些操作,比如,在访问目标资源前,验证权限,在访问结束后关闭资源等。
2.拦截器与处理器之间的关系:
HandlerMapping返回的是一个封装了Handler与拦截器的HandlerExecutionChain对象。
3.拦截器拦截请求的依据
拦截器根据请求url拦截请求,需要将请求url与拦截器绑定,不在拦截器绑定的请求url之列的请求不会被拦截器拦截。
4.SpringMVC只提供了一种创建拦截器的方法:接口式,实现HandlerInterceptor接口。接口中共有三个方法:
⑴preHandler(拦截器前置通知):在处理器方法执行前执行。
①作用:用于决定是否继续执行请求。
②返回true,继续执行后面的拦截器或者处理方法,不论后面的执行状况如何,afterCompletion都会被执行。返回false终止执行,请求结束,不会执行afteCompletion。
⑵postHandler(拦截器后置通知):在处理器方法执行完毕只有执行。
①作用:关系资源,向ModelAndView中添加数据。
⑶afterCompletion(拦截器渲染后通知):
①执行条件:前置通知返回true。
②执行时机:在视图渲染完毕之后执行。
5.由于拦截器需要实现HandlerInterceptor接口自定义,因此需要注册:
<mvc:interceptors> <mvc:interceptor> <mvc:mappingpath="/*" /> <refbean="oneInterceptor" /> </mvc:interceptor> <mvc:interceptor> <mvc:mappingpath="/*" /> <beanclass="com.springmvc.interceptor.TwoInterceptor" /> </mvc:interceptor> </mvc:interceptors>
6.执行顺序:
系统按照配置顺序执行拦截器,先配置的拦截器排在前面,处理器方法执行前从前往后执行拦截器,执行完毕后从后往前执行拦截器。
SpringMVC