Struts1教程手册
MVC模式
Jsp/Servlet Web常见架构:
- Jsp --> Jsp
Jsp页面数据提交给Jsp处理,并显示。 典型应用如Jive。
- Jsp -> Servlet --> Jsp
Jsp页面数据提交给Servlet处理,由Servlet推出Jsp页面。前者Jsp是显示输入数据;后者Jsp是显示处理结果。这是MVC模式实现。
Struts的MVC流程图如下:
- View 显示视图实现。使用Jsp技术;使用特定标签库提供与显示相关的控制功能,从而完全杜绝Jsp中的Java代码。
- Controller 控制协调。使用Servlet等技术;接受Jsp数据或推出Jsp视图。Struts的Action类似Servlet,通过Command配置去除了Servlet冗余代码,简洁高效。
- Model 后台模型。表示业务层。
注意:
1. 在Jsp中不写入与显示无关的Java代码。
2. 在Servlet中不写入业务核心功能代码。
使用Struts符合面向对象的设计和MVC模式:将界面离散表单数据字段包装成对象,将这个对象为业务层服务,从而保证业务核心是OO。分离了显示和控制以及业务核心,并且可对页面流程进行灵活控制。实际项目中变化最大就是页面流程。
Struts的开发步骤:
- 创建ActionForm实现
ActionForm是数据表单的对象实现。 - 创建Action实现
完成其execute()方法。 - 创建数据表单Jsp和结果Jsp
- 配置Struts-config.xml
Action代码实现
编写一个类,
继承org.apache.struts.action.Action,
实现execute方法:
public ActionForward execute(ActionMapping actionMapping,//对应配置
ActionForm actionForm,//表单对象
HttpServletRequest request,
HttpServletResponse response)
Action负责页面流程控制、前后台交互。将编写的Action类配置在页面流程控制struts-config.xml:
<action name=“xxxForm” path=“/xxxAction” scope=“request“ type="com.jdon.XxxViewAction">
<forward name="forward" path="/xxx.jsp" />
</action>
使用DispatchAction,克服一个Action只能一个方法的缺点,
Struts-config.xml中在<action>中加入配置parameter="method“。
在Jsp中提交加入:<input type="hidden" name="method" value="signon" />
ActionForm
ActionForm是表单的抽象对象,AF字段对应表单的字段,AF是数据对象。 AF也是界面对象,是Domain Model界面实现。
MyActionForm extends ActionForm{
String id;
public void setId(String id){ this.id = id}
public String getId(){ return id;}
}
ActionForm的生命周期
Scope有三种:request、session和application。
Request过程描述:
1. 当用户点按数据表单的提交submit按钮,ActionForm实例随request产生,被Struts使用request.setAttribute保存在request中。
2. Action接受ActionForm后,经过处理推出forward结果Jsp页面。
在一个Request经过的各个环节中,都可以获得相同的ActionForm实例,相当于使用request.getAttribute方法。
ActionForm创建:
//首先检查struts-config.xml配置映射中的scope值。
if ("request".equals(mapping.getScope())) {
// 如果是request,将ActionForm对象保存其中
request.setAttribute(mapping.getAttribute(), form);
} else {
//否则认为是Session,将ActionForm对象保存其中
HttpSession session = request.getSession();
session.setAttribute(mapping.getAttribute(), form);
request.setAttribute(mapping.getAttribute(), form);
}
ActionForm获得:
首先检查struts-config.xml配置映射中的scope值。
if ("request".equals(mapping.getScope())) {
// 如果是request,从其中获得ActionForm对象
request.setAttribute(mapping.getAttribute(), form);
} else {
//否则认为是Session,从其中获得ActionForm对象
HttpSession session = request.getSession();
session.setAttribute(mapping.getAttribute(), form);
request.setAttribute(mapping.getAttribute(), form);
}
通过下塑ActionForm获得
在action子类的具体方法XXXX中downCast:
public ActionForward XXXX(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
//ActionForm作为execute方法的输入参数
FiltersForm filtersForm = (FiltersForm) form;
return mapping.findForward("forward");
}
Jsp标签
标签两部分组成:tld配置和tagclass类代码组成。
标签使用:在jsp中首先需要导入tld配置;在web.xml中配置tld配置(URI--Location);
可以自行编写拓展标签库。 标签库优点在jsp中消灭java代码。
Struts标签
优点:
- 杜绝Jsp中的Java代码;
- 方便书写,如:
<html:form action=“/xxxAction.do”>无需在action值中指定Web名称,直接以/为开头。
- 以struts标签替代html相应语法。
标签的作用:
实现离散表单项目和对象之间的转换,实际就是一个转换配置。类似ORM中映射配置,也属于映射配置。为什么有人不喜欢用标签?如果没有对象概念,当然没有转换映射的需求,所以不会用标签。
标签的原理:
标签基本单元:name 和property
- Name: struts在当前scope(取决于配置,一般是request)中寻找符合name值的对象,实质是request.getAttribute(name值)。
- Property:通过反射机制,寻找name对象中是否存在property这个方法。执行PropertyUtils.getProperty方法
神奇核心:PropertyUtils
org.apache.commons.beanutils.PropertyUtils是apache的一个通用包功能:
使用Java Reflection APIs方便从一种高度来透过getter和setter操作所有JavaBean的属性。
- copyProperties方法:将一个对象属性值拷贝到另外一个对象相同属性中去。
- getProperty(aaa,bbb)方法:返回一个特定bean的特定属性值,相当于”aaa.getBbb”.
常用标签:
- 表单标签:html:form html:hidden html:text
- 单纯输出:bean:write
- 逻辑控制标签:logic:iterate
- 参数定义:bean:define bean:parameter
通过标签获得ActionForm:
一个表单一个ActionForm,表单的字段对应ActionForm的字段。
<html:text name=“ActionForm名称” property=“ActionForm字段”/>
………
<html:hidden …..
表单标签标签简化写法
<html:form action=“/xxxAction.do”>
<html:text property=“id” />
<html:text property=“name” />
</html:form>
没有声明name,缺省是和xxxAction相关配置。在struts-config.xml中的action配置中的name值。
通过标签获得任何对象:
设置该对象到当前scope中:
- request.setAttribute(“xx”, xx);
- bean:define name=xx property
通过两种方式获得:
- request.getAttribute();
- 通过标签的name定位。
复杂标签:
复杂标签: html:select html:option,
运行输出的html:
<select name=“”>
<option name=“”></option>
<option name=“”></option>
</select>
逻辑标签:
<logic:iterate id=“” name=“” property=“”> 显示集合中每个元素
</logic:iterate>
通过logic,替代了Jsp中本用于逻辑控制的Java代码。
将property中Collection集合遍历出来,并将单个对象保存到request的arrtibute中。
多行相同项目设计:
1.在ActionForm对于Collection字段提供get单个对象方法:
public UserProperty getUserProp(int index) {
return (UserProperty)((List)userProps).get(index);
}
2.在jsp:
<html:text property="userProp[0].name" />
增删改查流程
新增功能:推出一个空白表单的Jsp页面;修改页面:则先从数据库中查询,推出一个有数据表单的Jsp页面。
修改功能:
1. 查询已经存在的数据;
2. 显示修改表单
3. 接受修改的数据并保存数据库
设计
ViewAction,专门用于控制输出Jsp界面 ViewAction有输入参数Action的值,根据Action的值来判断是新增还是修改。
Action值如为空或为create值(如http://xxx/viewAction.do?action=create),则直接输出新增性质的JSP页面,
Action值如为edit(如http://xxx/viewAction.do?action=edit)
输出编辑性质的JSP页面
1. 创建一个JSP页面,既用于新增页面,也用于修改页面。将该Jsp页面作为ViewAction的输出页面。该Jsp页面结构如下:
<html:form action=”/XXXSaveAction.do”>
<html:hidden property="action" />
<!—该action的值是调用viewAction.do?action参数的值 -->
…….
</html:form>
该Jsp提交到SaveAction
2. 创建SaveAction,它用来接受提交表单的数据,不同于ViewAction专门用于输出Jsp表单页面,该Action专门用于接受Jsp表单页面提交的数据。
SaveAction中主要是调用业务层Service实现数据持久化操作,
Struts中组件编程
系统对外均是以action为切入点。
一个表单对应一个对象的特点的约束,通过变通手段实现复杂页面。
Action是导演;ActionForm是演员。
在Action和ActionForm上做文章:
1. 一个Action 多个ActionForm;
2. 多个Action 一个ActionForm;
Struts中组件模型编程方案一:
将多个模型装入一个ActionForm中,如使用MapForm等机制。
Struts中组件编程方案二:
对多个流程首尾相连,第一Action forward结果是第二个Action,最后输出一个Jsp,在这个jsp中就可以使用前面多个流程的多个ActionForm了,这属于串行方式。
使用Tiles:
不同流程输出到同一个页面的不同区域。是一种并行处理方式。灵活复杂,适合大型系统。
验证方式:
- 即时验证:通过Jsp页面的javascript验证。
优点:即时提示强;
缺点:安全性不强。 - 后台验证:通过ActionForm等后台程序验证。
优点:安全性强;
缺点:即时性不够,需要表单提交后方可得知。
实际使用中是两者结合。
ActionForm出错机制:
实现public ActionErrors validate的方法,
激活struts-config.xml中validate=true,然后
配置application.properties,在struts-config.xml中加入:
<message-resources parameter=" application.properties "/>
为在Jsp中显示出错信息,html:errors
Action中验证:
ActionMessages errors =
new ActionMessages();
ActionMessage error =
new ActionMessage(“error.id”);
errors.add(ActionMessages.GLOBAL_MESSAGE, error);
saveErrors(request, errors);
Tiles
Tile是有关视图界面的组件。Tile主要是将一个页面划分成几个部分,分别对应不同的JSP,大大提高了视图界面元素的可重用性。 适合门户系统;可应付不断变化的页面设计要求
Tiles优点
传统include缺点:
- 无法修改页面模板
- 容易导致include页面嵌套。
- 可以完全更改整个页面设计,没有阻碍
- 可以做适合不同用户的页面定制
语法对比
Jsp的include:
<jsp:include page="/header.jsp" />
Tiles相应语法
<tiles:insert page="/header.jsp" flush="true"/>
页面设计两个元素:
1 布局 layout
页面设计,什么区域放置什么内容等
2 组成部分
具体区域,是一个具体实体。
Tiles的语法
<tiles:insert page="/layout.jsp" flush="true">
<tiles:put name="header" value="/header.jsp"/>
<tiles:put name="body" value="/body.jsp"/>
<tiles:put name="footer" value="/footer.jsp"/>
</tiles:insert>
其中layout.jsp是布局设计Jsp, 其他是具体区域实体Jsp.
Tiles步骤:
- 做一个网页模板,将header、menu、body等嵌入位置。
- 配置tiles-defs.xml文件作为struts-config.xml的plugin启动。
- 配置tiles-defs.xml内部:指定tiles名称和具体jsp页面对应。
- 形成action --- > Tiles名称--- >jsp关系。