Struts是Java开发中应用最广泛的MVC框架,Struts1.x就是原来的Struts框架,Struts2.x为原来的WebWork框架,它们代表着两种不同的设计思想。
1、Servlet是多线程的。JeanBean是一种用Java语言写成的可重用组件,要编写JavaBean,类必须是具体类和公共类,并且具有无参数的构造器。JavaBean设计模式提供两种类型的方法来访问bean的内部状态:访问器用来读JavaBean的状态,修改器用来改变JavaBean的状态。修改器以小写的set前缀开始,后跟属性名,属性名的第一个字母必须大写,返回值通常是void,访问器以小写的get为前缀,后跟属性名,第一个字母必须大写,如果访问器返回一个逻辑值则属性名以小写的is为前缀。在使用JavaBean时,规范的方法体签名扮演了极为重要的角色。
2、Servlet/JSP规范0.92,提出Model2,servlet处理数据存取和导航流,JSP处理表现。当某个路径被请求时,Servlet就查询ActionMapping对象,ActionMapping对象告诉servlet,哪些个Action、ActionForm和ActionForward将要被本次请求使用,关于这些细节都在struts-config.xml文件中定义。ActionServlet在启动时读取这个配置文件,并创建一个配置对象数据库。
Struts组件
3、ActionForm是一个JavaBean,它扩展了org.apache.struts.ActionForm类,这个对象捕获经过请求传送的输入,ActionForm针对浏览器请求的HTML表单中的每个字段具有一个对应的属性,ActionServlet匹配请求的参数和ActionForm中的属性,当匹配好后ActionServlet为属性调用setter方法,并将请求中的值传入ActionForm。
Action是一个Java类,它扩展了org.apache.struts.Action,ActionServlet负责组装ActionForm,然后将其传递给Action,Action通常负责输入校验、访问业务信息,以及决定向Servlet返回哪个ActionForward。
struts-config.xml文件包含了ActionServlet需要用来处理应用请求的详细信息。
当收到一个请求时,ActionServlet做的第一件事情就是查找ActionMapping来匹配请求的路径,ActionMapping是根据struts-config.xml文件创建的JavaBean。
《Struts in Action》第一例编译时会报错:UserDirectory Not Found,是因为需要定义两个类,内容如下:
UserDirectory:
package com.kfc.struts.action;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.net.URL;
public class UserDirectory {
private static final String UserDirectoryFile =
"resources/users.properties";
private static final String UserDirectoryHeader =
"${user}=${password}";
private static UserDirectory userDirectory = null;
private static Properties p;
private UserDirectory() throws UserDirectoryException {
java.io.InputStream i = null;
p = null;
i = this.getClass().getClassLoader().
getResourceAsStream(UserDirectoryFile);
if (null==i) {
throw new UserDirectoryException();
}
else {
try {
p = new Properties();
p.load(i);
i.close();
}
catch (java.io.IOException e) {
p = null;
System.out.println(e.getMessage());
throw new UserDirectoryException();
}
finally {
i = null;
}
} // end else
}
public static UserDirectory getInstance() throws
UserDirectoryException {
if (null==userDirectory) {
userDirectory = new UserDirectory();
}
return userDirectory;
}
public String fixId(String userId) {
return userId.toUpperCase();
}
public boolean isValidPassword(String userId, String password) {
// no null passwords
if (null==password) return false;
// conform userId to uppercase
String _userId = fixId(userId);
// no passwords for non-users
if (!isUserExist(_userId)) return false;
// does password match user's password
return (password.equals(getPassword(_userId)));
}
public boolean isUserExist(String userId) {
// no null users
if (null==userId) return false;
// if not null, it's a user
return !(null==p.getProperty(userId));
}
public String getPassword(String userId) {
return p.getProperty(userId);
}
public Enumeration getUserIds() {
return p.propertyNames();
}
public void setUser(String userId, String password) throws
UserDirectoryException {
// no nulls
if ((null==userId) || (null==password)) {
throw new UserDirectoryException();
}
try {
// conform userId to uppercase when stored
p.put(fixId(userId), password);
String o = this.getClass().getClassLoader().getResource(UserDirectoryFile).getFile();
p.store(new FileOutputStream(o), UserDirectoryHeader);
}
catch (IOException e) {
throw new UserDirectoryException();
}
}
} // end UserDirectory
UserDirectoryException:
package com.kfc.struts.action;
public class UserDirectoryException extends Exception {
// ; Empty implementatio
}
4、Struts的核心是一个MVC的控制器,搭起了Model和View之间的桥梁。
ActionForward:开发人员可以将超链接定义为一个ActionForward,这些对象都有一个逻辑名称和一个path属性,这使得开发人员可以设置path,然后通过名称来引用ActionForward,这个元素事实上是创建了一个ActionForward JavaBean,并设置了这个bean的属性。
ActionForm:ActionForm设计用来处理来自HTML表单的输入,最终事实也是创建了一个JavaBean,Struts自动匹配JavaBean属性和表单控件的属性,开发者只需要定义ActionForm类,其余的就交给Struts。
Action:HTML表单使用action参数来告诉浏览器将数据送到何处,Struts提供相应的Action类来接收数据。Action根据返回到控制器的ActionForward对象做出控制流的决定。为保证可扩展性,控制器也传递当前的请求和响应对象,实际上,Action可以做所有Java Servlet可以做的事情。在Struts1.1中,新的execute方法应该是首选,它允许更好的异常处理。
ActionMapping:ActionMapping对象给定制动作一个URI,允许将同一个Action对象定义未不同的ActionMapping。
ActionServlet:Struts完全在幕后工作,它将其他组件绑定在一起。
5、Struts提供JSP标签库,和JSP页面一起使用,简化HTML表单和访问Action要转发的其他数据。
6、单独使用JSP的是Model1,结合使用JSP和Servlet被称为Model2,也被称为MVC模式。
Struts通过提供一个控制器Servlet实现了Model2架构:
核心Struts类和MVC的对应
除了核心类,Struts使用一些配置文件和视图助手来沟通控制器和模型:
Struts配置文件
为将Struts配置数据暴露给视图,框架以JSP标签形式提供了大量的助手类:
实践中,控制器和视图的交互通过请求,会话以及Servlet平台提供的应用上下文进行,控制器和模型的交互通过文件和数据存储系统完成。
7、Struts控制流
请求-响应流程
8、在web.xml中,有
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
将ActionServlet映射到那些符合/do/*样式的请求,许多应用喜欢使用前缀*.do。当ActionServlet收到一个请求,它通过一系列的流程处理locale、mapping、form bean、最后是Action来运行这个请求,包含的步骤有:处理多部分请求、处理路径、处理场所、处理内存和缓存、处理映射、处理角色、处理ActionFrom、处理组装、处理验证、处理转发和包含、处理Action。
Action执行要求的行为,可以包括:访问数据库系统、在请求中创建被视图使用的对象、如果需要在会话中创建对象、根据需要更新会话对象、执行需要的业务功能、处理意外和其它错误条件、直接返回一个响应或返回一个ActionForward给Servlet。
Struts不仅是线程安全的,也是线程依赖的。
9、Struts1.0弱点:
Struts1.1弱点:
Struts优点:
10、Jsessionid是一个容器维护的关键字,用来通过HTTP跟踪用户,在一个超链接中包含一个会话关键字称为URL重写。Servlet规范鼓励使用cookie来维护会话,当这种方法行不通时,可使用URL重写来代替。
11、除了Java类和一个JSP页面之外,开发人员必须创建或修改几个配置文件,包括:web.xml、struts-config.xml、Build.xml(Ant构建需要)、Application.properties。
反射,告诉我们Java类提供什么方法,自省则帮助我们推断出这些方法哪些是可以在运行时用来配置JavaBean的属性。这些配置文件最后会被用来创建一个一个Java对象。
12、Struts标签提供了标准的方式来组装控件,每个HTML标签对应一个标准的HTML标记元素,每个JSP标签都有一个属性项提供bean中的属性名称。标签会从JavaBean中获取属性,并将它作为HTML元素的value来插入。属性指field。任何JavaBean都可以用于Struts JSP标签以组装控件,但为了要提供输入的自动校验,Struts使用它自己的JavaBean子类ActionForm。一旦HTML表单的输入传递给ActionForm bean,并且经过了属性校验,所有的属性就作为一个漂亮整齐的JavaBean传递给Action。
13、ActionForm的要求:必须扩展自org.apache.struts.action.ActionForm,必须为每个应该从请求中获取的HTML输入控件定义一个公共属性,如果你要求ActionForm在传递属性到Action之前校验它们就必须实现validate方法,如果想在组装之前初始化属性必须实现reset。
map支持的ActionForm以及DynaActionForm。ActionForm不是一个普通的JavaBean,它有validate方法,可以 被ActionServlet调用,以确保数据输入是正确的。
数据的生命周期循环
14、ActionForward代表一个应用的URI,可以包含完整的URI,也可以包含一个查询组件。ActionForward是一个简单富有效率的包装类,其基类仅有4个属性:
当ActionServlet调用Action时,Action的mapping对象要传递给它,mapping对象包含一个局部转发的列表以及一个全局转发的链接。
15、ActionMapping描述了框架是如何处理每一个离散的业务操作的,当一个请求到来,ActionServlet利用path属性来选择对应的ActionMapping,ActionMapping的基本属性:
Web运行于URI之上,大多数URI都映射到物理文件。
16、Action类像一个小型的Servlet,在Struts应用中,Servlet扮演者分派器的角色,Action对象则干实际的工作。Servlet引用ActionMapping列表来选择一个Action处理请求。Actions是多线程的,当需要Action时,ActionServlet通过Action的perform或execute方法来调用。一个典型的Action的职责:校验前提条件或者声明、调用需要的业务逻辑方法、检测其他处理错误、将控制路由到相关视图。
17、ActionServlet的3个扩展点:RequestProcessor、ExceptionHandler和Plugin Action。
18、Struts标签和JSTL互补,4类重要的标签库:
19、Tiles是一个使用简单有效的标记来实现模板和布局的框架。Velocity模板旨在要求比相应的JSP更少的代码和更快速的渲染。Velocity模板语言VTL,简单强大。