一、interceptor拦截器
1、自定义拦截器
public class Cus_Emp_Interceptor implements Interceptor {
public String intercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
Customer customer = (Customer) ServletActionContext.getRequest().getSession().getAttribute("customer");
Employee employee = (Employee) ServletActionContext.getRequest().getSession().getAttribute("employee");
if(customer==null){
return "login";//对应配置文件的<result name="login"
}
return invocation.invoke();
}
}
2、声明拦截器
<package name="autoInterceptor" namespace="/" extends="struts-default">
<interceptors>
<!-- 1、声明拦截器 (可以多个)-->
<interceptor name="myInterceptor" class="struts2.interceptor.MyInterceptor">
<!-- 传递参数给action -->
<param name="aa">aaaa</param>
</interceptor>
<!-- 2、配置拦截器栈-->
<interceptor-stack name="mystack">
<!-- 先继承默认的拦截器栈,再实现自己的拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 3、配置默认的拦截器栈为自定义的-->
<default-interceptor-ref name="mystack"></default-interceptor-ref>
<action name="interceptorAction_*" method="{1}" class="struts2.interceptor.InterceptorAction">
<result name="login" type="redirectAction">customerAction_login.action</result>
</action>
</package>
struts2中的拦截器
*拦截器:继承Interceptor接口的一个类
*拦截器栈:多个拦截器的组合
*拦截器可以栈中有栈
*struts2容器中默认加载的就是整个栈
<default-interceptor-ref name="defaultStack"/>
*先执行拦截器后执行action,要执行action,拦截器必须返回:return invocation.invoke();
*在配置文件中,将声明中的参数传递到拦截器类中
*声明拦截器中有<param name="">...</param>
*则拦截器类中必须要对应属性,并且有set和get方法
*各拦截器按照声明顺序执行
*继承MethodFilterInterceptor
这个类叫做方法过滤拦截器,这个类继承自AbstractInterceptor,并且提供了一种机制,
即可以指定对Action中某些方法进行拦截或者是不拦截,所谓拦截不拦截,指的就是拦
截器中的intercept()方法是否被执行了,若没有执行,就是没有拦截,若执行了,就是拦截了。
- 拦截器类:
- package com.suo.interceptor;
- import com.opensymphony.xwork2.ActionInvocation;
- import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
- import com.suo.listeners.BeforeResultListener;
- public class MyInterceptor3 extends MethodFilterInterceptor {
- @Override
- protected String doIntercept(ActionInvocation invocation) throws Exception {
- System.out.println("before MyInterceptor3 invoke !");
- String result=invocation.invoke();
- System.out.println("after MyInterceptor3 invoke !");
- return result;
- }
- }
配置文件
- <action name="action1" class="com.suo.actions.Action1" method="myExecute">
- <result name="success" type="chain">
- <param name="actionName">action2</param>
- </result>
- <interceptor-ref name="myInterceptor3">
- <param name="includeMethods">myExecute</param>
- <param name="excludeMethods">execute</param><!--对myExecute进行拦截,对execute不拦截-->
- </interceptor-ref>
- </action>
二、struts2获取表单数据,有三种方法
1、较原始,也是较实用的方法
*action中声明属性对象(可以多个),并覆盖setter和getter
*前台不变,如果多个对象时,对象引用名.属性名
2、属性驱动ParamDriver
*在action中设置属性,属性的名称和页面表单中的name属性的名称保持一致
*在action中的属性,必须有set和get方法
*好处:这样设计可以保证action与servlet容器松耦合
原理:*action中的属性,运行的时候存在于对象栈中
*ParamInterceptor拦截器拦截到参数,通过ValueStack的setValue(key,value)方法
将值设置到对象栈中
3、模型驱动ModelDriver
*如果页面表单内容很多,action中就需要很多属性和set/get放,这样比较繁琐
*解决方法:采用javabean
*让action实现ModelDriver
*ModelDriverInterceptor拦截到该action,调用其getModel方法,将model属性的值放到栈顶
*利用ParameterInterceptor完成从页面到model的赋值
其中是利用valueStack.setValue方法给model对象中的属性赋值(还没找到该源代码)
三、token:struts2已经实现了token,防止表单重复提交的功能
而defaultStack拦截器栈中没有实现拦截器,所以要加入
1、struts文件中配置<!-- 防止表单重复提交-->
<package name="token" extends="struts-default">
<interceptors>
<interceptor-stack name="tokenStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="token">
<!--<param name="includeMethods">save,update</param>-->
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="tokenStack"></default-interceptor-ref>
</package>
2、对应action中结果集配置<result name="invalid.token">WEB-INF/common/error.jsp</result>
3、编写error.jsp页面
4、在jsp表单中,写上<s:token></s:token>
四、validate表单验证
步骤:
1、在页面中用<s:fielderror></s:fielderror>,该标签必须写在form中
2、在action中写上validate方法
public void validate(){
}
3、在配置文件中
<result name="input"></reuslt>
input是固定写法,且必须要写
在第二步中,可以这样写
public void validateXxx(){ //Xxx为当前请求action的方法
//写验证
}
五、文件上传
步骤:
1、在页面中需要加
<s:form enctype="multipart/form-data">
multipart/form-data表示页面以二进制流的形式上传文件
2、在UplodateAction中
有个属性为file,该属性的名称和页面上的相应的name属性名称要一致
3、该File属性必须有set和get方法
4、把上传的文件传到指定的目录中
文件下载
1、在页面中需要加
<s:form enctype="multipart/form-data">
multipart/form-data表示页面以二进制流的形式下载文件
2、配置结果集
<!-- 下载结果集 -->
<result name="download" type="stream">
<!--设置栈顶User对象中保存输入流的名称 -->
<param name="inputName">InputStreamxxx</param>
<!-- 配置响应头信息 -->
<param name="contentType">application/x-msdownload</param>
<param name="contentDisposition">attachment;filename="${filename}"</param>
<!-- 设置下载是缓存区的大小-->
<param name="bufferSize">1024</param>
</result>
六、类型转换:
原因:如果不做类型转换,action中的属性只能接受表单中一班数据(基本类型的数据)
如果有日期类型、例如:页面上有数据,在后台要用list来接受,
struts2默认就不支持,这时候需要类型转换
步骤:
1、在src下有一个配置文件xwork-convertion.properties
java.util.Date=cn.itcast.struts2.aciton.converter.DateCOnverter
key值代表转换后的类型,该类型在action中的属性中出现
value代表一个类,该类实现了转换的逻辑
2、写转化类 必须继承StrutsTypeConverter
public Object convertFromString(Map context.String[] values,Class toClass)
从表单转到action中
public String convertToString(Map context,
1、登陆用struts2的验证机制来做
2、添加防止表单重交
3、页面用struts2的ognl标签和UI标签
开发模式:走DebugInterceptor
token:谁用谁继承该配置
七、struts2统一错误处理
配置:需要写一个ErrorProcessor(将Exception放入栈顶)和error.jsp
<package name="struts-global-exception" extends="struts-default">
<global-results>
<result name="errHandler" type="chain">
<!--需要修改之处一-->
<param name="actionName">ErrorProcessor</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="errHandler" exception="java.lang.Exception">
</exception-mapping>
</global-exception-mappings>
<!--需要修改之处二->
<action name="ErrorProcessor" class="struts2.exception.ErrorProcessor">
<!--需要修改之处三-->
<result>WEB-INF/login/error.jsp</result>
</action>
</package>
第二种配置方法
1、struts.xml里面配置,并在对应的action中引用
<package name="error" extends="struts-default">
<global-results>
<result name="error">/WEB-INF/pages/process/commons/message.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
</package>
2、页面配置
<s:property value="exception.message"/>
附:上下文Context
1、ServletActionContext
建立Struts2与Servlet通信的借口
2、ActionContext
1、Action的上下文
2、可以根据AcgtionContext获取session,Appliction,ActionInvocation,ValueStack等跟action相关的内容
3、ActionInvocation
1、Struts2容器的上下文
2、必须通过其他方式产生,ActionContext.getActionInvocation
ObjectFactory与静态注入
1、ObjectFactory:对象工厂
struts2的action是需要产生对象
struts2中拦截器是需要创建的
struts2的各种结果集也需要创建对象
2、ObjectFactory中的各种方法
buildAction是用来创建interceptor
buildResult是用来创建结果集
静态注入:
静态:凡是在struts的xml文件中配置的bean,列如:
<bean type="com.opensmphony.xwork2.ObjectFactory" name="struts"
class="org.apache.struts2.impl.StrutsObjectFactory"/>
在服务器启动的时候就会加载,而且只加载一次,所以为静态
注入:StrutsObjectFactory就给纳入到struts2容器中,这样的现象为注入
应用:值栈的实现类也是通过静态注入改变的
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="struts"
class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory"/>