1.78k likes | 2.22k Views
Struts2. MVC 模式 控制器 -FilterDispatcher 模型 -action 视图 -result. Struts2. 如何工作 拦截器 : 拦截器在 action 前 / 后调用 完成特定工作 , 实现低耦合 . 值栈和 OGNL: 值栈存储数据中心 OGNL 访问这些数据. Struts2 配置方式 (xml 和元数据 ). Struts.xml: <action name="HelloWorldAction" class="..HelloWorldAction">
E N D
Struts2 MVC模式 控制器-FilterDispatcher 模型-action 视图-result 北京传智播客教育 www.itcast.cn
Struts2 如何工作 拦截器:拦截器在action前/后调用 完成特定工作,实现低耦合. 值栈和OGNL:值栈存储数据中心 OGNL访问这些数据 北京传智播客教育 www.itcast.cn
Struts2配置方式(xml和元数据) Struts.xml: <action name="HelloWorldAction" class="..HelloWorldAction"> <result>/index.jsp</result> </action> <action name="MyAction" > <result>/index.jsp</result> </action> 注解: @Results({ @Result(name="input", value="/RegistrationSuccess.jsp" ) @Result(value="/RegistrationSuccess.jsp" ) }) public class LoginAction implements Action { public String execute() { //Business logic for login } } 北京传智播客教育 www.itcast.cn
Struts2配置方式(默认值以及模块化) 许多属性不需要显式设置,他们都有合理的默认值. 这些默认值基本上都定义在struts-default.xml/default.properties文档中. <struts> <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> <action name="Menu"> <result>/menu/Menu.jsp</result> </action> </package> <include file="manning/chapterTwo/chapterTwo.xml"/> <include file="manning/chapterThree/chapterThree.xml"/> </struts> 北京传智播客教育 www.itcast.cn
Struts2配置(web.xml) 注:struts2.1.3以后推荐使用org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter Init():进行初始化。 北京传智播客教育 www.itcast.cn
Struts2(url) 在struts1中,通过<action path="/test/helloworld">节点的path属性指定访问该action 的URL路径。 在struts2中,URL路径由两部份组成:包的命名空间+action的名称,例如 http://localhost:port/项目名称/test/helloworld.action <package name="itcast" namespace="/test" extends="struts-default"> <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute" > <result name="success">/WEB-INF/page/hello.jsp</result> </action> </package> 北京传智播客教育 www.itcast.cn
Struts2(hello world) struts.xml <struts> <package name="HelloWorldPkg" namespace="/HelloWorld" extends="struts-default"> <default-action-ref="HelloWorldAction" /> <default-action-class="...HelloWorldAction" /> <action name="NoClassAction"> <result>/helloworld/helloworld.jsp</result> </action> <action name="HelloWorldAction" class="..HelloWorldAction"> <result name="success">/helloWorld.jsp</result> </action> </package> </struts> 注:http//localhost:8085/struts2/aaa/bbb/HelloWorldAction.action ? 北京传智播客教育 www.itcast.cn
Struts2(hello world) index.jsp <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title>helloWorld.jsp</title> </head> <body> <h4>Enter your name </h4> <s:form action="HelloWorldAction"> <s:textfield name="name" label="username"/> <s:submit/> </s:form> </body> </html> 北京传智播客教育 www.itcast.cn
Struts2(hello world) HelloWorldAction.java package cn.itcast.struts2.action; public class HelloWorldAction { private static final String GREETING = "Hello "; public String execute() { setCustomGreeting( GREETING + getName() ); return "SUCCESS"; } private String name; get/set private String customGreeting; get/set } 北京传智播客教育 www.itcast.cn
Struts2(hello world) helloWorld.jsp <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title>HelloWorld</title> </head> <body> <h3>Custom Greeting Page</h3> <h4><s:property value="customGreeting"/></h4> </body> </html> 北京传智播客教育 www.itcast.cn
Struts2(hello world) 执行示意图: 北京传智播客教育 www.itcast.cn
Struts2(hello world-使用注解) web.xml <filter> <filter-name>struts2</filter-name> <filter-class>...FilterDispatcher</filter-class><!-- 不推荐使用 --> <filter-class>...StrutsPrepareAndExecuteFilter</filter-class> <init-param> <param-name>actionPackages</param-name> <param-value>manning</param-value> </init-param> </filter> AnnotatedNameCollector.java @Result( value="/chapterTwo/AnnotatedNameCollector.jsp" ) public class AnnotatedNameCollector extends ActionSupport { /* EMPTY */ } 北京传智播客教育 www.itcast.cn
Struts2(操纵action) Aciton封装了工作单元并提供了数据传输中心 //工作单元 public string execute(){ … } //数据传输中心 Public string name ;//get/set Public string greetingName ; //get/set 该应用中name参数被从表单转移到action的name属性(按照名称匹配的原则).除此以外action还 要把javabean属性暴露给结果. 在struts1中,每个action只有一个实例.如果struts2也是如此的话,我们就不能用action来携带 请求数据了,因为在多线程的情况下这是有问题的.struts2解决这一问题的办法是每次实例化新的 action实例.这也是和struts1不同的地方. 北京传智播客教育 www.itcast.cn
Struts2(操纵action) Aciton的方法返回控制串用于结果路由 Struts1如何处理的? 返回的控制串表明哪个结果要被渲染.而且消除了代码中对路由对象的依赖,使得代码更简洁,达到了 解耦的目的.这些路由串必须和xml文档中配置的结果相匹配. <action name="HelloWorld" class="manning.chapterOne.HelloWorld"> <result name="success">/chapterTwo/HelloWorld.jsp</result> <result name="error">/chapterTwo/Error.jsp</result> </action> <action name="HelloWorld2" class=".." method="view"> <result name="input">/chapterTwo/Error.jsp</result> </action> 注:开启动态方法调用.[struts.enable.DynamicMethodInvocation = true] http://.../struts/HelloWorldAction!view.action?... 北京传智播客教育 www.itcast.cn
Struts2(操纵action) 打包action Struts2中的包和java的包作用相当.逻辑上的容器,组织action和其他的组件.其中包的url中的 Namespace必须指定,而且包可以继承或抽象化. <package name="chapterThreeSecure" namespace="/chapterThree/secure" extends="struts-default"> <action name="AdminPortfolio" > <result>/chapterThree/AdminPortfolio.jsp</result> </action> <action name="AddImage" > <result>/chapterThree/ImageAdded.jsp</result> </action> <action name="RemoveImage" > <result>/chapterThree/ImageRemoved.jsp</result> </action> </package> url:http://localhost:8080/manningHelloWorld/chapterThree/ secure/AddImage.action 北京传智播客教育 www.itcast.cn
Struts2(使用struts-default下的组件) 只要扩展struts-default.xml,默认组件即可使用.默认拦截器栈即是 典型案例. <package name="struts-default"> <interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servlet-config"/> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="profiling"/> <interceptor-ref name="scoped-model-driven"/> <interceptor-ref name="model-driven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> 北京传智播客教育 www.itcast.cn
Struts2(使用struts-default下的组件) 只要扩展struts-default.xml,默认组件即可使用.默认拦截器栈即是 典型案例. <interceptor-ref name="params"> <param name="excludeParams">dojo\..*</param> </interceptor-ref> <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-stack> . . . <default-interceptor-ref name="defaultStack"/> . . . </package> 北京传智播客教育 www.itcast.cn
Struts2(使用struts-default下的组件) 只要扩展struts-default.xml,默认组件即可使用.默认拦截器栈即是 典型案例. 北京传智播客教育 www.itcast.cn
Struts2(实现action) 任何javabean都可以成为action,当action被执行时只要提供一个供框 架调用的入口方法即可. Struts2中的action不是必须实现action接口,只要含有execute()方法 并且返回控制串即可. 北京传智播客教育 www.itcast.cn
Struts2(实现action) 可选action接口 com.opensymphony.xwork2.Action 该接口提供了执行方法和常量串供开发方便调用. String execute() throws Exception public static final String ERROR="error" public static final String INPUT="input" public static final String LOGIN="login" public static final String NONE="none" public static final String SUCCESS="success" <action name="Name"> <result>/chapterOne/NameCollector.jsp</result> </action> 北京传智播客教育 www.itcast.cn
Struts2(实现action) actionSupport类 该类实现了action接口和其他的几个有用的接口,比如数据校验、错误消息本 地化等.继承该类后,这些功能便自动获得. 一、基本校验 Struts2框架提供了丰富的高度可配的验证框架,同时也提供了基本的验证方法.这些任务主要是 通过拦截器和接口实现.actionSupport实现了两个接口和默认栈中的一个拦截器配合使用. DefaultWorkflowInterceptor提供了基本的校验功能.若action使用了默认栈而且继承了该类, 则也具备了验证的功能. <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/> <interceptor-stack name="defaultStack">... <interceptor-ref name="params"/>... <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref>... </interceptor-stack name="defaultStack"> 北京传智播客教育 www.itcast.cn
Struts2(实现action) actionSupport类 一、基本校验(续) 该拦截器称为工作流拦截器是因为当验证错误发生时他会将请求的工作流转向导收入页面.注意 params拦截器在workflow之前,params拦截器把请求数据移动到action上,工作流拦截器再进行 校验,对于大多数的拦截器而言,顺序很重要.工作流拦截器启动时,首先寻找action中的validate() 方法来调用.该方法定义在com.opensymphony.xwork2.Validateable接口中.我们需要重写这 个方法的空实现.代码如下: public class RegisterAction extends ActionSupport { public String execute(){ ... return SUCCESS; } private String username;//get/set private String password;//get/set 北京传智播客教育 www.itcast.cn
Struts2(实现action) actionSupport类 一、基本校验(续) public void validate(){ PortfolioService ps = getPortfolioService(); if ( getPassword().length() == 0 ){ addFieldError( "password", "Password is required.") ); }... } public String validateToRegView(){...} 验证方法执行完,控制权返回到工作流拦截器,该方法没有返回值,秘密就在于校验生成的错误消息. 工作流拦截器会查看是否有错误消息生成,如果有的话,他会更改请求的工作流,终止请求处理并立即 返回到用户的输入表单页面.在页面上会显示错误消息. 问题:消息存哪里了?如何检查有错误消息生成? 北京传智播客教育 www.itcast.cn
Struts2(实现action) actionSupport类 一、基本校验(续) com.opensymphony.xwork2.ValidationAware接口定义了存储和检索错误消息的方法,方法 及错误消息集合都已由actionSupport实现,只需通过如下访问. addFieldError ( String fieldName, String errorMessage )---(1) addActionError ( String errorMessage )--------------------(2) 方法1必须指定一个字段名,方法2时添加一个action范围的错误消息,不需要指定太多东西. ValidationAware接口也定义了判断错误消息是否存在的方法,工作流拦截器会使用它们来决定 是否需要重定向工作流到input页面,若有错误发生,拦截器会寻找input结果. <action name="Register" class="manning.chapterThree.Register"> <result>/chapterThree/RegistrationSuccess.jsp</result> <result name="input">/chapterThree/Registration.jsp</result> </action> 至于错误消息如何显示在页面上,那是UI标签的事情,我们以后介绍. 北京传智播客教育 www.itcast.cn
Struts2(实现action) actionSupport类 二、为消息文本使用资源束 硬编码错误消息在action中不可想象的,好的方式是采用外部资源束文件. ActionSupport提供了两个接口实现该功能. com.opensymphony.xwork2.TextProvider提供了从资源束中提取消息的方法. ActionSupport类给出了实现.使用这些方法都需要指定key值,然后返回和该action关联的属性 文件中key所对应的消息. Register.properties: user.exists=This user already exists. username.required=Username is required. password.required=Password is required. portfolioName.required=Portfolio Name is required. 该文件需要Action放在一起. 然后即可通过getText()方法来访问消息了. addFieldError("username", getText( "user.exists")); 北京传智播客教育 www.itcast.cn
Struts2(实现action) actionSupport类 二、为消息文本使用资源束 ActionSupport为本地化消息文本也提供了国际化方案. com.opensymphony.xwork2.LocaleProvider接口暴露了getLocale()方法. ActionSupport实现了该接口检索用户设置在浏览器中的locale信息. ActionSupport的TextProvider实现每次接受到消息文本时,也会检查locale信息,他是通过调 用LocaleProvider接口的getLocale()方法,然后定位到 相应的属性文件. 北京传智播客教育 www.itcast.cn
Struts2(向对象传递数据) 我们可以暴露一个复杂的对象在action中,而不是定义基本的javabean属性.(struts1 form?) 有两种方案可以使用. 一、将javabean属性暴露成后台对象 每次手动收集数据信息再封装成domain对象是很繁琐的工作. Action中: Private User user ;//get/set Public String execute(){ getPortfolioService().createAccount( user ); } jsp中: <s:textfield name="user.username" label="Username"/> <h3>The <s:property value="user.portfolioName" /> Portfolio</h3> 北京传智播客教育 www.itcast.cn
Struts2(向对象传递数据) 二、ModelDriven Action 模型驱动action通过getModel()方法暴露domain对象,由com.opensymphony.xwork2. ModelDriven接口定义.这引入了另一个拦截器,该拦截器已经在默认栈中了.数据传输仍然是自动完 成的而且比以前更容易. ActionSupport没有实现该接口,需要我们单独实现,他只有一个方法-getModel(). public class ModelDrivenRegister extends ActionSupport implements ModelDriven { public String execute(){ getPortfolioService().createAccount( user ); return SUCCESS; } private User user = new User(); public Object getModel() { return user; } }} 北京传智播客教育 www.itcast.cn
Struts2(向对象传递数据) 二、ModelDriven Action private User user = new User(); 我们必须初始化model对象,需要注意的是在action的execute()方法调用之前,框架已经获得了 Model对象的引用,通过getModel()完成,而且框架至始至终引用的就是这同一个model对象,所以 如果在action中改变model对象的引用,会造成数据的不一致. 以下代码阐述了这个问题: public String execute(){ user = new User(); user.setSomething(); getPortfolioService().createAccount( user ); return SUCCESS; } private User user = new User(); public Object getModel() { return user; } <s:textfield name="username" label="Username"/> 北京传智播客教育 www.itcast.cn
Struts2(文件上传) 通过默认栈获得内置的上传支持. <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> <interceptor-stack name="defaultStack"> <interceptor-ref name="fileUpload"/> </interceptor-stack> <action name class> <interceptor-ref name="defaultStack"> <param name="fileUpload.allowedTypes">text/plain,... <param name="fileUpload.allowedExtensionTypes">.jpg,.jpeg </interceptor-ref> </action> 北京传智播客教育 www.itcast.cn
Struts2(文件上传) fileUpload拦截器运行机制: fileUpload拦截器在params拦截器之前,文件上传拦截器执行时,处理multipart request来 传输文件,他使用servlet request包装类完成这一工作. <s:file name="pic" label="Picture"/> Action: File pic; String picContentType; String picFileName; 若多个文件:File[]即可 北京传智播客教育 www.itcast.cn
Struts2(用拦截器添加工作流) 通过拦截器的分离关注,使得框架更加整洁.即每个拦截器负责特定的工作,而不是都交给 某个组件/action完成.拦截器从我们的action中删除了横切的任务,我们通常所说的预处理/后处 理等.action的调用是被分层处理的,在action执行前后包括一系列拦截栈的执行.action被最后执 行,选择相应的结果,结果执行后,拦截器以相反的顺序进行后处理工作. 有些时候,拦截器决定action不能执行.那么就需要拦截器本身返回控制串.workflow拦截器就是 典型的案例.他做了两件事,首先validation拦截器调用validate()方法,再判断是否存在错误消 息,若存在错误消息,他返回控制串阻止action的进一步执行,action将不会启动,下一个拦截器也不 会调用. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 拦截器实战 一、ActionInvocation 该类封装了和特定action相关联所有的处理细节. 框架接受请求->决定url映射到哪个action->action实例添加到新建的ActionInvoc ation对象中->框架询问xml启动哪个拦截器(以何顺序).除此以外,该对象还会持有对 重要信息的引用,比如Request对象和该action的Result Map. 二、拦截器如何启动 该类暴露的invoke方法供框架调用,来开始action的执行.,他负责追踪调用的执行步骤 并传递控制权给栈中相应的拦截器.主要通过调用拦截器的intercept()访方法来实现. 拦截启动顺序: 先从上到下执行->调用action->渲染页面->逆向调用拦截器(供后处理使用) 递归调用,维护状态(步骤) 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 4.2.1ActionInvocation(续) 拦截器启动时可以做如下工作: 三个步骤: 预处理 传递控制权(到拦截器/action/控制串) 后处理 public String intercept(ActionInvocation invocation) throws Exception { long startTime = System.currentTimeMillis(); String result = invocation.invoke(); long executionTime = System.currentTimeMillis() - startTime; ... log the time ... return result; } Invoke()方法返回后,页面已经被渲染,即已经打开. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 一、工具拦截器 Timer: 计时action执行 INFO: Executed action [/chapterFour/secure/ImageUpload!execute] took 123 ms. Logger: 预处理和退出后处理的日志记载. INFO: Starting execution stack for action /chapterFour/secure/ INFO: Finishing execution stack for action /chapterF 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 三、数据传输拦截器 Params拦截器: Static-params拦截器:移动静态参数到值栈属性中. <action name="exampleAction" class="example.ExampleAction"> <param name="firstName">John</param> <param name="lastName">Doe</param> </action> 注意顺序,他在参数后面,会有覆盖问题. AUTOWIRE拦截器: 整合spring 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 数据传输拦截器 SERVELET-CONFIG: ServletContextAware—Sets the ServletContext ServletRequestAware—Sets the HttpServletRequest ServletResponseAware—Sets the HttpServletResponse ParameterAware—Sets a map of the request parameters RequestAware—Sets a map of the request attributes SessionAware—Sets a map of the session attributes ApplicationAware—Sets a map of application scope properties PrincipalAware—Sets the Principal object (security) FILEUPLOAD:文件上传拦截器 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 WorkflowInterceptor public String intercept(ActionInvocation invocation) throws Exception { Action action = invocation.getAction(); if (action instanceof Validateable) { Validateable validateable = (Validateable) action; validateable.validate(); } if (action instanceof ValidationAware) { ValidationAware validationAwareAction = ValidationAware) action; if (validationAwareAction.hasErrors()) { return Action.INPUT; } } return invocation.invoke(); } 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 工作流拦截器 工作流拦截器携带以下几个参数: alwaysInvokeValidate:总是调用校验方法.true|false true inputResultName:输入结果名.校验失败后寻找结果的名称.默认为ACTION.INPUT. excludeMethods:不执行校验的方法(排外) <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 VALIDATION拦截器 不同于workflow拦截器使用硬编码方式进行校验,该拦截器是struts2框架的一部分,用于验证框架. 也会使用ValidationAware方法存放错误信息,工作流验证错误消息时,并不知道消息由谁创建.这 不是什么问题,主要是验证拦截器先于工作流拦截器之前启动. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 Prepare拦截器 调用action的prepare()方法[需要实现Preparable接口],在调用某些方法之前,执行某些准备工 作.还可为不同方法指定不同的预备方法.但prepare()方法始终都要执行.而且还可以关闭该拦截器 通过传递参数给该拦截器alwaysInvokePrepare – 默认值为true. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 ModelDriven拦截器 模型驱动拦截器通过调用getModel()方法将model对象放置到valueStack顶端,用来接受请求 中的参数.该拦截器改变了工作流,不然params拦截器会将请求参数直接传递到action中. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 各种拦截器 Exception 捕获异常并按类型映射他们到指定的错误页面,它位于栈顶以确保可以捕获到任何错误 面. <global-results> <result name="error">/chapterFour/Error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error"/> </global-exception-mappings> 异常发生时,该拦截器会创建ExceptionHolder对象并放置到栈顶.该类是对栈 跟踪信息的异常包装.并作为javabean属性可通过标签访问. Exception Name: <s:property value="exception" /> What you did wrong:<s:property value="exceptionStack" /> 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 Tocken和Tocken-session 避免重复提交.tocken拦截器通过请求传递令牌值给拦截器,如果值重复出现则说明重复提交了. 两者不同之处是是否有更多的处理方式. Scoped-ModelDriven 该拦截器支持跨越多个请求的向导方式的持久化处理. ExeAndWait 请求耗时执行,给个页面作为反馈.防止用户变得焦躁. <interceptor name="execAndWait" /> <result name="wait">/xxx.jsp</result> <meta http-equiv="refresh" content="2;url=<s:url/>"/> 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 考察内置拦截器 内置栈 除了默认栈以外,还有很多其它的栈可供使用. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 声明拦截器 Xml方式支持拦截器声明,注解方式目前还不支持. 声明单独的拦截器和拦截器栈 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 声明拦截器 映射拦截器到action <action name="MyAction" class="org.actions.myactions.MyAction"> <interceptor-ref name="timer"/> <interceptor-ref name="logger"/> <result>Success.jsp</result> </action> 以上设置是不包含默认拦截器栈的,因此功能有限. <action name="MyAction" class="org.actions.myactions.MyAction"> <interceptor-ref name="timer"/> <interceptor-ref name="logger"/> <interceptor-ref name="defaultStack"/> <result>Success.jsp</result> </action> 可以改变默认拦截器栈的设置: <default-interceptor-ref name="defaultStack"/> 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 声明拦截器 设置/重载参数 <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <action name="YourAction" class="org.actions.youractions.YourAction"> <interceptor-ref name="defaultStack"> <param name="validation.excludeMethods">doSomething</param> </interceptor-ref> <result>Success.jsp</result> </action> 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 构建自己的拦截器 实现拦截器接口 com.opensymphony.xwork2.interceptor.Interceptor public interface Interceptor extends Serializable { void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; } 前两个是生命周期方法. 如果你希望拦截器支持参数话类型(比如校验不包含某些方法),你可以继承一个该接口实现类. com.opensymphony.xwork2.interceptor.MethodFilterInterceptor. 北京传智播客教育 www.itcast.cn
Struts2 (用拦截器添加工作流) 构建自己的拦截器 创建登录拦截器 public class Login extends ActionSupport implements SessionAware { public String execute(){ User user = getPortfolioService().authenticateUser( getUsername(), getPassword() ); if ( user == null ){ return INPUT; } else{ session.put( Struts2PortfolioConstants.USER, user ); } return SUCCESS; } public void setSession(Map session) { this.session = session; }} 北京传智播客教育 www.itcast.cn