- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章SpringMVC中的拦截器详解及代码示例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文研究的主要是SpringMVC中的拦截器的介绍及实例代码,配置等内容,具体如下.
Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用方法.
。
1.1 springmvc拦截器的定义 。
在springmvc中,定义拦截器要实现HandlerInterceptor接口,并实现该接口中提供的三个方法,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//测试拦截器1
public
class
HandlerInterceptor1
implements
HandlerInterceptor{
@Override
public
Boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws
Exception {
System.out.println(
"HandlerInterceptor1....preHandle"
);
//false表示拦截,不向下执行;true表示放行
return
true
;
}
@Override
public
void
postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView)
throws
Exception {
System.out.println(
"HandlerInterceptor1....postHandle"
);
}
@Override
public
void
afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws
Exception {
System.out.println(
"HandlerInterceptor1....afterCompletion"
);
}
}
|
针对这三个方法,我做一下简单的分析:
1.2 springmvc拦截器的配置 。
在springmvc中,拦截器是针对具体的HandlerMapping进行配置的,也就是说如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。比如,假设我们在配置文件中配置了的映射器是org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,那么我们可以这样来配置拦截器:
1
2
3
4
5
6
7
8
9
10
|
<
bean
class
=
"org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"
>
<
property
name
=
"interceptors"
>
<
list
>
<
ref
bean
=
"handlerInterceptor1"
/>
<
ref
bean
=
"handlerInterceptor2"
/>
</
list
>
</
property
>
</
bean
>
<
bean
id
=
"handlerInterceptor1"
class
=
"ssm.intercapter.HandlerInterceptor1"
/>
<
bean
id
=
"handlerInterceptor2"
class
=
"ssm.intercapter.HandlerInterceptor2"
/>
|
那么在springmvc中,如何配置类似于全局的拦截器呢?上面也说了,springmvc中的拦截器是针对具体的映射器的,为了解决这个问题,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中,这样就可以成为全局的拦截器了。配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!-- 配置拦截器 -->
<
mvc:interceptors
>
<!-- 多个拦截器,按顺序执行 -->
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<!-- 表示拦截所有的url包括子url路径 -->
<
bean
class
=
"ssm.interceptor.HandlerInterceptor1"
/>
</
mvc:interceptor
>
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<
bean
class
=
"ssm.interceptor.HandlerInterceptor2"
/>
</
mvc:interceptor
>
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<
bean
class
=
"ssm.interceptor.HandlerInterceptor3"
/>
</
mvc:interceptor
>
</
mvc:interceptors
>
|
一般我们都用这种配置,<mvc:mapping>中指定要拦截的url即可.
。
仿照上面的HandlerInterceptor1再写两个拦截器,HandlerInterceptor2和HandlerInterceptor3,配置是按照上面这个配置。然后我们来测试一下三个拦截器的执行情况,并做相关总结.
2.1 三个拦截器都放行 。
也就是说,我们将三个拦截器的preHandle方法中返回值都改成true,来测试一下拦截器的执行顺序,测试结果如下:
HandlerInterceptor1….preHandle HandlerInterceptor2….preHandle HandlerInterceptor3….preHandle 。
HandlerInterceptor3….postHandle HandlerInterceptor2….postHandle HandlerInterceptor1….postHandle 。
HandlerInterceptor3….afterCompletion HandlerInterceptor2….afterCompletion HandlerInterceptor1….afterCompletion 。
根据打印的结果做一个总结:当所有拦截器都放行的时候,preHandle方法是按照配置的顺序执的;而另外两个方法按照配置的顺序逆向执行的.
2.2 有一个拦截器不放行 。
我们将第三个拦截器的preHandle方法中返回值改成false,前两个还是true,来测试一下拦截器的执行顺序,测试结果如下:
HandlerInterceptor1….preHandle HandlerInterceptor2….preHandle HandlerInterceptor3….preHandle 。
HandlerInterceptor2….afterCompletion HandlerInterceptor1….afterCompletion 。
根据打印的结果做一个总结: 1. 由于拦截器1和2放行,所以拦截器3的preHandle才能执行。也就是说前面的拦截器放行,后面的拦截器才能执行preHandle。 2. 拦截器3不放行,所以其另外两个方法没有被执行。即如果某个拦截器不放行,那么它的另外两个方法就不会背执行。 3. 只要有一个拦截器不放行,所有拦截器的postHandle方法都不会执行,但是只要执行过preHandle并且放行的,就会执行afterCompletion方法.
2.3 三个拦截器都不放行 。
这种情况其实可以参考上面的情况了,是一个特例,也看一下运行结果:
HandlerInterceptor1….preHandle 。
很明显,就只执行了第一个拦截器的preHandle方法,因为都不放行,所以没有一个执行postHandle方法和afterCompletion方法.
。
从第二种情况来看,比如现在要写一个统一异常处理的逻辑,那么要将该拦截器放在拦截器链的第一个位置,且一定要放行,因为只有放行了,才会去执行afterCompletion,而且放在拦截器链的第一个的话,afterCompletion方法会最后执行,才能在里面执行统一异常处理的逻辑。 再比如,登陆认证拦截器,放在拦截器链接中第一个位置(如果有统一异常处理,那么应该放在统一异常处理的后面)。权限校验拦截器,放在登陆认证拦截器之后(因为登陆通过后才校验权限)。 这里写一个登陆验证的拦截器来说明一下如何使用springmvc的拦截器.
3.1 需求 。
首先看一下需求:我们要拦截啥,拦截到了要干啥。思路如下:
1、用户请求url 2、拦截器进行拦截校验 如果请求的url是公开地址(无需登陆即可访问的url),让放行。 如果用户session不存在,则跳转到登陆页面。 如果用户session存在则放行,继续操作.
3.2 实现登陆的Controller方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//登陆
@RequestMapping
(
"/login"
)
public
String login(HttpServletRequest request, String username, String password)
throws
Exception {
//实际中要去和数据库匹配的
//....
//这里就假设登陆成功了
HttpSession session = request.getSession();
session.setAttribute(
"username"
, username);
return
"redirect:queryItems.action"
;
}
//退出
@RequestMapping
(
"/logout"
)
public
String logout(HttpServletRequest request)
throws
Exception {
HttpSession session = request.getSession();
session.invalidate();
return
"redirect:queryItems.action"
;
}
|
3.3 登陆验证拦截器的实现 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//测试拦截器1
public
class
LoginInterceptor
implements
HandlerInterceptor{
//进入Handler方法之前执行
//可以用于身份认证、身份授权。如果认证没有通过表示用户没有登陆,需要此方法拦截不再往下执行,否则就放行
@Override
public
Boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws
Exception {
//获取请求的url
String url = request.getRequestURI();
//判断url是否公开地址(实际使用时将公开地址配置到配置文件中)
//这里假设公开地址是否登陆提交的地址
if
(url.indexOf(
"login.action"
) >
0
) {
//如果进行登陆提交,放行
return
true
;
}
//判断session
HttpSession session = request.getSession();
//从session中取出用户身份信息
String username = (String) session.getAttribute(
"username"
);
if
(username !=
null
) {
return
true
;
}
//执行到这里表示用户身份需要验证,跳转到登陆页面
request.getRequestDispatcher(
"/WEB-INF/jsp/login.jsp"
).forward(request, response);
return
false
;
}
//节省空间,省略另外两个方法不写了,也不用处理
}
|
然后配置该拦截器:
1
2
3
4
5
6
7
8
9
|
<!-- 配置拦截器 -->
<
mvc:interceptors
>
<!-- 多个拦截器,按顺序执行 -->
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<!-- 拦截所有的url包括子url路径 -->
<
bean
class
=
"ssm.interceptor.LoginInterceptor"
/>
</
mvc:interceptor
>
<!-- 其他拦截器 -->
</
mvc:interceptors
>
|
这样当我们任意请求一个url的时候,就会被刚刚我们定义的拦截器给捕获到,然后会判断是否session中有用户信息,没有的话就会跳到登陆页面让我们登陆:
1
2
3
4
5
|
<
form
action
=
"${pageContext.request.contextPath }/login.action"
method
=
"post"
>
用户名:<
input
type
=
"text"
name
=
"username"
/><
br
>
密码:<
input
type
=
"password"
name
=
"password"
/><
br
>
<
input
type
=
"submit"
name
=
"提交"
/>
</
form
>
|
拦截器的使用基本上就介绍到这了.
。
以上就是本文关于SpringMVC中的拦截器详解及代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持! 。
原文链接:http://blog.csdn.net/eson_15/article/details/51749880 。
最后此篇关于SpringMVC中的拦截器详解及代码示例的文章就讲到这里了,如果你想了解更多关于SpringMVC中的拦截器详解及代码示例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!