沈阳电脑维修上门服务13889116605: 在实际项目中我们的方法都是需要验证登录状态的,所以在使用Struts2框架的项目中,自定义拦截器是一个不错的选择,本文就简单介绍如何使用拦截器,对全局方法进行验证登录状态!第一步:搭建Str...
在实际项目中我们的方法都是需要验证登录状态的,所以在使用Struts2框架的项目中,自定义拦截器是一个不错的选择,本文就简单介绍如何使用拦截器,对全局方法进行验证登录状态!
第一步:搭建Struts2开发环境
第二步:编写一个Action方法
packagecsg.struts2.action;
/**
*
*@author小夜的传说
*@2014-4-18
*@struts
*@csg.struts2.action
*@StrutsAction
*@2014-4-18上午1:03:37
*/
publicclassStrutsAction{
privateStringmessage;
publicStringgetMessage(){
returnmessage;
}
publicvoidsetMessage(Stringmessage){
this.message=message;
}
publicStringexecute(){
message="execute方法";
return"success";
}
publicStringaddUI(){
message="addUI方法";
return"success";
}
}
第三步:写一个jsp视图模仿登录状态,只要访问这个jsp了,就把用户信息放在Session中代表已经登录,可以操作action方法,没有访问这个jsp代表没有登录,不可以操作任何方法
<%@pagelanguage="java"import="java.util.*"pageEncoding="utf-8"%>
<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<html>
<head>
<title>拦截器</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
</head>
<body>
<%
request.getSession().setAttribute("user","login");
%>
用户已登录
</body>
</html>
第四步:配置struts.xml文件,先测试方法
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<packagename="struts2"namespace="/test"extends="struts-default">
<!--通配符形式访问action-->
<actionname="list_*"class="csg.struts2.action.StrutsAction"method="{1}">
<resultname="success">/WEB-INF/page/success.jsp</result>
</action>
</package>
</struts>
第五步:部署到服务器上直接访问:http://127.0.0.1:8080/struts/test/list_addUI.action
会打印出addUI方法!ok,下面就是写一个拦截器了!
第六步:编写登录拦截器
packagecsg.struts2.interceptor;
importcom.opensymphony.xwork2.ActionContext;
importcom.opensymphony.xwork2.ActionInvocation;
importcom.opensymphony.xwork2.interceptor.Interceptor;
/**
*
*@author小夜的传说
*@2014-4-18
*@struts
*@csg.struts2.interceptor
*@LoginInterceptor
*@2014-4-18上午1:03:29
*/
publicclassLoginInterceptorimplementsInterceptor{
//方法在拦截器被垃圾回收之前调用,用来回收init方法初始化的资源
publicvoiddestroy(){
}
//方法在拦截器被创建之后,在对Action镜像拦截之前调用,使用这个方法主要是给拦截器做类似初始化的操作
publicvoidinit(){
}
publicStringintercept(ActionInvocationinvocation)throwsException{
Objectuser=ActionContext.getContext().getSession().get("user");
if(user!=null){
//如果user不为null,代表用户已经登录,允许执行action中的方法这个结果就代表返回验证通过
returninvocation.invoke();
}else{
//提示用户登录,我这里直接提示,在实际项目中,肯定会返回到登录页面
ActionContext.getContext().put("message","你没有登录");
return"success";
}
}
}
第七步:最重要的,我们要在写好的struts.xml文件中,配置我们写好的这个拦截器,这一步,我会写的很详细,看懂的童鞋,拦截器基本上可以很好掌握了!
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<packagename="struts2"namespace="/test"extends="struts-default">
<interceptors>
<interceptorname="logininterceptor"class="csg.struts2.interceptor.LoginInterceptor"/>
<!--自定义一个拦截器栈,下面你拦截只需要用这个栈名字就行了-->
<interceptor-stackname="loginstack">
<!--这个是系统拦截器栈,不这样写,就是当你单独一个action引用拦截器的时候就无法使用拦截器的中的核心功能-->
<interceptor-refname="defaultStack"/>
<!--这个引用你自己写的拦截器-->
<interceptor-refname="logininterceptor"/>
</interceptor-stack>
</interceptors>
<!--这样写的意思是在这个package包下面的所有action方法都需要拦截器-->
<default-interceptor-refname="loginstack"></default-interceptor-ref>
<!--全局视图,这个就是说拦截到你没登录的时候提示你登录,你做的话可以提示返回登录界面-->
<global-results>
<resultname="success">/WEB-INF/page/message.jsp</result>
</global-results>
<!--通配符形式访问action-->
<actionname="list_*"class="csg.struts2.action.StrutsAction"method="{1}">
<resultname="success">/WEB-INF/page/success.jsp</result>
<!--也可以这样写,但是这样写就比较麻烦了,假如你下面还有action,这样你就每个action都需要引用,所以我注掉了-->
<!--<interceptor-refname="loginstack"></interceptor-ref>-->
</action>
</package>
</struts>
第八步:解析
1、为什么<interceptor-refname="defaultStack"/>
因为Struts2拦截器是个很奇诡的东西,当你自定义拦截器之后,在某个方法引用自己编写的拦截器之后,那么Struts许多的核心拦截器将无法使用,所以我们我们一般将自己写的拦截器和这个系统拦截器栈一起组成一个栈,这样就可以继续使用Struts2的拦截器了
可以参照struts源代码,在struts2-core-2.3.16.1.jar下面有个struts-default.xml文件,搜索defaultStack
如图:
2、配置全局拦截器的优缺点<default-interceptor-refname="loginstack"></default-interceptor-ref>
假如,你某一个action方法需要另一个拦截器,但是其他方法不需要,这样你就需要在这个action中单独引用,注意,当你引用了这个拦截器之后,你定义的这个全局拦截器对于这个方法就会失效,所以一定要再次引用一次这个全局拦截器
3、为什么系统拦截器栈写在你定义的拦截器之前
<!--这个是系统拦截器栈,不这样写,就是当你单独一个action引用拦截器的时候就无法使用拦截器的中的核心功能-->
<interceptor-refname="defaultStack"/>
<!--这个引用你自己写的拦截器-->
<interceptor-refname="logininterceptor"/>
因为Struts在实例化的过程中读取的xml是从上到下的这样方式,所以本着项目安全角度,我们先让系统执行Struts2核心拦截器,然后再执行自己写的拦截器。当然你反过来写也行,但是可能有些自己写的复杂的拦截器在系统拦截器没实例化之前,会失效。
4、本文详细对于Struts2拦截器的基本原理进行了简单解析,如果有哪位童鞋有意见,欢迎举手!Thankyou!
上一篇:DDoS攻防战(三):ip黑白名单防火墙frdev的原理与实现