TMaize Blog

Struts2学习-05 拦截器 自带的标签库

拦截器

  1. struts2 是框架,封装了很多功能,里面封装的功能都是在拦截器里面

  2. 有很多的拦截器,不是所有的都执行,每次执行默认的拦截器

  3. 执行时间,Action对象创建之后,Action方法执行之前执行

  4. struts2 默认拦截器的位置

    struts核心包里面的struts-default.xml定义了默认的拦截器

     <interceptors>
             <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
             <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
             <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
             <!-- ............ -->
             <interceptor-stack name="defaultStack">
                 <interceptor-ref name="exception"/>
                 <interceptor-ref name="alias"/>
                 <interceptor-ref name="servletConfig"/>
                 <interceptor-ref name="i18n"/>
                 <interceptor-ref name="prepare"/>
                 <interceptor-ref name="chain"/>
                 <interceptor-ref name="scopedModelDriven"/>
                 <interceptor-ref name="modelDriven"/>
                 <interceptor-ref name="fileUpload"/>
                 <interceptor-ref name="checkbox"/>
                 <interceptor-ref name="datetime"/>
                 <interceptor-ref name="multiselect"/>
                 <interceptor-ref name="staticParams"/>
                 <interceptor-ref name="actionMappingParams"/>
                 <interceptor-ref name="params"/>
                 <interceptor-ref name="conversionError"/>
                 <interceptor-ref name="validation">
                     <param name="excludeMethods">input,back,cancel,browse</param>
                 </interceptor-ref>
                 <interceptor-ref name="workflow">
                     <param name="excludeMethods">input,back,cancel,browse</param>
                 </interceptor-ref>
                 <interceptor-ref name="debugging"/>
             </interceptor-stack>
             <!-- ............ -->
     </interceptors>
     <!-- ............ -->
     <default-interceptor-ref name="defaultStack"/>
    

    拦截器原理及执行步骤

  5. AOP思想:面向切面编程,不修改源代码来拓展功能

  6. 责任链模式

  7. 步骤

      //执行Action
      execute.executeAction(request,responsemap)
    
      ...
      //使用动态代理创建Action
      ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);
     ...
     proxy.execute();
    
     //执行很多的拦截器
     if (interceptors.hasNext()) {
         ...
     }
    
     //放行
     return invocation.invoke();
    

过滤器和拦截器的区别

过滤器:理论上可以过滤任意内容,比如 html、jsp、servlet、图片路径

拦截器:只可以拦截Action

自定义拦截器

struts里面的拦截器不能满足需求时,可通过自定义拦截器来实现

  1. extends AbstractInterceptor

    AbstractInterceptor 实现了Interceptor接口

    有init,destroy,intercept方法,intercept被AbstractInterceptor复写为抽象的,必须要实现 其他两个用哪个就复写哪个

  2. extends MethodFilterInterceptor

    在开发中一般使用这个,因为它可以定义Action中的那些方法不要拦截

    其实第一种方式也可以实现,不过要用反射

实现自定义拦截器

  1. 自定义拦截器

     public class LoginInterceptot extends MethodFilterInterceptor {
    
         @Override
         protected String doIntercept(ActionInvocation invocation) throws Exception {
                
             boolean flag = false;
                
             //invocation.getStack()
             //invocation.getInvocationContext().getParameters()
             HttpServletRequest request= (HttpServletRequest)invocation.getInvocationContext().get(StrutsStatics.HTTP_REQUEST);
             HttpServletRequest req = ServletActionContext.getRequest();
                
             //String key = req.getParameter("key");
                
             .....
    
             if (flag) {
                 //放行    
                 return invocation.invoke();
             }else{
                 //到action的配置中很据结果找页面
                 return "login";
             }
                
         }
     }
    
  2. 配置与Action的关联

    在package标签里面声明拦截器

    在具体的action标签里面声明要使用的拦截器

    注意:如果在action中定义了拦截器,那么系统默认的拦截器将不会执行,所以要做下面的配置

     <package name="testdemo" extends="struts-default" namespace="/">
         <interceptors>
             <interceptor name="checklogin" class="com.day01.LoginInterceptot"></interceptor>
             <interceptor-stack name="mydefault">
                 <interceptor-ref name="checklogin" >
                     <!-- 配置不拦截的方法 -->
                     <param name="excludeMethods">login,other</param>
                 </interceptor-ref>
                 <!-- 加上默认的拦截器 -->
                 <interceptor-ref name="defaultStack" />	
             </interceptor-stack>
         </interceptors>
         <action name="test" class="com.day01.Test">
             <result name="success">/WEB-INF/test.jsp</result>
         </action>
         <action name="login" class="com.day01.Login">
             <result name="success">/WEB-INF/login.jsp</result>
             <!-- 使用拦截器 -->
             <interceptor-ref name="mydefault" />
         </action>
     </package>
    

标签库

使用需要在jsp中引入标签库<%@ taglib uri="/struts-tags" prefix="s"%>

常用标签

property:和ognl配合在jsp中显示值栈中的数据

iterator:获取值栈list集合数据

debug:查看值栈结构和数据

a:超链接

if:if...

表单标签

见下面的使用例子

<%-- 指定修饰的样式,默认是表格<s:form theme="simple"> --%>
<%-- 默认时提交到当前页面 --%>
<s:form>
	<s:textfield name="name" label="userName"></s:textfield>
	<s:password name="password" label="pasword"></s:password>
	
	<s:radio list="#{'man':'男','woman':'女'}" name="sex" label="性别"></s:radio>
	
	<s:radio list="{'V1','V2'}" name="other" label="其他"></s:radio>
	
	<s:checkboxlist list="{'吃饭','睡觉','打豆豆'}" name="love" label="爱好"></s:checkboxlist>
	
	<s:select list="{1995,1996,1997}" name="year" label="年份"></s:select>
	
	<s:file name="file" label="文件上传"></s:file>
	
	<s:hidden name="hidden" value="123"></s:hidden>
	
	<s:reset value="重置"></s:reset>
	
	<s:submit value="提交"></s:submit>
</s:form>

显示效果:

p1

转换后的html

<form id="test" name="test" action="/day01/test.action" method="post">
	<table class="wwFormTable">
		<tbody>
			<tr>
				<td class="tdLabel"><label for="test_name" class="label">userName:</label></td>
				<td class="tdInput"><input type="text" name="name" value="" id="test_name"></td>
			</tr>
			<tr>
				<td class="tdLabel"><label for="test_password" class="label">pasword:</label></td>
				<td class="tdInput"><input type="password" name="password" id="test_password"></td>
			</tr>
			<tr>
				<td class="tdLabel"><label for="test_sex" class="label">性别:</label></td>
				<td class="tdInput">
					<input type="radio" name="sex" id="test_sexman" value="man"><label for="test_sexman"></label>
					<input type="radio" name="sex" id="test_sexwoman" value="woman"><label for="test_sexwoman"></label>
				</td>
			</tr>
			<tr>
				<td class="tdLabel"><label for="test_other" class="label">其他:</label></td>
				<td class="tdInput">
					<input type="radio" name="other" id="test_otherV1" value="V1"><label for="test_otherV1">V1</label>
					<input type="radio" name="other" id="test_otherV2" value="V2"><label for="test_otherV2">V2</label>
				</td>
			</tr>
			<tr>
				<td class="tdLabel"><label for="test_love" class="label">爱好:</label></td>
				<td class="tdInput">
					<input type="checkbox" name="love" value="吃饭" id="test_love-1"> <label for="test_love-1" class="checkboxLabel">吃饭</label>
					<input type="checkbox" name="love" value="睡觉" id="test_love-2"> <label for="test_love-2" class="checkboxLabel">睡觉</label>
					<input type="checkbox" name="love" value="打豆豆" id="test_love-3"> <label for="test_love-3" class="checkboxLabel">打豆豆</label>
					<input type="hidden" id="__multiselect_test_love" name="__multiselect_love" value="">
				</td>
			</tr>
			<tr>
				<td class="tdLabel"><label for="test_year" class="label">年份:</label></td>
				<td class="tdInput">
					<select name="year" id="test_year">
						<option value="1995">1995</option>
						<option value="1996">1996</option>
						<option value="1997">1997</option>
					</select>
				</td>
			</tr>
			<tr>
				<td class="tdLabel"><label for="test_file" class="label">文件上传:</label></td>
				<td class="tdInput"><input type="file" name="file" value="" id="test_file"></td>
			</tr>
			<tr style="display: none;">
				<td colspan="2"><input type="hidden" name="hidden" value="123" id="test_hidden"></td>
			</tr>
			<tr>
				<td colspan="2"><div class="formButton"><input type="reset" value="重置"></div></td>
			</tr>
			<tr>
				<td colspan="2"><div class="formButton"> <input type="submit" value="提交" id="test_2"> </div></td>
			</tr>
		</tbody>
	</table>
</form>