0 序... 2
0.1猜想... 2
0.2 HTTP,HTML,User Agents. 2
0.3 HTTP 请求/响应周期... 2
0.4 Java语言和应用框架... 2
0.5 JavaBeans. 2
0.6属性文件和资源绑定... 3
0.7 JavaServlet 3
1介绍... 5
1.1Struts的历史... 5
1.2 MVC模式... 6
1.3 Struts控制流程... 7
2 创建模型组件... 8
2.1概述... 8
2.2 JavaBean和作用域... 8
2.3 ActionForm Bean. 9
2.4系统状态Bean. 9
2.5商业逻辑Bean. 9
3 创建视图组件... 9
3.1 概述... 9
3.2 国际化信息... 9
3.3Forms 和 FormBeans的交互... 11
3.4 其他表示层技术... 13
4 创建控制(Controller)组件... 15
4.1 概述... 15
4.2 ActionServlet 15
4.3 ActionForm类... 16
4.4 Action类... 19
4.5 异常处理器... 20
4.6 插件类... 20
4.7 ActionMapping的实现... 20
4.8 编写Action Mappings. 21
4.9 在页面中使用ActionMapping. 22
4.10 在ActionMapping中使用通配符... 22
4.11 公共的Log 接口... 23
5. 配置应用... 23
5.1 概述... 23
5.2 Struts配置文件... 23
5.3 为应用配置模块... 25
5.4 WEB应用部署描述符... 25
0 序
0.1猜想
本手册适合于有创建Java Web 应用经验的Web 开发人员.在开始学习Struts之前你应该了解如下的技术:
1. HTTP,HTML,User Agents
2. HTTP 请求/响应生命周期
3. Java语言和应用框架
4. JavaBeans
5. 属性文件和资源绑定
6. Java Servlets
7. Java Server Pages ,JSP Tag Librariy
8. XML
0.2 HTTP,HTML,User Agents
WWW是基于超文本传输协议和超文本标识语言建立的.
用户代理,比如浏览器,他们使用HTTP去请求一个文档然后格式化显示.
0.3 HTTP 请求/响应周期
对于Web开发者来说,理解HTTP的请求和响应周期是很重要的.你要使用HTTP发送一个请求,然后服务器给你一个响应.当你创建WEB应用时,你需要返回一个响应对象来回应请求.
0.4 Java语言和应用框架
Struts是用JAVA编写的.JAVA是面向对象的语言,而Struts充分利用了面向对象的技术.除此而外JAVA支持线程.如果你很好的掌握了JAVA,特别是面向对象编程和线程,这将会有益于最有效的使用Struts和这个手册.
0.5 JavaBeans
象大多数JAVA应用一样,大多数Struts对象都是JavaBean.遵循JavaBean设计模式使得Struts更容易被开发者和JAVA开发工具使用.尽管JavaBean的最初是用来开发可视元素的,但它对开发可重用组件也非常有益.
0.5.1反射和内省
反射是决定什么样的函数或域存在某对象中的方法.内省是反射的特殊形式.
使用内省就可以知道哪些方法将会被其他对象使用(如getter,setter)
Struts框架使用内省来转换HTTP参数到JAVABEAN的属性中和把JAVABEAN中的属性数据组装到HTML的域.
0.5.2 MAP
JAVABEAN把数据存在属性中.JAVABEAN虽然是灵活而功能强的对象,但它并不是编程者存储数据的唯一对象.另一个熟为人知的对象是java.util.Map.Map它是一个名字/值对的数据集合,它经常用来存储动态数据.
0.5.3 DynaBeans
DynaBeans集成了JAVABEAN 的扩展性和MAP的灵活性.编写JAVABEAN要创建一个新类,并且要为每个属性编写方法.DynaBeans则将属性放在XML中配置.
在Struts应用中,你可以使用DynaBeans来描述你的HTML Form,这个策略可以避免编写普通的JAVABEAN来存储很简单的属性.
0.6属性文件和资源绑定
JAVA应用包括WEB应用的配置经常使用属性文件来完成. Struts的消息资源都是通过资源绑定和属性文件实现的.
JAVA资源绑定使用一个或多个属性文件来实现应用的国际化.
0.7 JavaServlet
由于JAVA是面向对象的语言,因此JAVA平台已经将HTTP转换成对象的形式.这将会使JAVA 程序员关注于应用本身而不是HTTP.
HTTP提供了一个标准的机制来扩展服务器的功能,我们称之为CGI. 服务器将请求发送到CGI程序,CGI程序则返回一个响应.同样的任何JAVA服务器则会接收请求,然后转发到Servlet.
Servelt 是javax.servlet.http.HttpServlet的子类,每个Servlet必须完成四个方法:
* public void init(ServletConfig config)
* public void doGet(HttpServletRequest request, HttpServletResponse response)
* public void doPost(HttpServletRequest request, HttpServletResponse response)
* public void destroy()
Struts提供了一个可用的Servlet--org.apache.struts.action.ActionServlet.
作为一个Struts开发者,你只需要编写对象供ActionServlet调用就行了.但是,理解Servlet并熟悉他在JAVA WEB应用中扮演的角色那是最好不过了.
0.7.1 Servlets 和多线程
为了提高性能,Servlet设计程多线程.每个Servlet仅创建一个实例,每一个请求都传递到同一个对象.这将有利于Servlet容器充分的利用资源.因此doGet,doPos在编程时必须保证他是线程安全的.
0.7.2 Servlet Context
ServletContext(javax.servlet.ServletContext)定义了Web 应用中Servlet的视图.在Servlet中通过getServletConfig()可以访问得到,在JSP中则通过隐式对象application得到.ServletContext提供了几个对于创建Struts应用来说非常有用的几个方法:
1.访问WEB应用资源 Servlet通过getResource(),getResourceAsStream()可以访问WEB应用中的静态资源文件.
2.Servlet Context属性 Servlet上下文可以存储JAVA对象到属性中.这些属性对整个WEB应用都可见.
0.7.3 Servlet请求
Servlet请求就是javax.servlet.http.HttpServletRequest,通过它可以访问HTTP请求的所有信息:
1. Cookies 通过getCookies()可以得到当前请求的所有cookie
2. HTTP头 HTTP请求的头可以通过对应的名字来访问.你当然可以通过枚举来列出所有的头.
3. 参数 你可以通过参数来访问HTTP请求的URL的参数或表单中的内容.
4. 请求特性 HTTP请求表单的提交方式(GET/POST),用的是什么协议(HTTP/HTTPS)
5. 请求URI信息 通过getRequestURI()可以得到最初的请求URI,除此之外,我们还可以得到contextPath,servletPath,pathInfo
6. 用户信息 如果你正使用容器来进行安全管理,你可以得到一个Principal对象来代表当前用户,并确认该用户是否拥有某叫角色的权限.
Servlet请求拥有请求级别的属性,与前面提到的应用级别属性类似.请求级别的属性经常用来传递状态信息到可视化组件(如JSP).
Servlet容器保证被Servlet处理的请求处于单线程内.因此你不必担心在访问request对象的属性时会有多线程的问题.
0.7.4 Servlet响应
Servlet的功能就是接收请求,然后生成相应的响应. 这是通过调用javax.servlet.http.HttpServletResponse的方法实现的.
1.设置头 你可以设置包含在响应中的头.最重要的头就是Content-Type,它用来告诉客户端内容的格式,比如:text/html代表html,text/xml代表XML
2.设置Cookies 你可以加入cookie到当前的响应中
3.发送错误响应 你可以使用sendError()发送一个HTTP错误编号
4.重定向到其他资源 你可以使用sendRedirect()定向到另外一个URL
使用Response API的一个最重要的原则就是:操作Header,Cookie的任何方法必须在第一次输出缓冲区满且发送到客户端前调用.
0.7.5过滤
如果你的Servlet容器是基于Servlet规范2.3或更高,那么你就可以使用javax.servlet.Filter来对请求和响应作些处理.许多filter聚合在一起,每一个filter都有机会来对请求和响应做处理.
Struts1.0,1.1,1.2只需要Servlet规范2.2,因此这些版本的Struts并不支持filter.
Struts从1.3开始就需要Servlet规范2.3的容器了.
0.7.6 Session
HTTP的一个关键特性就是无状态,因此我们不知道某个请求是否是来自同一用户的请求,这将会使跨请求的会话变得很艰难.
为了解决这个问题,Servelet实现了一个javax.servlet.http.HttpSession.Servlet容器将采用Cookie或URL Rewriting来保证接邻近的请求包含session id来标识该请求是同一个session.因此保存在session中的属性可以被多个请求共享.
为了不浪费资源,Session有一个可配置的超时时间设置.如果两个请求间的时间差超过了超时时间间隔,那么session中的数据会失效.你可以定义一个默认的超时时
查看本文来源
3.4 其他表示层技术
尽管外观可以用JSP或Struts的标签来实现,但你仍然应该考虑融合其他技术来提高组件的重用,减少维护工作量,减少错误。
3.4.1 特定应用标签
忽略
3.4.2使用包含组合页面
将一个页面放在一个JSP文件中是一个普遍的设计方法,但是许多应用需要将应用中的不同部分显示在一个页面中。例如一个门户应用需要如下功能:
1. 访问门户的搜索引擎
2. 访问门户的讨论区
3. 用户感兴趣的话题
4. 邮件等待指示器
将这些不同的功能交给不同的开发者开发,要完成这个门户应用是比较容易的。然后你就可以使用包含( include)来
将它们组合到一个页面中。有三种不同的包含方式,选择哪种取决于你希望整个输出在什么时候整合:
1. <%@ include file="xxxxx" %>
2. <jsp:include page="xxxxx" flush="true" />
3. bean:include
3.4.3 使用Tiles组合页面
Tiles是一个功能很强的模板库,它可以将很多tile组合成最终的视图。以下是设置向导:
1.创建layout/layout.jsp,它包含标准外观
<html>
<body>
<tiles:insert attribute="body"/>
</body>
</html>
2.创建你的主页/index.jsp
<h1>This is my homepage</h1>
3.创建文件/WEB-INF/tiles-defs.xml
<tiles-definitions>
<definition
name="layout"
path="/layout/layout.jsp">
<put name="body" value=""/>
</definition>
<definition name="homepage" extends="layout">
<put
name="body"
value="/index.jsp"/>
</definition>
<tiles-definitions>
4.在文件struts-config.xml中设置TilesPlugin
<plug-in
className="org.apache.struts.tiles.TilesPlugin">
<set-property
property="definitions-config"
value="/WEB-INF/tiles-defs.xml"/>
</plug-in>
5.在struts-config.xml文件中设置一个Action指向你的主页
<action path="/index" type="org.apache.struts.actions.ForwardAction" parameter="homepage"/>
3.4.4 图片渲染组件
一些应用需要动态产生图片,有两种方法符合如下需求:
1. 产生一个执行Servlet请求的超链接 Servlet将使用图形库来产生图片
2. 将JAVA Applet嵌入在HTML页面中来产生图片
3.4.5 文本输出
一些应用需要动态的产生文本(如XML),因为整个页面将通过PrinterWriter输出,我们可以通过设置PrinterWriter的属性来做到:
response.setContentType("text/plain"); // or text/xml
PrintWriter writer = response.getWriter();
// use writer to render text
return(null);
3.4.6 Struts EL 标签库
Struts基本的标签都是依赖rtexprvalue(runtime scriptlet expression)来动态计算属性
的值,例如,要根据资源关键值打印来自属性文件中的信息
<bean:message key='<%= stringvar %>'/> 这样写是假定stringvar是JSP中的
脚本变量,如果使用Struts的EL标签库就会是如下形式:
<bean-el:message key="${stringvar}"/>
4 创建控制(Controller)组件 4.1 概述
我们已经知道如何去构建Model和View组件,现在我们将集中到Controller组件。Struts包含了一个映射请求URI到Action类的Servlet。因此你编写WEB应用时在Controller组件这方面要做的工作如下:
1.编写AtionForm作为Model和View的中介
2.编写Action(继承org.apache.struts.action.Action)来处理请求
3.为每一个逻辑请求在struts-config.xml.中编写一个ActionMapping
4.2 ActionServlet
对于熟悉MVC架构的人来讲,ActionServlet就代表着 C ? Controller。Controller的任务是:
1.处理用户请求
2.根据用户请求来决定用户将要完成什么任务
3.将Model的数据传到视图(View)
4.选择合适的视图响应请求
Controller会将大部分工作放到Request Processor和Action 类中。
4.2.1 请求处理器(Request Processor)
RequestProcessor对每个请求做核心处理的地方,它要做的处理如下:
1.processPath - 确定请求的路径,以备后面的处理检索ActionMapping
2.processLocale ? 为请求选择一个locale
3.processContent - 设置默认的内容(Content)类型.
4.processNoCache ? 设置响应头:Pragma,Cache-Control,Expires
5.processPreprocess - RequestProcessor让子类重载实现,默认返回真(True),如果子类重载此方法并返回真,则该请求将继续处理流程,如果返回假,则意味着你处理了该请求,处理流程直接返回。
6.processMapping - 确定请求所对应路径的ActionMapping
7.processRoles - 保证请求的用户具备特定的角色
8.processActionForm - 实例化ActioForm并且把它放在适当的作用域中。
9.processPopulate - 用请求中的数据组装ActionForm
10.processValidate - 校验ActionForm中的数据
11.processForward - 如果映射是一个转向( Forward)指令,就转向到特定的路径。
12.processInclude - 如果映射是一个包含(Include)指令,就将映射指定的路径的输出结果包含进来。
13.processActionCreate - 实例化映射指定的Action.
14.processActionPerform ? 执行Action的perform或excute方法。
15.processForwardConfig - 最后RequetProcessor使用Action类返回的ActionForward来选择下一个资源。大多数的AtionForward将会导航到显示页面输出响应。
4.3 ActionForm类
一个ActionForm代表着一个与用户交互的HTML表单。ActionForm中的属性来存储表单中的状态,并且有getter,setter方法来访问他们。ActionForm可以存储在session或request的作用域中(默认的是session).如果ActionForm放在session中记得要实现reset方法,以备每次使用ActionForm时都会初始化。Struts根据请求中的参数设置ActionForm的属性并且把经过校验后的ActionForm传到Action的execute方法。
当你在编写ActionForm时必须坚持如下原则:
1.ActionForm本身没有任何特定的方法被实现。仅仅用来表示它是整个框架中一个特定的角色。ActinForm中只有getter,setter方法,并没有任何商业逻辑。
2.AtionForm提供标准的校验机制。如果你重载了ActionForm的validate方法,并且在资源属性文件中提供了错误消息,那么Struts就会自动校验表单中的数据。当然你也可以忽略ActionForm中的校验,在Action类中来实现校验。
3.为输入表单中的每一个输入定义属性。输入域的名称和ActionForm中属性的名称必须符合JAVA规范。例如一个输入域的名称username将会导致ActionForm中的setUsername被调用。
4.也可以为Form中的按钮或其他控件定义属性。当提交表单时这将有利于你知道哪个控件被选中了。
5.把ActionForm当作HTTP和Action之间的防火墙。ActionForm的方法可以校验所有必须的属性已经存在了并且包含合理的值。如果校验失败请求将不会被Action类处理。
6.你可能会放一个Bean的实例在ActinForm中,这样你就会用到嵌套属性引用。例如,你可能有一个“customer”在ActionForm中,然后在页面中用“customer.name”来引用属性。
4.3.1 DynaActionForm
维护一个具体的ActionForm是要耗费时间的。特别是ActionForm越来越多并且都是校验一些简单的属性时你可能会感觉到一股挫折感。
这个瓶颈通过DynaActionForm会有所减轻。通过在Struts的配置文件中列出属性,类型和默认值来替代以前的定义一个新类,并且添加getter/setter方法。例如,在struts-config.xml中添加一个UserForm:
<form-bean
name="UserForm"
type="org.apache.struts.action.DynaActionForm">
<form-property
name="givenName"
type="java.lang.String"
initial="John"/>
<form-property
name="familyName"
type="java.lang.String"
initial="Smith"/>
</form-bean>
DynaActionForm支持的数据类型:
java.lang.BigDecimal
java.lang.BigInteger
boolean and java.lang.Boolean
byte and java.lang.Byte
char and java.lang.Character
java.lang.Class
double and java.lang.Double
float and java.lang.Float
int and java.lang.Integer
long and java.lang.Long
short and java.lang.Short
查看本文来源