provides the practical and concrete details to bring the theoretical concepts from the first chapter down to earth.
(本章将通过实践和具体的细节来把第1章中讲述的理论概念落到实处)
This application isn’t intended to demonstrate the full complexity of the framework.
(这个示例应用程序并不能展示这个框架的全部功能)
Declarative architecture
In this book, we use the phrase declarative architecture to refer to a type of configuration that allows developers to describe their application architecture at a higher level than direct programmatic manipulation.
(在本书中,我们使用声明性架构来引用一种配置,这种配置允许开发者在高级别上描述他们的应用型架构,而不是直接编程操作)
Similar to how an HTML document simply describes its components and leaves the creation of their runtime instances to the browser, Struts 2 allows you to describe your architectural components through its high-level declarative architecture facility and leave the runtime creation of your application to the framework.
(和HTML文档简单描述它的组件类似,而将创建这些运行时实例的任务交给了浏览器。struts2允许你通过高级的声明架构组件来描述应用程序的架构组件,而将运行时创建这些架构组件的任务交给框架)
Two kinds of configuration
First, we need to clarify some terminology.
(首先,我们需要明白一些科学术语)
In the introduction to this chapter, we referred to the act of declaring your application’s Struts 2 components as configuration.
(在本章的介绍部分,我们把声明应用的struts2组件的行为称为配置)
While there is nothing wrong with this nomenclature, it can be confusing.
(虽然这么命名没有什么错误,但是它可能会引发一些困惑)
Hidden beneath the far-reaching concept of configuration, we can distinguish between two distinct sets of activity that occur in a Struts 2 project.
(在这个意义深远的配置概念之后,在struts2项目内部我们可以区分两类明显不同的行为)
One of these, the declarative architecture, is more central to actually building Struts 2 applications, while the other is more administrative in nature.
(其中一类是声明性架构,与实际构建struts2应用程序更接近,而另外一类在本质上更接近于管理。)
Conceptually, it’s important to distinguish between the two.
(在本节中,我们将会了解上述过程的细节)
CONFIGURING THE FRAMEWORK ITSELF
First, we have configuration in the traditional sense of the word.
(首先,我们理解传统意义上的配置)
These are the more administrative activities.
(这而配置更多的是管理上的活动)
Because the Struts 2 framework is flexible, it allows you to tweak its behavior in many areas.
(因为struts2框架是非常灵活的,它允许你在许多区域调整它的行为)
If you want to change the URL extension by which the framework recognizes which requests it should handle, you can configure the framework to recognize any extension that you like.
(如果你想改动框架赖以识别哪些请求应该处理的URL扩展名,那么可以配置框架去识别你所用的扩展名)
By default, Struts 2 looks for URLs ending in .action, but you could configure the framework to look for .do ( the Struts 1.x default extension) or even no extension at all.
(默认情况下,struts2查找以.action结尾的URL,但是你可以配置框架查找.do(struts1的默认扩展名),甚至可以不适用任何扩展名)
Other examples of configurable parameters include maximum file upload size and the development mode flag.
(其它配置参数还包括上传文件的最大容量和开发模式标志等)
Due to its administrative nature, we’ll explain this type of configuration as we come to topics in the book that can be configured.
(由于这些配置属于管理性质,我们会在本书中遇到配置的主题时再讲解)
DECLARING YOUR APPLICATION’S ARCHITECTURE(struts2 比较简单,只需要实现一些动作)
The more important type of configuration, which we’ll refer to as declarative architecture, involves defining the Struts 2 components that your application will use and linking them together—or wiring them—to form your required workflow paths.
(这种类型的配置更重要,我们称之为声明性架构,包含定义应用程序使用的struts2组件,以及将他们的连接起来形成需要的工作流路径)
By workflow path, we mean which action fires when a particular URL is hit, and which results might be chosen by that action to complete processing.
(这里说的工作流路径是指当一个特定的URL被单击时会触发哪个动作,以及该动作会选择哪个结果来完成处理流程)
Declarative architecture is a specialized type of configuration that allows developers to create an application’s architecture through description rather than programmatic intervention.
(声明性架构是一种特别的配置方式,这种类型允许开发者通过描述而不是硬编码的方式来创建一种应用型程序的结构)
The developer describes the architectural components in high-level artifacts, such as XML files or Java annotations, from which the system will create the runtime instance of the application.
(开发人员使用高级工件来描述架构组件,例如:XML文件或java注解,系统会应用高级化组件来创建应用程序的运行时实例)
The developer needs only to declare which objects will serve as the actions, results, and interceptors of their application.
(开发人员仅仅需要声明哪些对象作为应用程序的动作、结果和拦截器)
This process of declaration primarily consists of specifying which Java class will implement the necessary interface. Almost all of the Struts 2 architectural components are defined as interfaces.
(这个声明过程主要包括哪个java类实现哪个接口。几乎所有的struts2组件都被定义为接口)
In reality, the framework provides implementations for nearly all of the components you’ll ever need to use.
(实际上,框架提供了你可能用到的所有的组件实现)
For instance, the framework comes with implementations of results to handle many types of viewlayer technologies.
(例如,框架包含了很多结果的实现,以支持不同类型的显示技术)
Typically, a developer will only need to implement actions and wire them to built-in results and interceptors.
(一般说来,开发者仅仅需要实现动作,之后将他们内建的结果和拦截器关联起来)
Furthermore, the use of intelligent defaults and annotations can further reduce the manual tasks needed in this area.
(此外,使用智能默认值和注解可以 进一步减少配置过程中所需要的手工任务)
Two mechanisms for declaring your architecture(声明你架构的两种方式:xml 和 annotation)
As you can see, whether your application’s Struts 2 components are declared in XML or in annotations, the framework translates them into the same runtime components.
(如你所看到的,不管使用XML方式还是java注解方式声明应用程序的struts2组件,框架都会将他们转化为相同的运行组件)
In the case of the XML, we have the familiar XML configuration document with elements describing your application’s actions, results, and interceptors.
(在XML例子中,我们使用带有描述应用程序的动作、结果和拦截器等元素的XML配置文档)
Now, the metadata is collected in Java annotations that reside directly within the Java source for the classes that implement your actions.
(所有的元数据都集中放在java注解中,这些注解直接驻留在实现动作的类对应的java源代码中)
Regardless of which method you use, the framework produces the same runtime application.
(选择哪种声明的样式要比主要取决于你的偏好)
Many of you are already familiar with the use ofXMLfor declarative software development.
(和许多使用XML用来声明软件开发类似)
(框架使用一个特别的文件作为进入这个大的描述的入口点)
This entry point is the struts.xml file.
WHICH METHOD SHOULD YOU USE?(你该使用哪一种呢?)
(就因为这个,这个文档的根目录不是存放敏感信息的安全场所)
If you add some features that we don’t use in this book, you might need to add additional JARs.
However, it also tries to exercise all of the core Struts 2 architectural components.
(你在servlet容器上部署应用,从我们之前看到的菜单中选择HelloWorld连接)
Note that we’re starting with the XML version, not the annotated version.
(注意我们是从XML版本开始,而不是注解版本)
HELLOWORLD DETAILS
We’ll begin by looking at the architectural components used by HelloWorld.
(我们将通过使用HelloWorld来研究结构组件)
We’ve also said that many developers use this root document to include other XML documents, allowing for modularization.
(我也提到许多开发者使用根文档包括其他XML文件,以便模块化)
We’ve done this for the sample application, modularizing on the basis of chapters.
(示例程序就是这样做的,按照章来分模块)
Though off topic, we should note that the constant element ① can be used to set framework properties;
(这里需要说明常量元素①可以用来设置框架的属性)
You can also do this with property files, as we’ll see later.
(你同样能够用属性文件设置,稍后我们将会看到)
Also off topic, we should note that struts.xml is a good place to define some global actions in a default package.
(同时还需要说明,我们应该注意到struts.xml在默认包中定义一些全局动作)
Since our main menu doesn’t belong to any of our modularized mini-applications, we place it here.
(由于主菜单不属于任何模块化的迷你应用程序,所以我们把它放在这里)
Finally back on topic, we see the most important aspect of the struts.xml file, a long list of includes that pull all of our chapter-based XML documents into the declarative architecture.
(最后我们回到主题,我们看看struts.xml最重要的方面,一个长长的清单,这些清单包含将所有按照章节组织的文档引入到声明性架构)
All of these files will be pulled into this main document, in line, to create a single large XML document.
(所有这些文件会按照内联的方式被引入到主文档,以创建一个大的XML文档)
This is true for all the examples in this book, but when we print listings here we’ll remove the comments for clarity.
(本书中的所有例子都是这样的,为了清单打印清晰,我们移除了这些注释)
The only other elements here are the struts root element and the package element.
(这里仅有其它元素是struts根元素和package元素。)
The struts element is the mandatory document root of all Struts 2 XML files and the package element is an important container element for organizing your actions, results, and other component elements.
(struts元素是所有struts2 XML文件的强制性的文档根元素,package元素是一种重要的容器元素,用来组织应用程序的动作元素、结果元素和其它组件元素)
For now, the only thing we need to note about the package element is that it declares a namespace that’ll be used when the framework maps URLs to these actions.
(我们需要注意的唯一事情是关于package元素,它声明了一个当框架将URL映射到动作时会用到的命名空间)
Figure 2.6 shows how the namespace of the package is used to determine the URL that maps to our actions.
(图2-6展示了如何使用包的命名空间来决定映射到动作的URL)
The URL combines the servlet context with the package namespace and the action name.
(这个URL组合了servlet上下文、包的命名空间以及动作名称)
It merely forwards to the page that will present the user with a form to collect her name.
(它只是转到呈现给用户一个收集名字的表单的页面)
This keeps the application’s architecture consistent, prewires your workflow in anticipation of increases in complexity, and hides the real structure of your resources behind the logical namespace of the Struts 2 actions.
(这个可以让应用程序的架构保持一致性,可以预先防备工作流预计增加的复杂度,并且可以将资源的真正结构隐藏在struts2动作的逻辑命名空间之后)
While we could technically use a URL that hits the form JSP directly, a well-accepted best practice is to route these requests through actions regardless of their lack of actual processing.
(虽然从技术上来说我们能够使用URL来指向一个JSP表单,但是一个被广泛接受的最佳实践是,尽管有没有真正的处理,也使用动作来转发这些请求)
As you can see, such pass-through actions do not specify an implementation class.
(就像你看到的一样,类似这样转发用的动作不需要指定一个实现类)
They’ll automatically forward to the result they declare.
(它们将会自动指向它们定义好的结果页面)
This action points directly at the NameCollector.jsp page, which renders the form that collects the name.
(这个动作直接指向NameCollector.jsp页面,它呈现收集用户的名单)
At this point, we provide this listing only for the sake of full disclosure.
(现在,我们提供代码清单2-6的目的是为了展示其中的内容)
The HelloWorld action satisfies that contract by providing an execute() method that returns a string.
(HelloWorld 动作通过提供一个返回字符串的execute()方法来满足这个契约)
The only other important thing to note is the presence of JavaBeans properties to hold the application domain data.
(需要注意的是,这里用到了JavaBeans属性存放应用数据)
For now, recall that the action, as the MVC model component of the framework, both contains the business logic and serves as a locus of data transfer.
(现在,想一想作为框架MVC模型的组件的动作,既包含了业务逻辑,又为数据传输提供了场所)
Though there are other ways the action can hold the data, one common way is using JavaBeans properties.
(虽然动作有其他的方式来存放数据,但一种通用的方式是使用JavaBeans属性来存放)
The framework will set incoming data onto these properties when preparing the action for execution.
(当准备执行动作的时候,框架将会把访问的数据先存放到属性上面去)
First, let’s clear up some potential confusion regarding the location of data in the framework.
(首先,让我们说明一下数据在框架中的位置这个概念)
This is great because it allows convenient access to data from the action’s execute() method.
(因为动作的execute()方法可以很方便的访问数据)
So that the rest of the framework can access the data, the action object itself is placed on the ValueStack.
(为了框架的其它部分访问数据,这个动作对象本身也被放在ValueStack中)
The mechanics of the ValueStack are such that all properties of the action will then be exposed as toplevel properties of the ValueStack itself and, thus, accessible via OGNL.
(ValueStack机制就像所有动作属性一样,都会被作为ValueStack的第一级属性公开出来,这样可以通过OGNL来访问)
As figure 2.7 shows, the action holds the data, giving its own Java code convenient access.
(图2-7显示,动作用来装载数据,是为了动作组件的Java代码方便访问这些数据)
At the same time, the framework makes the properties of the action available on the ValueStack so that other regions of the framework can access the data as well.
(与此同时,框架在ValueStack上提供了这些动作的属性,以至于框架的其它区域能很好的访问数据)
In terms of our HelloWorld application, the two most important places this occurs are on the incoming form and the outgoing result page.
(在我们HelloWorld应用上,两个最重要地方发生在来自表单的数据和去向结果的页面)
In the case of the incoming request, the form field name attribute is interpreted as an OGNL expression.
(在请求的例子中,表单字段的name属性被当做OGNL表达式解析)
The expression is used to target a property on the ValueStack; in this case, the name property from our action.
(这个表达式用来指向ValueStack上的属性,此时是动作的name属性。)
The value from the form field is automatically moved onto that property by the framework.
(来自表单的值通过框架自动移动到对应的属性上)
On the other end, the result JSP pulls data off the customGreeting property by likewise using an OGNL expression, inside a tag, to reference a property on the ValueStack.
(在另一个端,JSP也需要在一个标签内使用指向ValueStack上一个属性的OGNL表达式取出属性customGreeting上的数据)
Obviously, this complicated process needs more than a quick sketch.We’ll cover it fully, particularly in chapters 5 and 6.
(很显然,这个复杂的过程需要更清晰的描述。我们会在5和6章特别的提到)
HelloWorld using annotations
As we’ve said, the annotations are placed directly in the source code of the actions.
(就像我们说的,注解直接使用在动作的源码上)
If we tell the framework where we keep our action classes, it will automatically scan them for annotations.
(如果我们告诉框架,我们的动作类在哪儿,框架将为了注解自动扫描他们)
The location of our actions is specified in an initialization parameter to the Struts 2 FilterDispatcher, defined in the web.xml deployment descriptor for the application.
(动作的位置在Struts2拦截器的初始化参数上设置,在应用程序的web.xml部署描述上定义)
But just telling the system where our action classes are isn’t enough. In addition, we must somehow identify which classes are actions.
( 但是只告诉框架动作类在哪里是不够的。另外,我们必须识别哪个类是动作类)
To mark our classes as actions, we either make our actions implement the com.opensymphony.xwork2.Action interface or use a naming convention where our class names end with the word Action.
(标记动作类,我们可以让我们的动作实现com.opensymphony.xwork2.Action接口或使用命令约定,也就是所有动作类的命名以Action结尾)
Now that the framework knows how to find our annotations, let’s see how they actually work.
(现在框架知道如何查找注解,让我们看看它们如何精确的工作)
As we discuss annotations, we’ll refer back to their counterparts in the XML version of HelloWorld.
(当我们讨论注解时,我们将会重新提起XML版本的HelloWorld应用程序中的对应内容)
The most notable thing is that several of the elements disappear entirely.
(最值得关注的事情是几个元素完全消失了)
Most importantly, the framework assumes that our namespace for this package will be derived from the Java package namespace of the action class.
(最重要的是,框架假定包元素的命名空间从动作类java包的命名空间而来)
The former, probably more correctly labeled configuration, involves tweaking or tuning the behavior and performance of the framework.
(对框架自身的配置,可能更适合称为配置,它包含了对框架的性能和行为的调节和调整)
The latter plays a much more central role in the development of our web applications;
(在我们web应用开发中,对应用程序框架的配置扮演一个非常核心的角色)
While annotations are considered by many to be more elegant than XML, we’ve opted to use XML because of its educational convenience.
(虽然很多开发人员认为java注解比XML更加优雅,但是为了便于说明,我们选择使用XML)
With the high-level overviews, architectural glosses, and the obligatory HelloWorld out of the way, we’ve officially completed the introductory portion of the book.
(在进行了宏观介绍及讲述了架构和必要的HelloWorld应用后,我们正式的完成了本书介绍部分的学习)
summary (我们来看看HelloWorld运营机制)
1、示例目录结构
First, all of the top-level directories, except WEB-INF, are in the document root of the web application.
(首先,所有的第一层应用目录,除了WEB-INF之外,都在web应用程序的文档根目录中)
One important thing to note about the document root is that these resources can potentially be served as static resources by the servlet container.
(一件非常重要的事情需要注意:文档根目录的这些资源能够被servlet容器作为静态资源使用)
Because of this, the document root is not considered a secure place for sensitive material.
(就因为这个,文档根目录对于一些敏感信息的来说不是安全场所)
if you want to see the absolute minimum set of JARs, you should check out HelloWorld.war, referenced in an earlier sidebar.
(如果你想查看Struts 2必需的最小的JAR集合,可以参看之前讲解的HelloWorld.war文件)
This file, formally known as the deployment descriptor, contains definitions of all of the servlets, servlet filters, and other Servlet API components contained in this web application.
(WEN-INF文件的正式名称是部署描述符,它包含了web应用所有的servlet、servlet过滤器和其他servlet API组件的定义)
For a Struts 2 application, the most important elements in this deployment descriptor are the filter and filter-mapping elements that set up the Struts 2 Filter-Dispatcher.
(对于Struts 2应用来说,在部署描述符中最重要的元素是filter和filter-mapping元素,它们组成了Struts 2的Filter-Dispatcher)
This servlet filter is basically the Struts 2 framework.
(这个servlet过滤器是Struts 2框架的基础)
This filter will examine all the incoming requests looking for requests that target Struts 2 actions.
(它检查所有传入的请求,查找指向Struts 2动作的请求)
The other important thing about the configuration of the Filter- Dispatcher is the initialization parameter that we pass in.
(另外一个关于Filter-Dispatcher重要的配置是我们传入的初始化参数)
The actionPackages parameter is necessary if you’re going to use annotations in your application.
(如果你在你的应用中使用注解,那么这个actionPackages参数就会被用到)
In fact, since Struts 2 uses a servlet filter rather than a servlet, many Struts 2 applications won’t have any servlets in them—unless you count compiled JSPs.
(实际上,由于Struts 2使用Servlet过滤器而不是Servlet,所以很多Struts 2应用程序不包含任何Servlet -- 除非JSP编译得到的Servlet也算在内。)
Since it’s not uncommon to integrate other servlets with the framework, we’ve included another servlet, as seen in listing 2.3, in our web application.
(由于整合框架和其它的servlet并不罕见,所以我们在应用程序包含了另外一个servlet)
Also off topic, we should note that struts.xml is a good place to define some global actions in a default package.
(同时还需要说明struts.xml文件是在默认包内定义全局动作的好地方)
Since our main menu doesn’t belong to any of our modularized mini-applications, we place it here.
(由于主菜单不属于任何模块化迷你应用程序,所以我们把它放在这里)
The struts element is the mandatory document root of all Struts 2 XML files and the package element is an important container element for organizing your actions, results, and other component elements.
(struts元素是所有Struts 2 XML文件的强制性的文档根元素,package元素是一个重要的容器元素,用来组织应用程序的动作、结果、和其它组件元素)
For now, the only thing we need to note about the package element is that it declares a namespace that’ll be used when the framework maps URLs to these actions.
(现在,对package元素,唯一需要注意的地方是它声明了一个当框架将URL映射到动作时会用到的命名空间)