一、复习
1.复习xml的基本内容
2.DTD约束:Xml文件使用DOCTYPE声明语句来指明它所遵循的DTD文件,DOCTYPE声明语句有两种形式:
(1).当引用的文件在本地时,采用如下方式:
<!DOCTYPE 文档根节点 SYSTEM “DTD文件的URI” >
(2).当引用的文件是一个公共的文件时,采用如下方式:
<!DOCTYPE 文档根节点 PUBLIC “DTD名称” “DTD文件产URL” >
3.DTD约束语法
在DTD文档中使用ELEMENT声明一个xml元素,语法格式如下:
<!ELEMENT 元素名称 元素类型>
元素类型可以是元素内容、或类型
如为元素内容:则需要使用()括起来,如
<!ELEMENT 学校 (班级,老师,学生人数)>
<!ELEMENT 班级 (#PCDATA)>
如为元素类型,则直接书写,DTD规范定义了如下几种类型:
EMPTY:用于定义空元素,例如<br/> <hr/>
ANY:表示元素内容为任意类型。
在元素内容中也可以使用+、*、?等符号表示元素出现的次数:
+:一次或多次(班级+)
?:0次或一次(班级?)
*:0次或多次(班级*)
设置说明:
#REQUIRED:必须设置该属性。
#IMPLIED:可设置也可不设置。
#FIXED:说明该属性的取值固定为一个值,在xml文件中不能为该属性设置其它值,但需要为该属性提供这个值。
直接使用默认值:在xml中可以设置该值也可以不设置该属性值。若没设置则使用默认值。
CDATA:普通文本字符串类型。
#PCDATA:该内容模型说明元素中可以同时出现文本和元素。
ENUMERATED:枚举类型。
ENTITY:实体类型
2.xml解析方式分为两种:dom和sax
dom:将整个文档读入到内存中,作为一个完整的document对象,优点:对文档的增删改查比较方便,缺点:占用内存大
sax:优点:占用内存下,解析速度快。缺点:只适合做文档的读取
3.dom和dom4j的crud 收获:
在删除节点的时候,首先取得这个节点,然后在获取这个节点的父节点,在调用父节点的方法删除这个节点,最后将内存中的document对象写入到文档中。
dom删除节点:
Element p2 = (Element)document.getElementsByTagName("p").item(1);
p2.getParentNode().removeChild(p2);
dom4j删除节点:
Element p1 = document.getRootElement().element("body").element("p");
p1.getParent().remove(p1);
二、struts2的新内容(视频笔记)
I.struts2执行前半过程:
1.浏览器发送一个请求到StrutsPrepareAndExecuteFilter.doFilter(ServletRequest, ServletResponse, FilterChain)方法
2.创建一个StrutsActionProxy(StrutsAction代理),然后调用它的execute()(execute方法是用作Action调用的入口函数)方法,这个对象有一个对DefaultActionInvocation的引用
调用其invoke()方法
3.DefaultActionInvocation去调用其他拦截器的intercept()方法 ,调用完之后回调DefaultActionInvocation的invoke()方法,再调用
下一个拦截器的intercept()方法,如此反复,到了最后一个拦截器掉完以后,在调用自己的invokeAction()方法,最终调用我们目标的Action()方法
StrutsActionProxy(action代理的作用):Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy的execute()方法
而该方法又调用了DefaultActionInvocation的invoke()方法
ActionInvocation就是Action的调用者。ActionInvocation在Action的执行过程当中,负责interceptor(拦截器).Action和Result等一系列元素的调度
II.Parameters 和 ModelDriven拦截器
1.Parameters 拦截器将把表单字段映射到ValueStack栈的栈顶对象的各个属性中,如果某个字段在模型里没有匹配的属性,param拦截器将会尝试ValueStack栈中的下一个对象
2.如果Action类实现了ModelDriven接口,则该ModelDriven拦截器将把ModelDriven接口的getModel()方法返回的对象置于栈顶
3.Action 实现 ModelDriven接口后的运行流程
1).先会执行ModelDrivenInterceptor的intercept方法
public String intercept(ActionInvocation invocation) throws Exception {
//获取Action对象:EmployeeAction 对象,此时该Action已经实现了ModelDriver接口
//public class EmployeeAction implements RequestAware,ModelDriven<Employee>
Object action = invocation.getAction();
//判断Action是否是ModelDriven的实例
if (action instanceof ModelDriven) {
//强制转换为ModelDriven类型
ModelDriven modelDriven = (ModelDriven) action;
//获取值栈
ValueStack stack = invocation.getStack();
//调用ModelDriven接口的getModel()方法
//即调用EmployeeAction 的getModel()方法
Object model = modelDriven.getModel();
if (model != null) {
//把getModel()返回的值压入到值栈的栈顶,实际上压入的是EmployeeAction的employee成员变量
stack.push(model);
}
if (refreshModelBeforeResult) {
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
}
}
return invocation.invoke();
}
2).执行ParametersInterceptor的intercept方法:把请求参数的值赋值给栈顶元素对应的属性,若栈顶元素没有对应的属性,则查询值栈中下一个对应的属性
体会:将employee成员变量压入到栈顶,并且通过ParametersInterceptor的intercept方法将前台传进来的值赋给employee的变量,而且在EmployeeAction中得到了这个经过赋值的employee变量,接下来就可以进行一系列操作,大大减少了代码长度,Action写起来比较简单