一、复习

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写起来比较简单