Struts2的拦截器

1 需求概述

		在CRM系统中,有用户登录功能,如果访问者知道后台的访问页面路径,
		可以没有登录直接进入CRM系统,所以要对没有登录的用户要进行拦截。

2 拦截器

(1)概述
	* 在AOP(aspect-oriented progaramming)面向切面编程中
	  用于在访问某个方法和字段之前 进行拦截操作。
	 * 拦截是AOP的一种实现策略。
	 * 在Struts2的WebWork的中文文档解释拦截器为 动态拦截Action调用的对象。
(2)拦截器在strust2的作用
	* 执行Action前进行拦截处理操作
	* 执行Action前阻止其执行
	* Action纵向重复代码横向抽取
(3)拦截器链(Interceptor Chain)
	它在Struts2称为拦截器栈(Interceptor Stack)。
	拦截器链就是将拦截器按一定顺序结成一条链,拦截器链中的拦截器按顺序逐个被调用。
(4)拦截器的实现原理
	大部分,拦截器方法都是通过代理方式调用的,Struts2拦截器的实现过程为:
	当请求到达Struts2的ServletDispatcher时,Struts2根据Strut2.xml配置文件中的拦截器配置,
	实例化成一个个拦截器对象,串成一个列表,最后一个个调用列表中的拦截器。
	拦截器是AOP的一种实现,它可插拔。Struts2的拦截器栈将拦截器按顺序连成链,按顺序被调用。
(5)自定义拦截器类
	(拦截器的生命周期:随项目的启动而创建,随项目的关闭而销毁)
	<1>方式一:实现接口Interceptor,需实现相应的方法
		public class MyInterceptor implements Interceptor{
			//销毁
			@Override
			public void destroy() {
				System.out.println("myInterceptor销毁");
				
			}
			//创建
			@Override
			public void init() {
				System.out.println("myInterceptor初始化");
			}
			//拦截方法
			@Override
			public String intercept(ActionInvocation arg0) throws Exception {
				System.out.println("myInterceptor拦截处理代码.....");
				return null;
			}
		}
	<2>方式二:通过继承一个抽象类AbstractInterceptor
			 * 其内部源码帮我们实现了 Intercepter接口,并实现了inint()和destroy()方法
			 * 使我们不需要实现这两个方法就可以使用 intercept()方法
			public class MyInterceptor2 extends AbstractInterceptor{
				@Override
				public String intercept(ActionInvocation arg0) throws Exception {
					System.out.println("interceptor2拦截处理");
					return null;
				}
			}
	<3>方式三:继承  MethoFilterInterceptor类
		   主要功能为:定制拦截器的拦截方法 --定制哪些方法需要拦截和不需要拦截
			public class MyInterceptor3 extends MethodFilterInterceptor{
				@Override
				protected String doIntercept(ActionInvocation invocation) throws Exception {
					//过滤器的前处理代码
					System.out.println("MyInterceptor3的前处理代码");
					
					/*放行--如果执行 此  放行方法    则代表要一直把所有的拦截器都递归完然后
					 *才返回到 Action中的 result结果,如果不执行此 方法,则直接返回到Action中的result结果(进行结果处理)
					 */
					invocation.invoke();
					
					//过滤器的后处理代码
					System.out.println("MyInterceptor3的后处理代码");
					return null;
				}
			}
(6)配置过滤器
		<1>精简版示例
			步骤一:自定义操作
				<interceptors>
							<!--自定义拦截器  -->
							<interceptor name="myInterceptor" class=""></interceptor>
							
							<!--创建自定义拦截器栈和 将自定义拦截器放进栈中 -->
							<interceptor-stack name="myInterceptorStack">
							
								<interceptor-ref name="myInterceptor">
									<param name="includeMethods"></param>
									<param name="excludeMethods"></param>
								</interceptor-ref>
								
								<!--引用默认拦截器栈的20个拦截器-->
								<interceptor-ref name="defaultStack"></interceptor-ref>
								
							</interceptor-stack>
				</interceptors>
			步骤二:为struts.xml的<package>指定  自定义拦截器栈  作为默认拦截器栈
					<default-interceptor-ref name="myStack"></default-interceptor-ref>
			步骤三:为action指定 自定义拦截器栈
					<action>
						<interceptor-ref name="myStack"></interceptor-ref>
					</action>
	<2>详细版示例
		<!--自定义拦截器的配置-->
		<interceptors>
			<!--1 注册拦截器-->
			<interceptor name="myinterceptor3" class="cnxxxa.interceptor.MyInterceptor3"></interceptor>
			<!--2 注册拦截器栈和将自定义拦截器放进该栈中-->
			<interceptor-stack name="myStack">
				<!--自定义拦截器的拦截器栈的引入建议放在默认20拦截器栈的前面
					因为如果自定义拦截器存在错误信息,后面的拦截器会帮忙处理-->
				<interceptor-ref name="myinterceptor3">
					<!--指定哪些方法不拦截-->
					 <!-- <param name="excludeMethods">add,delete</param> -->
					 <!--指定哪些方法需要拦截,两者只能取其一进行配置-->
					 <param name="includeMethods">add,delete</param>
				</interceptor-ref>
				<!--引用默认的20个拦截器栈-->
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		 
		<!--3 指定包中默认拦截器栈为自定义过的拦截器栈 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
		
		<!--4 为action单独指定哪个拦截器(栈),此拦截器只作用于此 action中
				此刻action中拥有21个拦截器。(自定义1个+默认的20个)	-->
		<action name="Demo1Action_*" class="cn.ixxx.interceptor.Demo1Action" method="{1}">
			<interceptor-ref name="myStack"></interceptor-ref>
			<result name="success">/show.jsp</result>
		</action>

Struts2的标签库

1 概述

	<1>早期的jsp开发嵌入大量的java脚本,不利于维护和阅读,struts2标签库语言应运而生。
	<2>Strust2标签库定义在struts2-core-2.3.24.jar/META-INF/struts-tags.tld的文件中。
	<3>使用struts2标签库,需在jsp使用taglib指令导入:
			<%@ taglib uri="/struts-tags" prefix="s" %>

2 Struts2标签库分类(普通标签和UI标签)

(1)普通标签又包括 控制标签(Control Tags)和数据标签(Data Tags) <1>控制标签用来完成条件逻辑,循环逻辑的控制,以及集合的操作。 * 条件逻辑 <s:if test=""></s:if> <s:elseif test=""></s:elseif> <s:else></s:else> 示例: <s:if test="#list.size()==2"> list的长度为2 </s:if> <s:elseif test="#list.size()==1"> list的长度为1 </s:elseif> <s:else> lsit的长度不一不二 </s:else> * 循环逻辑 <s:iterator></s:iterator> 示例一:简单的集合元素迭代 <!--遍历方式一 var代表集合元素遍历的一个变量 --> <s:iterator value="#list" var="name"> <s:property value="name"/> </s:iterator> <hr/> <!--遍历方式二 var代表集合元素遍历的一个对象变量 --> <s:iterator value="#list" var="customer"> <s:property value="#customer.name"/> </s:iterator> 示例二:添加 step属性 后的迭代 <!--begin 迭代数组和集合的起始位置 end 迭代数组和集合的结束位置 step 每一次迭代索引的增量 --> <s:iterator begin="1" end="10" step="2"> aaaa </s:iterator> 示例三:添加status属性的迭代 <s:iterator var="name" value="{'a','b','c','d','e'}" status="st"> 当前遍历的元素个数 :<s:property value="#st.count"/><br/> <s:if test="#st.last"> 集合最后一个元素:<s:property value="name"/><br/> </s:if> <s:if test="#st.first"> 集合第一个元素:<s:property value="name"/><br/> </s:if> ============================================<br/> 当前索引值:<s:property value="#st.index"/><br/> <s:if test="#st.odd"> 元素索引为奇数:<s:property value="name"/><br/> </s:if> <s:if test="#st.even"> 元素索引为偶数<s:property value="name"/> </s:if> <hr/> </s:iterator> <2>数据标签(用来输出后台数据和完成其他数据访问。) * <s:property >用于输出指定的值 该标签具有的属性: * id (可选) 指定元素的标识 * default(可选) 输出值为null时,显示default的属性值 * escape(可选) 指定是否忽略html代码 * value(可选) 指定输出属性值,若没有指定,则默认输出ValueStack栈顶的值 示例: 1. value属性不写,则默认输出值栈顶的值: <s:iterator value="#list" > <s:property /> </s:iterator> 2. default属性,输入默认值: <s:property value="" default="这里是flower默认值"/> 3. 忽略html代码: <s:property value="'<h3>www.flower.com</h3>'" escape="true"/> 4. 不忽略html代码: <s:property value="'<h3>www.flower.com</h3>'" escape="false"/> * <s:a>用于构造html页面的超链接,与html的<a>相似 具有以下属性: * id 指定其id * href 指定超链接地址 * action 指定跳转Action名 * namespace 指定跳转Action的命名空间 * method 指定跳转Action中的哪个方法 示例: <s:a href="xxx.com">xxx.com</s:a> <s:a action="flowerAction" namespace="/" method="list"></s:a> * <s:debug>用于调试,主要输入ValueStack和StackContext中的信息。 * <s:include> * <s:param>

(2)UI标签又包括 表单标签(Form Tags),非表单标签(None-Form Tags),Ajax标签 <1>表单标签用来生成html的表单元素 * struts2表单标签好处 好处1:内置了一套样式 好处2:它会根据栈中的值,自动回显标签的值,不需要像之前那样 value="${user.name} * theme属性:指定表单的主题 xhtml:默认 simple:没有主题 * 示例: <s:form action="DemoTag2Action" namespace="/" theme="xhtml"> <s:textfield name="name" label="用户名"></s:textfield> <s:password name="password" label="密码"></s:password> <s:radio list="{'男','女'}" name="gender" label="性别"></s:radio> <s:radio list="#{1:'男',0:'女'}" name="gendar" label="性别"></s:radio> <s:radio list="#{0:'打篮球',1:'游泳',2:'踢足球'}" name="habits" label="爱好"></s:radio> <s:select list="#{0:'大专',1:'本科',2:'硕士'}" headerKey="" headerValue="--请选择--" name="edu" label="学历"></s:select> <s:file name="photo" label="近照"></s:file> <s:textarea name="desc" label="个人简历"></s:textarea> <s:submit value="提交"></s:submit> </s:form> <!--接收并显示错误提示信息--> <s:actionerror/> <2>非表单标签用来生成html的<div>标签以及输出Action中封装的信息。 <3>Ajax标签提供ajax技术支持。

struts2知识点补漏

在struts.xml文件中配置 全局异常结果集处理

示例:
		<global-exception-mappings>
				<!--result="error"  关联 action中error的结果处理
					   exception=""  关联相应的异常类
				-->
				<exception-mapping result="error" exception="java.lang.RuntimeException"></exception-mapping>
		</global-exception-mappings>
		
		<action name="" class=""  method="">
			<result name="error" >xxx.jsp</result>
		</action>
		
		//jsp页面回显  错误提示信息
		<s:property value="exception.message"/>