• 1. Struts2
  • 2. 课程目标掌握Struts2原理、基本配置及使用 掌握Struts2核心解析、国际化、类型转换、输入校验、OGNL、Struts2标签库 了解AJAX技术支持 掌握文件的上传与下载。 深入理解MVC与Struts之间的关系,并使用基本MVC和Struts进行项目开发2
  • 3. 主要内容Struts2原理 Action详解 类型转换 输入校验(使用xml、程序验证两种方式) 国际化 文件上传 OGNL表达式 常用标签库 属性驱动与模型驱动 3
  • 4. 参考书籍《Struts2.1权威指南》 4
  • 5. Framework伴随着软件开发的发展,在多层的的软件开发项目中,可重用、易扩展的,而且是经过良好测试的软件组件,越来越为人们所青睐。这意味着人们可以将充裕的时间用来分析、构建业务逻辑的应用上,而非繁杂的代码工程。于是人们将相同类型问题的解决途径进行抽象,抽取成一个应用框架。这也就是我们所说的Framework。5
  • 6. FrameworkFramework的体现提供了一套明确机制,从而让开发人员很容易的扩展和控制整个Framework开发上的结构。 通常,Framework的结构中都有一个“命令和控制”组件(“command and control” component)。6
  • 7. Framework通过基于请求响应(Request-Response)模式的应用Framework,基本上有如下几个表现逻辑结构组成。 控制器(Controller)——控制整个Framework中各个组件协调工作。 业务逻辑层(Business Logic)——对于Framework本身来说,这里仅仅只是概念和几个提供服务的基础组件,真正的实现与客户的业务逻辑接轨,还需要开发人员在Framework上再次扩展。 数据逻辑层(Data Logic)——绝大多数应用系统都需要数据交互,这一层次主要包括了数据逻辑和数据访问接口。7
  • 8. StrutsStruts目前有两个分支: Struts 1.x Struts 2.x 目前第二种框架是我们学习的重点。 Struts2.x实际上是Struts1.x与Webwork的整合(Apache+OpenSymphony)。8
  • 9. Struts框架的优势良好的架构和设计 可重用,模块化,扩展性好(提供了插件机制) Open source9
  • 10. Struts概述Struts有其自己的控制器(Controller),同时整合了其他的一些技术去实现模型层(Model)和视图层(View)。 在模型层,Struts可以很容易的与数据访问技术相结合,包括EJB、JDBC等。 在视图层,Struts能够与JSP表示层组件相结合。10
  • 11. Struts概述Struts有一组相互协作的类、Servlet以及Jsp TagLib组成。基于Struts架构的web应用程序符合JSP Model2的设计标准,可以说是MVC设计模式的一种变化类型。 根据前面对Framework的描述,我们很容易理解为什么说Struts是一个Web Framework,而不仅仅是一些标记类的组合。但Struts也包含了丰富的标记库和实用程序类。(文件上传等)11
  • 12. MVC的概念MVC是Model-View-Contoller的简称,即模型—视图—控制器。 MVC是一种设计模式,它把应用程序分成三个核心模块:模型、视图、控制器,它们各自处理自己的任务。12
  • 13. MVC结构图13
  • 14. MVC处理过程首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理。 然后模型根据用户请求进行相应的业务逻辑处理,并返回数据。 最后控制器调用相应的视图格式化模型返回的数据,并通过视图呈现给用户。14
  • 15. MVC的优点首先,最重要的一点是多个视图能共享一个模型。同一个模型可以被不同的视图重用,大大提高了代码的可重用性。 由于MVC的三个模块相互独立,改变其中一个不会影响其他两个,所以依据这种设计思想能构造良好的松耦合的构件。 此外,控制器提高了应用程序的灵活性和可配置性。控制器可以用来联接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段。15
  • 16. MVC的适用范围使用MVC需要精心的计划,由于它的内部原理比较复杂,所以你需要花费一些时间去理解它。将MVC运用到你的应用程序,会带来额外的工作量,增加应用的复杂性。 但对于开发存在大量用户界面,并且业务复杂的大型应用程序,MVC将会使你的软件在健壮性、代码重用和结构方面上一个新的台阶。尽管在最初构建MVC框架时会花费一定的工作量,但从长远角度看,它会大大提高后期软件开发的效率。16
  • 17. Java Web应用结构的发展阶段1:JSP是一个独立的、自主完成所有任务的模块 阶段2:JSP Model1 阶段3:JSP Model217
  • 18. JSP是一个独立的、自主完成所有任务的模块早期的Java Web应用中,JSP文件同时负责生成网页、控制到下一个网页的流程,以及负责业务逻辑,这给Web开发带来一系列问题: HTML和Java强耦合在一起,JSP文件的编写者必须既是网页设计者,又是Java开发者。 可读性差。 调试困难。 不利于维护,更改业务逻辑或数据可能牵涉相关的多个网页。18
  • 19. 19JSP是一个独立的、自主完成所有任务的模块请求 应用服务器响应JSP页面数据库 服务器
  • 20. 20Model I 体系结构Model I 体系结构结合使用 JSP 页面和 JavaBean 来开发 Web 应用程序请求 应用服务器响应JSP页面JavaBean数据库 服务器213456
  • 21. 21Model II 体系结构Model I 体系结构结合使用 JSP 页面和 JavaBean 来开发 Web 应用程序请求 应用服务器响应JSP页面JavaBeanServlet数据库 服务器
  • 22. Model II 体系结构JSP负责生成动态网页 Servlet或Filter负责流程控制 JavaBean负责业务逻辑22
  • 23. Struts与Web App的关系既然Struts叫做Web Framework,那么其肯定主要基于web层的应用系统开发。按照Java EE Architecture的标准,struts应当和jsp/servlet一样,存在于web container一层。23
  • 24. Struts概述24
  • 25. Struts2概述Struts提供了许多定制JSP标记,它们的使用简单,但是它们在隐藏信息方面功能强大。例如,除了bean名称和给定bean中每个属性的名称之外,页面设计者不需要知道有关表单bean的更多信息。25
  • 26. 增加Struts2功能将Struts2框架的类库复制到Web应用的WEB-INF/lib路径下。 编写控制器Action类。 编写struts.xml配置文件。 修改web.xml文件,在web.xml文件中配置Struts2的核心Filter。 26
  • 27. 27开发Struts2依赖的jar到http://struts.apache.org/download.cgi下载struts-2.2.x.x-all.zip,目前最新版为2.2.1.1。下载完后解压文件,开发struts2应用需要依赖的jar文件在解压目录的lib文件夹下。不同的应用需要的JAR包是不同的。下面给出了开发Struts 2程序最少需要的JAR。
  • 28. 28开发Struts2依赖的jarstruts2-core-2.x.x.jar :Struts 2框架的核心类库 xwork-core-2.x.x.jar :XWork类库,Struts 2在其上构建 ognl-3.0.x.jar :对象图导航语言(Object Graph Navigation Language),Struts 2框架使用的一种表达式语言 freemarker-2.3.x.jar :Struts 2的UI标签的模板使用FreeMarker编写 commons-logging-1.1.x.jar :ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。 Commons-fileupload-1.2.1 文件上传组件。
  • 29. 29控制器Struts2有两个重要的控制器: StrutsPrepareAndExecuteFilter: 核心控制器,负责接收所有请求。 Action: 负责处理单个特定请求。 Action是一个普通的类, 不需要实现任何接口或继承任何类.
  • 30. Action ClassesAction类是业务逻辑的一个包装。Action类的用途是将HttpServletRequest转换为业务逻辑。 Action中最重要的就是execute方法,它负责执行相应的业务逻辑,如果需要,它也进行相应的数据检查。执行完成之后,返回一个字符串对象,控制器通过该字符串对象来进行转发工作。30
  • 31. 31Action的基本结构public class HelloWorld { public String execute() throws Exception{ return “success” } } 说明: 无需实现任何接口或继承任何类,但有时为了简化某些功能必须继承ActionSupport类 execute()方法会被自动调用,该方法用于处理用户请求,返回类型为String,是跳转路径的逻辑名称.向上抛出Exception表示能够处理所有异常. “success”是跳转路径的逻辑名称.
  • 32. 32Struts2的配置文件Struts2默认的配置文件为struts.xml ,StrutsPrepareAndExecuteFilter过滤器在初始化时将会在WEB-INF/classes下寻找该文件,该文件的配置模版如下:
  • 33. 33struts.xml配置说明package:用于组织Action的一个逻辑概念,必须通过extends继承自struts-default包, struts-default包在struts-default.xml文件中定义,该文件配置了很多有用的功能。 属性: name extends namespace
  • 34. 34struts.xml配置说明action: 所有的Action都必须通过action标签配置 name: 访问action 逻辑名称 class: Action类的全限定名 result子标签: 定义跳转路径, execute()方法的返回值在此定义.默认情况下为转发,如果是重定向,必须按下面的格式: /xx.jsp
  • 35. 35Action的配置—struts.xmlAction必须配置在struts.xml文件中,该文件默认放在classpath下。 helloworld.jsp
  • 36. 36Struts2的启动配置在struts1.x中, struts框架是通过Servlet启动的。在struts2中,struts框架是通过Filter启动的。它在web.xml中的配置如下: struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter struts2 /*
  • 37. WebWork的数据流图37
  • 38. XWork2——Struts2的基础与WebWork2相同,Struts2框架也是由两部分组成:XWork2和Struts2。 XWork是一个命令模式框架,它是Struts2的基础。 XWork提供了很多核心功能: IoC(Inversion of control,控制反转)容器, 强大的表达式语言 (OGNL:Object Graph Navigation Language-----对象图像导航语言) 数据类型转换, 验证和可插入的配置。 XWork框架的核心概念包括action,拦截器(inerceptor)和result. 38
  • 39. Struts2拦截器工作原理39Struts2拦截器工作原理
  • 40. Struts2与XWork2之间的交互图40Struts2与XWork2之间的交互图
  • 41. Struts2与XWork2之间的交互一个HTTP请求到达Struts2的StrutsPrepareAndExecuteFilter之后,就会被转换成一个action command。 这个action command在穿越了一系列Struts2和XWork的拦截器(1~3)之后,最后执行用户编写的Action实例。 在Action执行后,响应还会穿越相同的拦截器,按照与请求相反的顺序即拦截器(3~1) 。 最后通过Struts2的HttpServletResponse转换成Web可识别的响应,如JSP。 41
  • 42. Struts2的数据流图42
  • 43. Struts的数据流程2-1当接收到一个HttpServletRequest,Interceptor做一些拦截或者初始的工作; 当外部的HttpServletRequest到来时,初始到了Servlet容器传递给一个标准的过滤器链;ActionContextCleanUp这个在集成插件方面非常有用。Other filters(SitMesh,etc) 调用FilterDispatecher会去查找相应的ActionMapper。 如果找到了相应的ActionMapper它将会将控制权限交给ActionProxy,ActionProxy将会通过ConfigurationManager来查找配置struts.xml;43
  • 44. Struts的数据流程2-2下一步将会通过ActionInvocation来负责命令模式的实现(包括调用一些拦截器Interceptor框架,在调用action之前),一旦action返回,会查找相应的Result,Result类型可以是JSP或者FreeMark等; 这些组件和ActionMapper一起返回给请求的url(注意拦截器的执行顺序),响应的返回是通过我们在web.xml中配置的过滤器; 如果ActionContextCleanUp是当前使用的,则FilterDispatecher将不会清理threadLocal ActionContext; 如果ActionContextCleanUp不使用,则将会去清理threadlocal。 44
  • 45. ActionMapperorg.apache.struts2.dispatcher.mapper.ActionMapper接口在HTTP请求和action调用请求之间提供了一个映射。 当给定一个HTTP请求时,ActionMapper根据请求的URI来查找是否有对应的action调用, 如果有,则返回一个描述了action调用的ActionMapper; 如果没有匹配的action调用请求,则返回null。 Struts2框架对该接口提供的默认实现是org.apache.struts2.dispatcher.mapper.DefaultActionMapper. 45
  • 46. ActionMappingActionMapping本质上是一个数据传输对象,它将Action类和要执行的方法的详细资料收集在一起。ActionMapping由org.apache.struts2.dispatcher.Dispatcher和用户各种接口组件使用。 ActionMapping的完整类名是org.apache.struts2.dispatcher.mapper.ActionMapping. 46
  • 47. ActionProxy和ActionInvocationActionProxy在XWork中和真正的Action充当代理的角色,在通过框架框架执行Action的过程中,因为是使用代理而不是直接操纵对象,所以可以在代理中封装拦截器、result等额外代码。 ActionProxy持有ActionInvocation对象。ActionInvocation代表了action执行的当前状态。它持有拦截器(按顺序 )、Action实例、结果映射(从结果码到Result实例的映射)和ActionContext。 47
  • 48. 接收用户数据问题开发Web应用程序,首先应会遇到对用户输入数据的接收,传统的Web应用程序是由开发人员调用HttpServletRequest的getParameter(String name)方法从请求中获取数据,而Web框架都提供了数据绑定机制,由框架从请求中获取数据然后绑定到一个JavaBean对象中。 Struts2提供了多种方式用于接收用户输入的数据。 Struts2的action完全与Web解耦,要获取Web层的数据,需要使用ActionContext,它为action提供了一个执行上下文。 48
  • 49. 接收数据方式一:用Action的属性在action里面定义要接收的参数,并提供相应的setter,getter,可以和提交参数的名称一致,并不用做数据类型的转换。 相应提交方式可以用get和post,如:userAction?password=admin&name=admin 49
  • 50. 接收数据方式二:使用Domain Model在Action里面不设置太多的属性,而是用Model层用到的模型,保存它的一个对象。 提交参数:userAction?user.password=1&user.name=admin;这里面的user指向Action里面的user。 50
  • 51. 接收数据方式三:使用Model DrivenAction实现ModelDriven泛型接口,定义Model类的对象(必须new),通过getModel方法返回该对象。 相应提交方式可以用get和post,如:userAction?password=admin&username=admin51
  • 52. 访问request,session,application对象52
  • 53. 与Servlet API解耦的访问方式53
  • 54. 与Servlet API解耦的访问方式要获取这三个Map对象,可以使用com.opensymphony.xwork2.ActionContext类。 54
  • 55. 通过ActionContext来获取request,session,application55
  • 56. 通过ActionContext来获取request,session,application56
  • 57. Success.jsp57
  • 58. 说明利用请求对象来传递数据还有一种方式,你可以直接使用ActionContext类的put()方法将数据保存到ActionContext中,如下: ActionContext.getContext().put(“hello”,”欢迎学习struts2”); 然后在结果页面中, 从请求对象中取出hello属性,如下: ${requestScope.hello}或者<%=request.getAttribute(“hello”)%> 58