java 私塾随堂笔记——Struts1.0
一.Struts1是什么?
基于MVC的轻量级,web应用框架。
二.有什么?
[table]
[tr][td=1,1,134][b]Strust1[/b][/td][td=1,1,326][b]描述[/b][/td][td=1,1,108][b]Strust2[/b][/td][/tr]
[tr][td=1,1,134]Servlet-ActionServlet[/td][td=1,1,326]控制器,接受用户请求和状态改变,以及发出视图选择[/td][td=1,1,108]FilterDispatcher[/td][/tr]
[tr][td=1,1,134]Action[/td][td=1,1,326]控制器的一部分,与模型交互,执行状态改变或状态查询,以及告诉ActionServlet 下一个选择的视图[/td][td=1,1,108][/td][/tr]
[tr][td=1,1,134]ActionForm[/td][td=1,1,326]状态改变的数据[/td][td=1,1,108]vo[/td][/tr]
[tr][td=1,1,134]ActionMapping[/td][td=1,1,326]状态改变事件[/td][td=1,1,108]xwork.xml[/td][/tr]
[tr][td=1,1,134]ActionForward[/td][td=1,1,326]用户指向或者视图选择[/td][td=1,1,108]Result[/td][/tr]
[/table]
三.运行流程
【此处有Struts1的运行流程图,可以到java 私塾官网下载完整笔记:www.javass.cn】
1.提交request→web容器(即tomcat);
2.依据web应用上下文找到web应用;如: <html: form action="/cc.do">
3.再依据部署描述文件web.xml找到ActionServlet
[code]
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>[/code]
4. ActionServlet接着大致执行顺序如下:
a.读struts-config.xml形成ActionMapping
b.依据path找到相应的Action类定义
<action path="/cc"
type="cn.javass.s2test.web.action.UserAction"
name="userForm"
scope="request"
input="/pages/add.jsp">
c.依据action定义找到Form的定义
<form-bean
name="userForm"
type="cn.javass.s2test.vo.UserForm">
</form-bean>
d.把页面参数填充到Form中
e.调用execute()
f.执行execute()得到ActionFoward
g.依据ActionFoward到mapping中去下一个页面
<forward name="toList" path="/pages/list.jsp" />
四.怎么做
1. 创建ActionForm
[code]
package cn.javass.s2test.vo;
import java.io.Serializable;
import java.util.*;
import org.apache.struts.action.ActionForm;
public class UserForm extends ActionForm implements Serializable {
private String uuid,userId,name;
private int age;
private Collection<UserForm> ufCol = new ArrayList<UserForm>();
@Override
public String toString(){
return "uuid=="+uuid+"userId=="+userId+"name=="+name+"age=="+age+"ufCol=="+ufCol;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uuid == null) 0 : uuid.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final UserForm other = (UserForm) obj;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Collection<UserForm> getUfCol() {
return ufCol;
}
public void setUfCol(Collection<UserForm> ufCol) {
this.ufCol = ufCol;
}
}[/code]
说明:
* ActionForm是一个JavaBean,需继承org.apache.struts.action.ActionForm类,它捕获通过HTTP请求传送的参数
* ActionForm针对每个HTML表单中的字段具有一个对应的属性
* ActionServlet匹配请求中的参数和ActionForm中的属性,并调用ActionForm中的setter方法,将参数传入ActionForm
* 我们的add.jsp有四个表单字段(下面将会看到),所以,我们需要定义ActionForm中相应的setter方法ActionForm中的getter/setter方法,可以通过Eclipse集成环境,自动生成
* ActionForm中的内部属性全部定义为私有的(private),并通过公共(public)的getter/setter方法来访问
2.创建Action类
[code]
package cn.javass.s2test.web.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import cn.javass.s2test.business.ebi.UserEbi;
import cn.javass.s2test.util.springhelp.SpringBF;
import cn.javass.s2test.vo.UserForm;
public class UserAction extends Action {
private UserEbi getEbi(){
return (UserEbi)SpringBF.getBF().getBean("user-ebi");
}
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
UserForm uf = (UserForm)form;
this.getEbi().create(uf);
uf.setUfCol(this.getEbi().getAll());
System.out.println("col============="+this.getEbi().getAll());
ActionForward af = mapping.findForward("toList");
return af;
}
}[/code]
说明:
* Action是一个Java类,需继承org.apache.struts.action.Action类
* ActionServlet将会组装ActionForm,并将它传递给Action
* Action 通常负责:
→ 输入校验
→ 调用业务逻辑类执行业务逻辑操作
→ 决定返回哪个ActionForward
* 我们的UserAction做了如下事情,这些是一个Action通常都会做的最典型的事情:
→ 将输入的ActionForm强制转换为UserActionForm
→ 从UserActionForm对象中获取数据信息
→ 执行数据信息的逻辑判断操作
→ 根据业务逻辑执行的结果,决定返回哪个ActionForward
3.创建Struts配置文件struts-config.xml
[code]
< xml version="1.0" encoding="ISO-8859-1" >
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<form-bean
name="userForm"
type="cn.javass.s2test.vo.UserForm">
</form-bean>
</form-beans>
<action-mappings>
<action path="/cc" type="cn.javass.s2test.web.action.UserAction"
name="userForm"
scope="request"
input="/pages/add.jsp">
<forward name="toList" path="/pages/list.jsp">
</forward>
<forward name="toUpdate" path="/pages/update.jsp">
</forward>
</action>
</action-mappings>
<message-resources parameter="MessageResources" />
</struts-config>[/code]
说明:
* struts-config.xml文件,是由ActionServlet读取的配置文件,它定义了所有关于Action、ActionForm、ActionForward等的详细信息
* <form-beans>标签内部可以包含多个<form-bean>标签
* <form-bean>标签必须指定name和type属性
→ name属性是给此ActionForm一个标识名称
→ type属性指定了此ActionForm是哪个类,必须是全路径的类名
* <action>标签可以配置的重要属性包括:
→ path-从页面上通过一个什么样的URL路径来访问Action(不包含.do)
→ type – 访问这个URL的时候,调用哪个Action类,这是Action的全路径类名
→ name – 这个属性用来标识哪个ActionForm将被创建,并将提交的表单组件给它
→ cope – FormBean的作用域范围,可以取值为session和request,一般取值都是request
创建add.jsp
[code]
<%@ page language="java" contentType="text/html; charset=gb2312";pageEncoding="gb2312"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新增页面</title>
</head>
<body>
<html:form action="/cc.do">
业务编号:<html:text property="uuid"></html:text><br>
用户编号:<html:text property="userId"></html:text><br>
用户姓名:<html:text property="name"></html:text><br>
用户年龄:<html:text property="age"></html:text><br>
<html:submit value="提交"></html:submit>
</html:form>
</body>
</html>[/code]
说明:
* 添加一个表单,action为cc.do,这个cc.do的意思,将会告诉struts的ActionServlet,它将需要调用哪个Action来处理这个表单的请求
* 添加输入域name,这个name的表单字段,必须跟UserActionForm中的属性一致
运行流程:
* 当你从浏览器输入地址:http://localhost:8088/web/pages/add.jsp,Tomcat将按通常情况来处理这个JSP并返回浏览器
* 当你提交表单,实际上是提交到了这样一个URL地址:http://localhost:8088/web/cc.do,Tomcat将会根据web.xml的配置,将这个请求发送给相应的Servlet,在我们的应用中,Tomcat将会把这个请求发送给org.apache.struts.action.ActionServlet这个类(请参看web.xml的配置)
* 然后ActionServlet根据struts-config.xml的配置信息,调用UserAction对象去处理这个请求,在此之前,它会将页面表单的请求数据封装到UserForm对象中,并传递给LoginAction
* UserAction返回一个ActionForward对象,包含了将要转向的路径信息
* ActionServlet根据这个ActionForward对象所包含的路径信息,调用相应的页面去执行响应
Struts1和Struts2的区别和对比:
* Action 类:
·Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
·Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。
* 线程模式:
·Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
·Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
* Servlet 依赖:
·Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
·Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。
* 可测性:
·测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
·Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
* 捕获输入:
·Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。
·Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。
* 表达式语言:
·Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
·Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL).
* 绑定值到页面(view):
·Struts 1使用标准JSP机制把对象绑定到页面中来访问。
·Struts 2 使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
* 类型转换:
·Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
·Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。
* 校验:
·Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
·Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性
* Action执行的控制:
·Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
·Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。
* MyEclipse支持struts1,不支持struts2.
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。