• 1. Struts2快速入门ganbin@talkweb.com.cn 版权所有,禁止翻改
  • 2. 内容介绍web分层应用 struts2概述 struts2与struts1区别 struts2体系结构及工作原理 怎样构建一个struts2应用 struts2核心配置文件struts.xml详解 struts2中Action的应用 struts2中通配符的使用 struts2中result的使用
  • 3. web的分层应用(MVC) 视图层(View) :与用户交互层,表现数据,收集数据。 控制层(control):接受视图层请求,通过处理层完成相应的响应。 模型层(model) :完成业务的处理,以及与数据库的交互。
  • 4. MVC框架的实现模型模型一:JSP+JavaBean JSP既充当控制,又充当视图,以页面为核心,JSP使用jsp:useBean,他不能够实现不同的页面,显示不同的数据,需要借助于中间类来调用JavaBean的方法才能实现。 模型二:JSP+Servlet+JavaBean 以控制为核心,JSP只负责收集和显示数据,sevlet,连接视图和模型,将视图层数据,发送给模型层,JavaBean,分为业务类和数据实体,业务类处理业务数据,数据实体承载数据,基本上大多数的项目都是使用这种MVC的实现模式。 注:在模式一中(jsp+javabean),这种设计模式适合,小规模web开发,体现在轻巧兴,也就是更轻量级一些(内存加载的类少,相对struts而言),但是jsp中会嵌入大量的html和java脚本,规模小还好,如果大型企业web,随着规模的加大,太多的html和java脚本交织在一起,可读性差,而且修改一个jsp可能会牵连到其他的页面。现在大规模的企业开发都选择模型二,因为他成功的吧web分为三层,即模型,视图,控制器,在开发团队中更容易分工,而且逻辑部分和显示部分被分离到,module和jsp中去了,可读性也好了。
  • 5. struts1的功能Struts提供了一个过滤器调度器ActionServlet作为控制器,程序员不必自行用servlet编写一个。 Struts使用了一个基于XML的配置文件来匹配URI和动作。因为XML文档是文本文件,所以对应用程序的许多改动都用不着重新编译有关代码即可生效。 对动作类进行实例化和提取用户输入去填充有关动作属性的工作都由Struts负责。而不用servlet一个个去取前台参数。 Struts可以在后台对用户输入做一些基本的合法性验证,并在遇到不合法的输入时自动地把用户重定向到相关的输入表单。 Struts负责调用动作方法,而程序员可以通过配置文件轻而易举地改变某个动作的方法,而不用修改代码。 Struts负责检查各个动作的结果和执行该结果。最常见的结果类型是Dispatcher,其含义是把控制权转交给一个JSP页面。 Struts还有一些其他的功能,比如用来显示数据的定制标签、数据转换、支持Ajax、支持国际化和本地化、可以通过插件对Struts进行扩展等等。
  • 6. 为什么要用strutsStruts是建立在MVC模式上的,Struts在M、V和C上都有涉及,但它主要是提供一个好的控制器和一套定制的标签库上,也就是说它的着力点在C和V上,因此,它天生就有MVC所带来的一系列优点,如:结构层次分明,高可重用性,增加了程序的健壮性和可伸缩性,便于开发与设计分工,提供集中统一的权限控制、校验、国际化、日志等等; Struts是个开源项目得到了包括它的发明者Craig R.McClanahan在内的一些程序大师和高手持续而细心的呵护,并且经受了实战的检验,使其功能越来越强大,体系也日渐完善; Struts对其他技术和框架显示出很好的融合性。
  • 7. StrutsMVC框架 Struts是使用MVC的实现模式二来实现的,也就是以控制器为核心。 Model:Struts没有提供model类。这个商业逻辑必须由Web应用程序的开 发者以JavaBean或EJB的形式提供。 View:Struts提供了action form创建form bean, 用于在controller和view间传输数据。此外,Struts提供了自定义JSP标签库,辅助开发者用JSP创建交互式的以表单为基础的应用程序,应用程序资源文件保留了一些文本常量和错误消息,可转变为其它语言,可用于JSP中。 Controller:Struts提供了一个核心的控制器ActionServlet,通过这个核心的控制器来调用其他用户注册了的自定义的控制器Action,自定义Action需要符合Struts的自定义Action规范,还需要在struts-config.xml的特定配置文件中进行配置,接收JSP输入字段形成Action form,然后调用一个Action控制器。Action控制器中提供了model的逻辑接口。
  • 8. 回顾历史 Struts框架的主要架构设计者和开发者是Craig R.McClanahan,他也是Tomcat 4的主要架构师,以及Java Web Services Developer Pack的主要架构师和实现者。他现在是Sun的JavaServer Faces(JSR-127)以及J2EE平台的Web层架构的规范领导。 Struts是Apache软件基金下Jakarta项目的一部分。除Struts之外,还有其他成功的开源产品,包括Tomcat, Ant 和Velocity。 2000年5月开始着手开发,直到2001年6月,Struts1.0版本发布 。 Struts1.0框架在以后几年中不断地完善和发展,先后经历了Struts 1.0、Struts 1.1、Struts 1.2 、Struts 1.3、Struts 2.0、 Struts 2.1等版本的变革。 2007年2月,Apache发布了Struts2的第一个稳定版本2.0.6。Struts2由Apache组织维护和推广。 WebWork出生名门:opensymehony 创始人:Rickard Oberg (JBoss和XDoclet的作者)。
  • 9. Struts2概述 Struts2是一个全新的基于MVC的Web编程框架。它的整体设计完全不同于Struts1。新的Struts2框架在很多方面采纳了Webwork的设计思想。事实上,Struts2是Struts和Webwork整合优化后的新一代的Web编程框架,具有如下的特点: 基于AOP的设计思路,将相关的内容集中到单独的软件层面中,这主要体现在Struts2的Interceptor的设计上。 Struts2的Action类不再依赖于Struts框架,任何的类都可作为Struts2的Action。 提供了大量的自带的Interceptor来实现许多系统级的服务,使开发者可以忽略很多Web编程处理中的细节,从而可以集中精力处理核心的业务问题。 提供了更为方便、独立的Spring的集成服务支持。 提供了更为方便、独立的Tiles的集成服务支持。
  • 10. Struts2概述提供了大量的缺省配置,这样可以大大简化基于Struts2开发 的配置工作量。 内置Web2.0 AJAX 特性。 内置validation服务。 提供了更为方便的文件上传支持。 提供对多种视图技术的支持及扩展。 提供了更为优雅的数据传递及访问模型。 Action类不再是单例,这样可以使开发者从复杂的多线程并发访问控制的编程中解脱出来。
  • 11. struts2与struts1的区别-a Action 类: • Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。 • Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。 线程模式: • Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。 • Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
  • 12. struts2与struts1的区别-bServlet 依赖: • Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。 • Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。 可测性: • 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。 • Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
  • 13. struts2与struts1的区别-c捕获输入: • Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。 • Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。
  • 14. struts2与struts1的区别-d表达式语言: • Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。 • Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL). 绑定值到页面(view): • Struts 1使用标准JSP机制把对象绑定到页面中来访问。 • Struts 2 使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
  • 15. struts2与struts1的区别-e类型转换: • Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。 • Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。 校验: • Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。 • Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。
  • 16. struts2与struts1的区别-fAction执行的控制: • Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。 • Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。
  • 17. Struts2的体系结构(Struts2的核心控制器FilterDispatcher) 拦截器1 拦截器2 拦截器3
  • 18. struts2的数据流图
  • 19. ActionContextCleanUp的作用延长action中属性的生命周期,包括自定义属性,以便在jsp页面中进行访 问,让actionContextcleanup过滤器来清除属性,不让action自己清除。 阅读一下FilterDispatcher的JavaDoc和源码,我们可以看到它调用了: finally { ActionContextCleanUp.cleanUp(req); } 在ActionContextCleanUp中,有这样的代码: req.setAttribute(CLEANUP_PRESENT, Boolean.TRUE); 如果FilterDispatcher检测到这个属性,就不会清除ActionContext中的内容了,而由ActionContextCleanUp后续的代码来清除,保证了一系列的Filter访问正确的ActionContext. 文档中提到,如果用到SiteMesh的Filter或者其他类似Filter,那么设置顺序是: ActionContextCleanUp filter SiteMesh filter FilterDispatcher
  • 20. Struts2核心构建元素RequestAction(M)ResponseFilterDispatcher(C)Result(V)ValueStack(Data Holder)ActionContextInterceptors (Services)OGNLOGNLInterceptors (Services)InvokeInvokeFinish
  • 21. Controller In Struts2 Struts2的控制器(Controller)是一个过滤器,所有的请求都需要经过该过滤器,其类型为:org.apache.struts2.dispatcher.FilterDispatcher,当FilterDispatcher接收到一个请求后,会根据相关的配置信息查找服务于该请求的interceptors、action类并自动创建它们的实例及调用它的方法服务于请求,它还会根据interceptors或action的执行结果来调用视图层组件Result来生成响应。FilterDispatcher过滤器必在应用的web.xml 中部署,并配置为过滤所有的请求,配置方法如下: filterDispatcher org.apache.struts2.dispatcher.FilterDispatcher filterDispatcher /*
  • 22. Model In Struts2Struts2中的模型(Model)包括action和interceptor。action是一个简单的POJO(JavaBean)对象,它不需要依赖于Struts2框架,因此独立性及复用性都很好,适合在该类中同业务(Biz)代码及数据访问(Dao)代码交互。action的开发是基于Struts2的项目的核心任务。Interceptor(拦截器)是一个遵守Struts2规范的一个对象,类似于Web编程中的Filter,控制层会在action方法执行之前以及之后执行interceptor中的代码。在实际开发中,最好将一些切面任务,比如:日志、安全、调试等代码放到interceptor中实现,然后通过配置的方式将interceptor和action在运行时关联到一起,从而使interceptor及action各为一层,这就是所谓AOP的设计思想。 为了加速基于Struts2的Web应用的开发,Struts2内置了很多常用的interceptor供开发者使用,这些interceptor提供的功能被称为Struts2的系统级服务。常用的服务包括:请求参数到action属性的绑定、参数校验、消息解析、文件上传处理等。开发者也可以根据需要编写自己的interceptor来实现项目级的服务代码。
  • 23. Model Configurations开发者必须为Struts2的Model对象提供配置信息以便当请求到来时控制器可以调用Model层的对象来处理请求。在Struts2中,这些配置信息可以在XML文件中指定,也可以在Action类源代码中指定(使用注释)。 XML配置 默认的XML配置文件的名字为struts.xml,该文件需要放置在Web应用的类路径下,即WebRoot/WEB-INF/classes目录下。 /welcome.jsp Welcome to the world of Struts 2 0.11
  • 24. Model ConfigurationsAnnotation配置 类似于XML的配置,开发者可以使用注释(annotation)在action类的源代码中指定等同于XML文件的配置信息,这样更便于配置信息的维护。 如果使用annotation来提供配置信息,部署者必须通知控制器哪些 action类包含这些配置信息,这可以通过FilterDispatcher的初始化参 数actionPackages来指定这些包含了annotation配置信息的action类所 在的包的列表(用逗号分隔)。package com.allanlxf.struts2.action.annotation; import org.apache.struts2.config.Result; import org.apache.struts2.config.Results; @Results(@Result("/welcome.jsp")) public class WelcomeAction { }
  • 25. Controller Using Annotations filterDispatcher org.apache.struts2.dispatcher.FilterDispatcher actionPackages com.talkweb.struts2.annotation filterDispatcher /*
  • 26. View In Struts2 Result作为Struts2中的视图(View)组件。Struts2支持多种视图技术,包括:JSP、Velocity、FreeMarker、XSLT等。更为重要的是该框架可以很容易地被扩展从而支持其它的视图技术。 Action执行完毕后,返回一个代表某个视图组件的逻辑名称,该名称同某个视图资源关联并由某个具体类型的Result对象来调用该视图资源,从而生成到客户端的响应。 当WelcomeAction的execute方法返回字符串”success”时,Struts2会通过ServletDispatcherResult来调用”/welcome.jsp”从而为客户做出响应。ActionResult /welcome.jsp Control String
  • 27. Data Transfer Between M&V在视图层(V)生成响应内容的过程中,经常需要访问模型层(M)中的数据,所以数据传递是开发中十分重要的内容。在早期的模型中,开发者大多会使用Servlet规范中规定的请求对象或会话对象的属性空间来实现数据的传递。 Struts2在设计上为开发者提供了更为方便数据传递模型,Struts2的数据传递是通过ActionContext、ValueStack以及OGNL实现的。ActionResultActionContextValue StackrequestsessionapplicationcontextMapInterceptorsOGNLOGNLOGNL
  • 28. Data Transfer Between M&VActionContext ActionContext是一个只在当前线程中可用的对象,即它存储在ThreadLocal中,它用来存放一些同当前的action密切相关的信息。使用它可以在所有服务于当前请求的对象之间共享信息。在interceptor,action,及result中均可访问该对象。 ValueStack ValueStack是一个精心设计的栈结构,在栈中可以存放程序运行过 程中产生的数据以便实现共享。更为重要的是可以使用EL对ValueStack中的对象进行赋值以及读取对象的信息。所有的EL操作都是针对最先找到的栈中的对象进行的,搜索顺序为从栈顶到栈底。 OGNL OGNL(Object Graphic Navigation Language)是一种表达式语言, 使用它可以动态地根据某个字符串的表达式对某个对象进行方法调用操作,而不需要知道该对象的具体类型。Struts2的ValueStack支持使用OGNL来动态操作栈中的对象。
  • 29. 构建基于Struts2的应用建立一个Java Web应用 Java Web应用是一个遵守了JavaEE Web应用规范的目录结构以及存放在该目录结构中的资源的集合。该目录结构如图所示:album-app为应用的根,默认情况下它 将作为本应用的虚拟访问路径。 WEB-INF是每个Java Web应用必须包含 的目录,该目录内的所有内容只有服务 器有权访问,不对客户端开放。WEB-INF下必须包含一个web.xml文件,该文件为本应用的部署描 述文件,应用中Listener、Filter以及Servlet都在该文件中部署。 classes文件夹为本Web应用的类路径,没有打包的类及文件都需 要放到该目录下。 lib目录下的所有jar文件都将自动添加到Web应用的类路径中。 WEB-INF目录外的应用内的其它目录及文件都对客户端开放。
  • 30. 构建基于Struts2的应用下载Struts2 可以从:http://struts.apache.org/download.cgi 下载Struts2的 最新版本。 在应用中安装Struts2及其相关的类库 将下载的压缩包解开,可以看到lib文件夹,将文件夹中下述jar文件拷贝到刚建立的Web应用的lib目录下: antlr-2.7.2.jar,commons-beanutils-1.6.jar,commons-chain-1.1.jar, commons-logging-1.0.4.jar,commons-logging-api-1.1.jar, commons-validator-1.3.0.jar,freemarker-2.3.8.jar,ognl-2.6.11.jar, oro-2.0.8.jar,struts2-core-2.0.11.1.jar,xwork-2.0.4.jar 其中,struts2-core-2.0.11.1.jar和xwork-2.0.4.jar包含了Struts2的核心 类文件,编译Struts2的action类时需要它们。其它的jar文件中的类只有在运行时才需要。 部署Struts2配置文件
  • 31. Struts2 Configuration Files Struts2是一个很灵活的框架,提供的很强的可配置性,考虑到以往的一些框架为了追求灵活性而导致程序员不得不编写大量的配置文件,给开发及维护带来了很大的不便。Struts2在启动的时候会读取它自己内置的配置文件来配置Struts2的缺省工作模式,开发者根据需要可以在应用级的配置文件中覆盖这些缺省配置。 构建基于Struts2的Web应用涉及的配置文件包括: web.xml (Required) struts-default.xml (System) default.properties (System) struts.xml (Application Specific) struts.properties (Application Specific) struts-default.vm (Velocity) velocity.properties (Velocity) struts-plugin.xml (Module Plugin)
  • 32. web.xml configureation Struts2的核心控制器FilterDispatcher必须在该文件中配置,在该文件中说明控制器的控制范围,通常为应用下的所有的请求。 FilterDispatcher是一个过滤器,它用来初始化Struts框架并负责调用于当前请求相关的Interceptors、Actions及Result。 可以为FilterDispatcher指定如下的初始化参数来通知控制器如何定位于控制相关的配置信息: config 指定用来配置Interceptors、Actions及Results的XML格式的配置文件的文件名,如果有多个可以用逗号分开,缺省为struts.xml actionPackages 指定包含了Annotation配置的Action类所以在的包,此时与Action相关的配置信息都包含到Action类的源代码中,如果有多个包可以用逗号将它们分开。
  • 33. Configure Struts2 Controller filterDispatcher org.apache.struts2.dispatcher.FilterDispatcher actionPackages com.allanlxf.struts2.annotation filterDispatcher /*
  • 34. Other Configuration Filesstruts-default.xml和default.properties 系统级别的配置文件,它们都存放在struts2-core-2.0.11.1.jar中,开发者不需要修改这两个文件。struts-default.xml配置了Struts2自带的Results、Interceptors、Interceptor stacks及struts-default包的配置信息,该配置文件的内容对所有的应用级别的配置文件,如struts.xml及其引用的文件是可见的。default.properties配置了Struts2框架的很多运行时的缺省配置参数,如文件上传配置参数、Action请求的扩展名、配置信息及资源的重载等。 struts.xml和struts.properties 应用级别的配置文件,需要将它们放置在应用的类路径的根目录下,即WEB-INF/classes目录下。struts.xml中配置应用内的Actions、Results、Interceptors等信息,在该配置文件中可以使用在struts-default.xml文件中配置的所有信息。struts.properties用来覆盖default.properties文件中的配置信息。另外一种覆盖default.properties的配置信息的方法是在struts.xml文件中使用元素。
  • 35. 构建基于Struts2的应用在classes文件夹下放置如下的struts.xml文件。 在classses文件夹下放置一个空的名字为struts.properties的文件。 struts.xml、struts.properties以及Action类、Interceptors类、其它辅助类Struts2核心类库、运行时所需的第三方类库、包含Action类、Interceptors类的库文件
  • 36. Greetings To Struts2 开发第一个基于Struts2的程序,此程序的功能是:向访问者输出一句问候的话语,并告知目前应用所用的Struts2的版本号。 编写WelcomeAction类 package com.allanlxf.struts2.action; public class WelcomeAction { private int majorVersion; private float minorVersion; private String message; public String execute() { setMessage(message + "." + majorVersion + "." + minorVersion); return "success"; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
  • 37. Greetings To Struts2 public int getMajorVersion() { return majorVersion; } public void setMajorVersion(int majorVersion) { this.majorVersion = majorVersion; } public float getMinorVersion() { return minorVersion; } public void setMinorVersion(float minorVersion) { this.minorVersion = minorVersion; } }WelcomeAction.java Continued.
  • 38. Coding With ActionsStruts2框架不强制Action类继承于任何父类或实现任何的接口,只要一个类中满足如下的要求,都可以作为Struts2的Action。 有公共的缺省构造器 业务方法遵守签名规则:public String methodName() 在默认情况下,控制器会调用Action类的execute方法。如果要调用其它的方法,可以在标签中通过属性method来指定其它的方法名。在开发时,为了保证编译期方法签名的检验,Struts2提供了一个轻量级的接口com.opensymphony.xwork.Action,该接口中规定了execute方法,实现在接口并不会影响程序的便携性。为了更为方便地使用Struts2的其它特性比如:读取资源文件、实现校验等,Struts2提供了该接口的一个实现类供开发者继承使用:com.opensymphony.xwork.ActionSupport。 Struts2中的Action对象即作为业务处理对象也作为数据传输对象,它工作在单线程环境下,这是同Struts1的最大的不同之处。这样设计的好处是可以使开发者同复杂的多线程控制代码中解脱出来,另一方面在业务方法中操作业务相关的数据也变得更为方便。
  • 39. Configure WelcomeAction在struts.xml中配置WelcomeAction Welcome to the world of Struts 2 0.11 /welcome.jsp
  • 40. Action ConfigurationsStruts2的Action类需要在struts.xml文件中进行配置,这样每个Action类都对应一个可以被访问的URL。 在配置文件中,action是通过package来组织的。一个package中可以包含多个action的定义,并且一个package可以通过继承于其它的package来复用父package中的配置信息。Struts2提供了一个叫做的struts-default的缺省的package,应用自定义的package通常继承于struts-default。 每个package都同某个namespace关联,这样在控制器接收到请求时,可以将请求的URL映射为某个namespace,并从该namespace所对应的package中查找action。 /welcome.jsp
  • 41. Action Configurations多个package可以对应同一个namespace,没有指定namespace的package被认为在“缺省的”namespace中。控制器在查找action时,先看指定的namespace中是否存在该action,如果不存在则在缺省的namesapce中查找。 查找http://localhost:8080/album-app/core/welcome.action的过程如下: welcome被认为是要查找的action的名字。 在namespace:/core所对应的package中进行查找。 如果找不到,则在缺省的namespace所对应的package中查找。 如果找不到,报告异常。 注意:在处理任意一个请求的过程中,系统最多查两个名字空间,即最长的名字空间和缺省的名字空间。还有,“/”并不代表缺省的名字空间。
  • 42. About Development Mode 为了便于Struts2应用的开发与调试 ,可以让Struts2工作在开发模式下,这样可以在不重新装载应用的前提下实现: 在请求之间自动重新载入struts.xml文件的信息。 在请求之间自动重新载入资源文件。 在请求之间自动重新载入校验文件。 工作在开发模式下,Struts2可以输出更多的运行时的调试信息,这样有助于跟踪调试程序。 要使Struts2工作在开发模式下,可以在struts.xml文件中加入: 也可以在struts.properties文件中加入: struts.devMode = true 另外,也可以通过指定: struts.i18n.reload=true及struts.configuration.xml.reload=true来单独实现资源文件及struts.xml文件的自动重载。
  • 43. JSP As View Component编写/welcome.jsp 上述代码中,是使用struts的标签来读取当前ActionContext所关联的ValueStack中的对象的信息,其中message为一个OGNL表达式。 访问WelcomeAction http://localhost:8080/album-app/core/welcome.action。其中,/core为namespace,welcome为action的名字。 <%@page contentType="text/html;charset=gbk" %> <%@taglib uri="/struts-tags" prefix="s"%> welcome

  • 44. Work Flow Analysehttp://localhost:8080/album-app/core/welcome.action FillterDispatcherActionContextstaticParams interceptordispatcher resultwelcome.jspValueStackWelcomeActionweb.xml default.propertiesstruts.xmlsettersexecuteControl signal returned by executeOGNLforward
  • 45. Work Flow Analyse客户端发送请求:http://localhost:8080/album-app/core/welcome.action 根据web.xml的配置所有的请求都被FilterDispatcher过滤,根据default.properties的配置,以.action结尾的请求为到action的请求。控制器会根据struts.xml中的配置构建action的调用栈,interceptors在前,然后为action,最后为result。系统创建一个ActionContext对象,并将它和当前的线程关联。系统会在ActionContext对象中构建一个ValueStack用来存放操作过程中的数据,并将action对象放入栈顶。 调用staticParams interceptor,该interceptor会将struts.xml中配置的当前action的信息赋给ValueStack中的action实例,此时使用OGNL实现。 执行action的execute方法。 根据execute的返回值调用相应的Result对象。 result对象执行目标资源,生成到客户端的响应。 FilterDispatcher执行ActionContext的资源回收工作。
  • 46. Using Annotations With Actionpackage com.allanlxf.struts2.annotation.action; import org.apache.struts2.config.Result; import org.apache.struts2.config.Results; @Results(@Result("/welcome.jsp")) public class AnnotatedWelcomeAction { private String message; public String execute() { setMessage("Welcome to Struts2.0.11"); return "success"; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
  • 47. Using Annotations With Action访问AnnotatedWelcomeAction http://localhost:8080/album-app/action/annotatedWelcome.action。其中,/action为namespace,annotatedWelcome为action的名字。 配置信息说明 FilterDispatcher的初始化参数actionPackages指定了系统查找使用了注释配置的action类所在的包。它的取值为用逗号分开的多个包,如果指定了某个包,那么它的所有子包也会被查找。如果搜索范围内的某个action类实现了com.opensymphony.xwork2.Action接口或该类的名字以Action结尾的话,它将被认为是以Annotation的配置形式发布,即使里面没有任何的注释。 如果action在包列表中的某个包的根下,它将被放到缺省的名字空间中。如果action在包列表的某个包的子包下,子包的路径名将作为该action的namespace。 如果action类实现了Action接口,那么类名将作为action的名字。否则action的名字为类名去掉Action后缀,第一个字母小写。
  • 48. struts.xml的配置Bean的配置 常量配置 包配置 命名空间配置 包含配置 拦截器配置
  • 49. (1)Bean的配置 Struts2是通过自己的IOC容器来管理框架的核心组件。 (应用中一般不用再配置) struts-core-2.1.6.jar 中的 struts-default.xml: ...
  • 50. (2)常量配置-a 通常,Struts框架按照如下搜索顺序加载Struts2常量: 1. struts-default.xml (存在于struts2-core-2.1.6.jar) 2. struts-plugin.xml (存在于struts2-Xxx-2.1.6.jar) 3. struts.xml (默认的Struts2配置文件) 4. struts.properties (默认的Struts2配置文件) 5. web.xml ...
  • 51. (2)常量配置-b对于struts.xml:(推荐在此配置) 对于struts.properties: struts.devMode = true 对于web.xml: struts2 ... struts.custom.i18n.resources MessageResource
  • 52. (3)包配置-aStruts2使用包来管理核心组件:Action和拦截器等 每个包就是多个Action、拦截器、多个拦截器引用的集合 配置包时,属性有: name —— 引用该包的key (必填) extends —— 指定继承其他包,可以继承其他包中的Action定义、 拦截器定义等 (可选) namespace —— 包的命名空间 (可选) 默认是"" abstract —— 指定是否非抽象包,抽象包不能包含Action定义 (可选) 注意:父包应该在子包之前定义。(因为配置文件是自上向下解析的)
  • 53. (3)包配置-b /date.jsp
  • 54. (4)命名空间配置 同一个Web应用需要同名的Action时,用命名空间来管理。但同一个命名空间中不能有同名的Action. 指定的方式:通过package来指定namespace,没有指定namespace,默认是""。 当指定命名空间后,url格式为: 命名空间+Action名 (作用类似Struts1的分模块) 注意,如果请求是:/ems/system/find.action,则先在/ems/system命名空间查找 find.action,如果找不到,会在默认的命名空间找,就这两种情况了。
  • 55. (5)包含配置优点:便于分模块开发,将项目分而治之,便于分工,统一管理。 在struts.xml中配置: Struts2的所有配置文件放在WEB-INF/classes下,通过加载struts.xml,加载所有的文件。 每个子配置文件的格式相对独立,自成体系。
  • 56. (6)拦截器配置充分体现AOP编程思想。 拦截时机:Action处理之前、之后。 拦截器作用:a.权限控制;b.跟踪日志;c.调试Action处理时间,排查性能瓶颈 Struts允许形成拦截器栈。(多个拦截器组成大的拦截器栈) ... //对于Action而言,引用拦截器和引用拦截器栈的用法完全一样
  • 57. Struts2的ActionAction是应用的核心。此(Struts2)Action非彼(Struts1)Action,它是一个普通的POJO,有很好的代码复用性。 Action中可以直接提供属性来封装Http请求参数。 Action里的属性还可以封装处理的结果。 Action中提供price属性(getter/setter方法); JSP中使用 直接输出price的值; 可以用标签库,输出复杂的类型(对象类型、数组、集合)。 Action的5个字符串常量: ERROR 、INPUT、LOGIN、NONE、SUCCESS, 详见Action接口(com.opensymphony.xwork2.Action)。 利用ActionSupport,可以大大简化Action的开发。用法:直接继承。
  • 58. Struts2提供了ActionSupportpublic class ActionSupport implements Action, Validateable, ValidationAware,TextProvider, LocaleProvider, Serializable { ..... public String execute() throws Exception{ //默认返回SUCCESS return SUCCESS; } public void validate(){ //空的输入校验方法 } ..... //其中包含了获取国际化信息、数据校验、默认的处理用户请求 }
  • 59. ActionSupport类 Provides a default implementation for the most common actions. 它实现的接口有:Action, LocaleProvider, TextProvider, Validateable, ValidationAware, Serivlizable. 另外,当用户配置的Action类没有指定class属性时,系统自动使用ActionSupport类作为默认的Action处理类。
  • 60. 通过Action访问Servlet API (常用)Servlet主要API:HttpServletRequest、HttpSession、ServletContext 对应JSP内置对象:request、session、application Struts2提供了ActionContext类,其方法: Object get(Object key) 等价于: request.getAttribute(name); Map getApplication() Map对象,模拟该应用的ServletContext实例。 static ActionContext getContext() 获取系统的ActionContext实例。 Map getSession() Map对象,模拟HttpSession实例。 Map getParameters() 获取所有请求参数,类似于request.getParameterMap() 注意:Map的value是一个String[]类型。 void setApplication(Map application) 传入一个Map实例,将该实例里的key-value转换成application的属性名、属性值。 void setSession(Map session) 传入一个Map实例,将该实例里的key-value对转换成session的属性名、属性值。
  • 61. Action直接访问Servlet API通过实现下列接口: org.apache.struts2.util.ServletContextAware 就可以访问 ServletContext org.apache.struts2.util.ServletRequestAware 就可以访问HttpServletRequest org.apache.struts2.util.ServletResponseAware 就可以访问HttpServletResponse
  • 62. 例子public class LoginAction implements Action, ServletResponseAware{ private HttpServletResponse response; private String username; private String password; getter/setter... public void setServletResponse(HttpServletResponse response){ //此方法必须实现 this.response = response; } public String execute() throws Exception{ Cookie c = new Cookie("user", getUsername()); c.setMaxAge(60*60); response.addCookie(c); return SUCCESS; } }
  • 63. Action直接访问Serlet APIjsp中: ${cookie.user.value} 通过表达式读取cookie的值 ServletActionContext由Struts2提供,借助于它的帮助,可以简化Servlet API的访问。 方法有: static PageContext getPageContext() static HttpServletRequest getRequest() static HttpServletResponse getResponse() static ServletContext getServletContext()
  • 64. action元素的method属性目的是将一个Action类定义为多个逻辑Action,就如同Struts1中的MappingDispatchAction //默认调用execute方法 /login.jsp /error.jsp /welcome.jsp //调用regist方法 /login.jsp /error.jsp /welcome.jsp //以上的配置会出现比较多的冗余配置,所以可以考虑采用通配符
  • 65. struts2中通配符的使用-a配置时,指定的name、class、method属性,包括结果,都支持通配符: /example/HelloWorld.jsp /example/Login.jsp findAll /example/{1}.jsp
  • 66. struts2中通配符的使用-b情况1,如果: 请求如果是loginAction.action,则调用LoginRegistAction的 login方法 如果是registAction.action,则调用regist方法 可以利用javascript进行表单的提交。 function regist(){ myForm = document.forms[0]; myForm.action = "registAction.action"; myForm.submit(); }
  • 67. struts2中通配符的使用-c情况2,如果: 如果请求是RegistAction.action,则Action类为com.RegistAction 调用execute方法 情况3,如果: 68. struts2中通配符的使用-d情况4,如果: /{1}.jsp name="*"表示可以匹配任意任意Action。没有指定class,所以默认ActionSupport来处理 默认execute方法返回success字符串。 所以如果请求是a.action,则访问a.jsp
  • 69. struts2中通配符的使用-e情况5,如果请求同时匹配多个Action时,如何安排? 如果请求是RegistAction.action,这样会被第一个配置的Action接管并处理。 所以,需要改成: /HelloWorld.jsp /welcome.jsp /login.jsp /error.jsp /welcome.jsp
  • 70. struts2中通配符的使用-f 结论:除非请求的url与Action的name属性绝对相同,否则按照先后顺序决定由哪个Action来处理。先来先得,所以最模糊的匹配尽量靠后。 /welcome.jsp /HelloWorld.jsp /login.jsp /error.jsp /welcome.jsp
  • 71. Struts2的result处理-aStruts2支持的处理结果类型。 在struts-default.xml中: (以下是系统默认配置文件,我们配置是只要选择type属性值) class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> class="org.apache.struts2.views.freemarker.FreemarkerResult"/> class="org.apache.struts2.dispatcher.ServletRedirectResult"/> class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
  • 72. Struts2的result处理-bredirectAction结果类型: 作用:用于重定向。 dispatcher与redirect的差别主要就是转发与重定向的差别。 原理:response.sendRedirect(String),会重新产生一个请求,以至于所有的 请求参数、请求属性、Action实例、Action中封装的属性会全部丢失。 /welcome.jsp
  • 73. Struts2的result处理-credirectAction结果类型: 与redirect非常类似,一样产生新的请求。 区别在于:redirectAction使用ActionMapperFactory提供的 ActionMapper来 重定向请求。 用 途:一个Action处理结束后,直接重定向到另一个Action。 配置时,还可以指定两个参数: actionName: 指定重定向的Action名 namespace: 指定需要重定向的Aciton所在的命名空间 相同点: redirect与redirectAction都是重定向,都要丢失请求参数、 请求属性和前一个Action的处理结果。 不同点:区别是前者一般用于生成一个具体的资源的请求,后者用于 生成一个对其他Action的请求。
  • 74. Struts2的result处理-d bookAction /myspace book.jsp error error.jsp
  • 75. Struts2的result处理-e全局结果的配置: 首先会在本Action里的局部结果里找,如果找不到,再到全局结果里找。 全局结果的影响范围是对所有的Action都有效。 /${target}.jsp //target是Action中的一个属性
  • 76. Struts2的result处理-f动态结果的配置: 如果请求是ems_toAdd.action 则调用com.EmpAction的toAdd方法处理 如果是success,则转入toAdd.jsp页面输出 /input.jsp /{1}.jsp
  • 77. Struts2的result处理-g动态结果的配置: 如果请求是ems_toAdd.action 则调用com.EmpAction的toAdd方法处理 如果是success,则转入toAdd.jsp页面输出 /input.jsp /{1}.jsp
  • 78. Struts2的result处理-h请求参数决定结果: 既可以使用${属性名}来指定资源,属性名对应的是Action中的属性。 也可以完全使用OGNL表达式:${属性名.属性名.属性名} /empmanager/editSkill.jsp edit.action?skillName=${currentSkill.name} /empmanager/editSkill.jsp edit.action?skillName=${currentSkill.name}