换一批

Struts

struts是开源软件。使用Struts的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,struts是一个不错的选择。

经验文章 概述

struts是开源软件。使用Struts的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,struts是一个不错的选择。

Struts 是Apache软件基金会(ASF)赞助的一个开源项目。它最初是Jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目。它通过采用JavaServlet/JSP技术,实现了基于Java EEWeb应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品。

基本信息

中文名称

开发软件

外文名称

Struts

目  的

为了帮助我们减少在运用MVC设计模型来开发Web应用的时间

属  于

Apache软件基金会(ASF)赞助的一个开源项目

简介

Struts是Apache软件基金会(ASF)赞助的一个开源项目。它最初是Jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目。它通过采用Java Servlet/JSP技术,实现了基于Java EE Web应用的Model-View-Controller〔MVC〕设计模式的应用框架〔Web Framework〕,是MVC经典设计模式中的一个经典产品。

struts是一个基于javaee平台的mvc框架,他是属于一个表现层的开发框架,框架是一个模板,模板是一个半成品,自己本身是不能正常运行的

​起源

Struts最早是作为Apache Jakarta项目的组成部分,项目的创立者希望通过对该项目的研究,改进和提高JavaServer Pages 、Servlet、标签库以及面向对象的技术水准。Struts这个名字来源于在建

筑和旧式飞机中使用的支持金属架。这个框架之所以叫"Struts",是为了提醒我们记住那些支撑我们房屋,建筑,桥梁,甚至我们踩高跷时候的基础支撑。这也是一个解释Struts在开发Web应用程序中所扮演的角色的精彩描述。当建立一个物理建筑时,建筑工程师使用支柱为建筑的每一层提供支持。同样,软件工程师使用Struts为业务应用的每一层提供支持。它的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。我们仍然需要学习和应用该架构,不过它将可以完成其中一些繁重的工作。如果想混合使用Servlets和JSP的优点来建立可扩展的应用,Struts是一个不错的选择。

早期Smalltalk 程序语言便采用了MVC(Model-View -Controller) 模式( Patterns ) 以增加程序代码弹性,MVC模式将程序代码整理切割为三部分,Model 部分是业务与应用领域( Business domain) 相关逻辑、管理状态之对象,Controller 部分接收来自View 所输入的资料并与Model 部分互动,

是业务流程控制( Flow Control) 之处,View 部分则负责展现资料、接收使用者输入资料。在Java 应用中,JFC/Swing、AWT、JSP 皆是可用作View 的技术规格,而JavaBean 与Enterprise JavaBean 规格则可用于Model 程序代码,一旦应用程序以MVC 模式加以适当的分割,Model 部分程序代码可在不同使用者接口外观的应用程序中重复使用。

随着JSP 与Servlet 技术大量应用于以Web 为基础的应用程序,Java 开发人员群体认为应以较佳的模式以提升Web 应用程序的可维护性与重复使用性。早期JSP 规格书中曾列举两种可行之JSP 应用架构,分别为Model1 与Model 2。

在Model 1 架构中,JSP 直接处理Web 浏览器送来的请求( Request ),并辅以JavaBean 处理应用相关逻辑。Model 1 架构单纯编写比较容易,但在Model 1 中JSP 可能同时肩负View 与Controller 角色,两类程序代码有可能混杂而不易维护。而Model 2 中将Servlet 纳入架构中扮演前端Controller 角色,将Web 浏览器送出的请求集中送至Servlet ,Servlet 可集中管理使用者登入、权限控制、多国语言转换等前置处理,再视需求转向给对应的JSP 处理。Model 2 中采用了较佳的MVC 模式,但增加了编写复杂度。

Struts是Apache软件基金下Jakarta项目的一部分。除Struts之外,还有其他成功的开源产品,包括Tomcat, Ant 和Velocity。2000 年Craig R. McClanahan 先生贡献了他编写

的JSP Model 2 架构的Application Framework 原始程序代码给Apache 基金会,成为Apache Jakarta 计划Struts Framework 前身。

开始的代码基础从2000年5月开始开发,直到2001年6月,1.0版本发布。有30 多个开发者参与进来,并有数千人参与到讨论组中。Struts 代码基础由一个志愿的Commnitter团队来管理。到2002年,Struts 小组共有9个志愿Commnitter。

Struts框架的主要架构设计和开发者是Craig R.McClanahan。Craig 也是Tomcat 4的主要架构师,以及Java Web Services Developer Pack的主要架构师和实现者。他现在是Sun的JavaServer Faces (JSR-127) 以及J2EE平台的Web层架构的规范领导。Craig R. McClanahan 先生是JCP ExpertGroup 成员之一,曾参与JSP 规格制定与Tomcat 4 之编写,因此Struts Framework 广受Java 开发人员群体所重视。Borland 自2002 年底开始于开发工具JBuilder 中支持Struts Framework。

Struts是Apache 基金会Jakarta 项目组的一个Open Source 项目,它采用MVC模式,能够很好地帮助java 开发者利用J2EE开发Web应用。和其他的java架构一样,Struts 也是面向对象设计,将MVC模式"分离显示逻辑和业务逻辑"的能力发挥得淋漓尽致。Structs 框架的核心是一个弹性

的控制层,基于如 Java Servlets,JavaBeans,ResourceBundles与XML等标准技术,以及 Jakarta Commons 的一些类库。Struts由一组相互协作的类(组件)、Servlet以及jsp tag lib组成。基于struts构架的web应用程序基本上符合JSP Model2的设计标准,可以说是一个传统 MVC设计模式的一种变化类型。

Struts最早是作为Apache Jakarta项目的组成部分问世运作。项目的创立者希望通过对该项目的研究,改进和提高Java Server Pages、Servlet、标签库以及面向对象的技术水准。

Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点,使开发者能更深入的了解其内部实现机制。

除此之外,Struts的优点主要集中体现在两个方面:Taglib和页面导航。Taglib是Struts的标记库,灵活运用,能大大提高开发效率。另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。

关于页面导航,我认为那将是今后的一个发展方向,事实上,这样做,

使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。

MVC即Model-View-Controller的缩写,是一种常用的设计模式。MVC 减弱了业务逻辑接口和数据接口之间的耦合,以及让视图层更富于变化。Struts 是MVC的一种实现,它将 Servlet和 JSP 标记(属于 J2EE 规范)用作实现的一部分。Struts继承了MVC的各项特性,并根据J2EE的特点,做了相应的变化与扩展。

流程

服务器启动后,根据web.xml加载ActionServlet读取struts-config.xml文件内容到内存。

以登录为例:第一次进login.jsp会先实例化Form、把默认值(String默认为空字符串,整型默认为0)赋给表单元素。

输入用户名密码提交表单、提交到action属性的login.action,通过ActionServlet读struts-config.xml文件找到 action下的path属性找到.action,通过name属性找form-beans中的form-bean的name属性得到ActionForm的包名类名,先实例化form,把表单的值填充给form,调用form的validate方法验证、ActionErrors返回null表示验证通过,否则失败返回input指定的页面.验证通过会实例化Action,执行Action的execute方法。

结构

综述

相应框架结构如图:

Struts对Model,View和Controller都提供了对应的组件。

在上图中,ActionServlet,这个类是Struts的核心控制器,负责拦截来自用户的请求。

Action,这个类通常由用户提供,该控制器负责接收来自ActionServlet的请求,并根据该请求调用模型的业务逻辑方法处理请求,并将处理结果返回给JSP页面显示。

Model部分

由JavaBean组成,ActionForm用于封装用户的请求参数,封装成ActionForm对象,该对象被ActionServlet转发给Action,Action根据ActionForm里面的请求参数处理用户的请求。

JavaBean则封装了底层的业务逻辑,包括数据库访问等。

View部分

该部分采用JSP实现。

Struts提供了丰富的标签库,通过标签库可以减少脚本的使用,自定义的标签库可以实现与Model的有效交互,并增加了现实功能。对应上图的JSP部分。

Controller组件

Controller组件有两个部分组成——系统核心控制器,业务逻辑控制器。

系统核心控制器,对应上图的ActionServlet。该控制器由Struts框架提供,继承HttpServlet类,因此可以配置成标注的Servlet。该控制器负责拦截所有的HTTP请求,然后根据用户请求决定是否要转给业务逻辑控制器。

业务逻辑控制器,负责处理用户请求,本身不具备处理能力,而是调用Model来完成处理。对应Action部分。

基本框架

struts框架具有组件的模块化,灵活性和重用性的优点,同时简化了基于MVC的web应用程序的开发。

struts可以清晰地区分控制,事务逻辑和外观,从而简化了开发应用程序的过程。struts提供的类使得开发工作更加简单,这些类包括:

a. 控制程序流程的类

b. 实现和执行程序事务逻辑的类

c. 自定义的标记库使得创建和验证HTML表单更加容易

压缩包内容 文件夹jakarta-struts-1.0.2包含两个

OGNL

Struts2 ognl中的#、%和$符号用法说明

#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分。在这里笔者简单介绍它们的相应用途。

1.#符号的用途一般有三种。

1)访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute(”msg”)。

2)用于过滤和投影(projecting)集合,如示例中的persons.{?#this.age>20}。

3)用来构造Map,例如示例中的#{'foo1':'bar1','foo2':'bar2'}。

2.%符号%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。如下面的代码所示:构造Map

The value of key "foo1" is

;不使用%:

;使用%:

3.$符号$符号主要有两个方面的用途。

在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

在Struts 2框架的配置文件中引用OGNL表达式,例如下面的代码片断所示: 10 100 BAction-test校验:数字必须为${min}为${max}之间!

Struts2

简介

Struts 2是Struts的下一代产品。是在 struts 和WebWork的技术基础上进行了合并,全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。因为Struts 2和Struts 1有着太大的变化,但是相对于WebWork,Struts 2只有很小的变化。具体请参考百度百科Struts2。

发展概况

经过六年多的发展,Struts1已经成为了一个高度成熟的框架,不管是稳定性还是可靠性都得到了广泛的证明。市场占有率超过20%,拥有丰富的开发人群,几乎已经成为了事实上的工业标准。但是随着时间的流逝,技术的进步,Struts1的局限性也越来越多地暴露出来,并且制约了Struts1的继续发展。

对于Struts1框架而言,由于与JSP/Servlet耦合非常紧密,因而导致了一些严重的问题。首先,Struts1支持的表现层技术单一。由于Struts1出现的年代比较早,那个时候没有FreeMarker、Velocity等技术,因此它不可能与这些视图层的模版技术进行整合。其次,Struts1与Servlet API的严重耦合,使应用难于测试。最后,Struts1代码严重依赖于Struts1 API,属于侵入性框架。

从目前的技术层面上看,出现了许多与Struts1竞争的视图层框架,比如JSF、Tapestry和SpringMVC等。这些框架由于出现的年代比较近,应用了最新的设计理念,同时也从Struts1中吸取了经验,克服了很多不足。这些框架的出现也促进了Struts的发展。目前,Struts已经分化成了两个框架:第一个是在传统的Struts1的基础上,融合了另外的一个优秀的Web框架WebWork的Struts2。Struts2虽然是在Struts1的基础上发展起来的,但是实质上是以WebWork为核心的。Struts2为传统的Struts1注入了WebWork的先进的设计理念,统一了Struts1和WebWork两个框架。Struts1分化出来的另外一个框架是Shale。这个框架远远超出了Struts1原有的设计思想,与原有的Struts1关联很少,使用了全新的设计思想。Shale更像一个新的框架而不是Struts1的升级。 本文下面的内容将主要讨论Struts2。

体系结构

应用流程注解

当Web容器收到 请求(HttpServletRequest)它将请求传递给一个标准的的过滤链包括(ActionContextCleanUp)过滤器,然后经过Other filters(SiteMesh ,etc),

接下来需要调用FilterDispatcher核心控制器,然后它调用ActionMapper确定请求那个Action,ActionMapper返回一个收集Action详细信息的ActionMaping对象。

接下来FilterDispatcher将控制权委派给ActionProxy,ActionProxy调用配置管理器(ConfigurationManager) 从配置文件中读取配置信息(struts.xml),然后创建ActionInvocation对象,ActionInvocation在调用Action之前会依次的调用所用配置拦截器(Interceptor N) 一旦执行结果返回结果字符串ActionInvocation负责查找结果字符串对应的(Result)然后执行这个Result Result会调用一些模版(JSP)

来呈现页面,之后拦截器(Interceptor N)会在被执行(顺序和Action执行之前相反)最后响应(HttpServletResponse)被返回在web.xml中配置的那些过滤器和(核心控制器)(FilterDispatcher)。

与Struts1比

通过上面对Struts2体系结构的了解,我们发现Struts2对Struts1进行了巨大的改进。主要表现在如下几个方面:

在Action的实现方面:Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。

线程模型方面:Struts1的Action是单实例的,一个Action的实例处理所有的请求。Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象),没有线程安全方面的问题。

Servlet依赖方面:Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。这使程序难于测试。Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。

封装请求参数:Struts1中强制使用ActionForm对象封装请求的参数。Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。

表达式语言方面:Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。

绑定值到视图技术:Struts1使用标准的JSP,Struts2使用“ValueStack”技术。

类型转换:Struts1中的ActionForm基本使用String类型的属性。Struts2中使用OGNL进行转换,可以更方便的使用。

数据校验:Struts1中支持覆盖validate方法或者使用Validator框架。Struts2支持重写validate方法或者使用XWork的验证框架。

Action执行控制的对比:Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期。Struts2支持通过拦截器堆栈为每一个Action创建不同的生命周期。

与WebWork对比

Struts和Webwork同为服务于Web的一种MVC框架,从某种程度上看,Struts2是从WebWork2上升级得到的。甚至Apache的官方文档也讲:WebWork2到Struts2是平滑的过渡。我们甚至也可以说Struts2就是WebWork2.3而已。在很多方面Struts仅仅是改变了WebWork下的名称。Struts2对应的有自己的标签,并且功能强大。Webwork也有自己的标签。在2005年12月,WebWork与Struts Ti决定合并, 再此同时, Struts Ti 改名为 Struts Action Framework 2.0,成为Struts真正的下一代。

ActionSupport基类

五个标准返回值

ActionSupport基类中定义了五个标准的返回值 ,当然我们可以自己随意定义返回的名字

String SUCCESS = "success"; //默认是 SUCCESS 类型

String NONE = "none";

String ERROR = "error";

String INPUT = "input";

String LOGIN = "login";

方法

ActionSupport基类定义了了一些方法,程序员自己写的action如果继承了ActionSupport基类,就可以应用这些方法,很方便解决一些问题。

一些比较常用的方法:

getText(String aTextName);//国际化用到

...//getText(String aTextName)的重载方法

addActionMessage(String aMessage);

addFieldError(String fieldName, String errorMessage);

//校验失败后返回给客户端的信息,struts2 标签可以取得

addActionError(String anErrorMessage);

Result Type

在默认时,标签的type属性值是“dispatcher”(实际上就是转发,forward)。开发人员可以根据自己的需要指定不同的类型,如redirect、stream等。如下面代码所示:

/result.jsp

这此result-type可以在struts2-core-2.0.11.1.jar包或struts2源代码中的struts-default.xml文件中找到,在这个文件中找到标签,所有的result-type都在里面定义了。代码如下:

dispatcher

用来转向页面,通常处理JSP

org.apache.struts2.dispatcher.ServletDispatcherResult

freemaker

处理FreeMarker模板

org.apache.struts2.views.freemarker.FreemarkerResult

httpheader

控制特殊HTTP行为的结果类型

org.apache.struts2.dispatcher.HttpHeaderResult

stream

向浏览器发送InputStream对象,通常用来处理文件下载,还可用于返回AJAX数据

org.apache.struts2.dispatcher.StreamResult

StreamResult等价于在Servlet中直接输出Stream流。这种Result被经常使用于输出图片、文档等二进制流到 客户端。通过使用StreamResult,我们只需要在Action中准备好需要输出的InputStream即可。

配置:

image/jpeg

imageStream

filename="document.pdf"

1024

同时,StreamResult支持许多参数,对输出的Stream流进行参数控制。

velocity

处理Velocity模板

org.apache.struts2.dispatcher.VelocityResult

随着模板技术的越来越流行,使用Freemarker或者Velocity模板进行View层展示的开发者越来越多。Struts2同样为模板作为Result做出了支持。由于模板的显示需要模板(Template)与数据(Model)的紧密配合,所以在Struts2中,这两个Result的主要工作是为模板准备数据。

xslt

处理XML/XLST模板

org.apache.struts2.views.xslt.XSLTResult

plainText

显示原始文件内容,例如文件源代码

org.apache.struts2.dispatcher.PlainTextResult

chain

用来处理Action链

com.opensymphony.xwork2.ActionChainResult

chain其实只是在一个action执行完毕之后,forward到另外一个action,所以他们之间是共享HttpServletRequest的。在使用chain作为Result时,往往会配合使用ChainingInterceptor。ChainingInterceptor的作用是在Action直接传递数据。事实上,源Action中ValueStack的数据会被做一次Copy,这样,2个Action中的数据都在ValueStack中,使得对于前台来说,通过ValueStack来取数据,是透明而共享的。比如说,一张页面中,你可能有许多数据要显示,而某些数据的获取方式可能被很多不同的页面共享(典型来说,“推荐文章”这个小栏目的数据获取,可能会被很多页面所共享)。这种情况下,可以把这部分逻辑抽取到一个独立Action中,并使用chain,将这个Action与主Action串联起来。这样,最后到达页面的时候,页面始终可以得到每个Action中的数据。

从实战上讲,使用chain作为Result也的确存在着上面所说的许多问题,我个人也是非常不推崇滥用这种Result。尤其是,对于使用Spring和Hibernate的朋友来说,如果你开启OpenSessionInView模式,那么Hibernate的session是跟随HttpServletRequest的,所以session在整个action链中共享。这会为我们的编程带来极大的麻烦。因为我们知道Hibernate的session会保留一份一级缓存,在action链中,共享一级缓存无疑会为你的调试工作带来很大的不方便。

所以,谨慎使用chain作为你的Result,应该成为一条最佳实践。

redirect

重定向到一个URL

org.apache.struts2.dispatcher.ServletRedirectResult

如果你在Action执行完毕后,希望执行另一个Action,有2种方式可供选择。一种是forward,另外一种是redirect。有关forward和redirect的区别,这里我就不再展开,这应该属于Java程序员的基本知识。在Struts2中,分别对应这两种方式的Result,就是chain和redirect。

先来谈谈redirect,既然是重定向,那么源地址与目标地址之间是2个不同的HttpServletRequest。所以目标地址将无法通过ValueStack等Struts2的特性来获取源Action中的数据。

同时,Redirect的Result支持在配置文件中,读取并解析源Action中ValueStack的值,并成为参数传递到Redirect的地址中。

redirectAction

重定向到一个Action

org.apache.struts2.dispatcher.ServletActionRedirectResult

区别

redirect和redirectAction chain的区别

struts2中关于result的返回类型一般我们是转发到一个jsp页面或者是html页面等,但是struts2中的result的返回类型还有redirect,redirectAction,chain。对于这三种返回类型之间肯定是有区别的,下面我们来看看关于redirect redirectAction chain这三种struts2的返回类型之间的区别。当使用type=“redirectAction” 或type=“redirect”提交到一个action并且需要传递一个参数时。这里是有区别的:使用type=“redirectAction”时,结果就只能写Action的配置名,不能带有后缀:“.action”

Xml代码

User?u_id=${loginBean.u_id}

使用type=“redirect”时,结果应是action配置名+后缀名

Xml代码

User.action?u_id=${loginBean.u_id}

redirect:action处理完后重定向到一个视图资源(如:jsp页面),请求参数全部丢失,action处理结果也全部丢失。

redirect-action:action处理完后重定向到一个action,请求参数全部丢失,action处理结果也全部丢失。

chain:action处理完后转发到一个action,请求参数全部丢失,action处理结果不会丢失。

出现漏洞

7月17日是许多安全运维、黑客的不眠之夜……Struts2高危漏洞造成大规模的信息泄露将会影响无数网民(可能无人能够幸免……)利用漏洞,黑客可发起远程攻击,轻则窃取网站数据信息,严重的可取得网站服务器控制权,构成信息泄露和运行安全威胁。

据乌云目前掌握的情况:Struts漏洞影响巨大,受影响站点以电商、银行、门户、政府居多。而且一些自动化、傻瓜化的利用工具开始出现,填入地址可直接执行服务器命令,读取数据甚至直接关机等操作...

以下是国家计算机网络应急技术处理协调中心发布的关于Apache Struts2 远程命令执行高危漏洞和开放重定向高危漏洞的情况通报:

安全公告编号:CNTA-2013-0022

近期,我中心主办的国家信息安全漏洞共享平台收录了Apache Struts存在一个远程命令执行漏洞和一个开放重定向漏洞(编号:CNVD-2013-28972,对应CVE-2013-2251; CNVD-2013-28979,对应CVE-2013-2248)。利用漏洞,可发起远程攻击,轻则窃取网站数据信息,严重的可取得网站服务器控制权,构成信息泄露和运行安全威胁。

相关文章


    Notice: Undefined index: newRealte in /home/www/www.tulaoshi.com/releases/release-70/cache/smarty/983617069c66cd03ffc5dc16662ae9b9b33bfbd9.file.tag.html.php on line 258

    Notice: Trying to get property of non-object in /home/www/www.tulaoshi.com/releases/release-70/cache/smarty/983617069c66cd03ffc5dc16662ae9b9b33bfbd9.file.tag.html.php on line 258
手机页面
收藏网站 回到头部