1、MVC设计模式
实现MVC(Model、View、Controller)模式的应用程序由三大部分构成:
①模型:封装应用程序的数据和业务逻辑 POJO(Plain Old Java Object)
②视图:实现应用程序的信息显示功能 JSP
③控制器:接受来自用户的输入,调用模型层,响应对应的视图组件。Servlet / Filter
- 使用Filter作为控制器的比servlet好(FilterChain这个APIservlet中没有)
使用一个过滤器来作为控制器,可以方便地在应用程序里对所有资源(包括静态资源)进行控制访问。servlet不擅长拦截资源
2、Struts2概述
Struts2是一个用来开发MVC应用程序的框架,它提供了Web应用程序开发过程中一些常见问题的解决方案。
- 对来自用户的输入数据进行合法验证
- 统一的布局
- 可扩展性
- 国际化和本地化
- 支持Ajax
- 表单的重复提交
- 文件的上传和下载
- ........
3、Struts2 VS Struts1
体系结构方面:
①类更少,更高效:在Struts2中无需使用“ActionForm"来封装请求参数
②扩展更容易:Struts2通过拦截器完成了框架的大部分工作,在Struts2中插入一个拦截器对象相当简便易行。
更容易测试:
①即使不使用浏览器也可以对基于Struts2的应用进行测试
4、Struts2的HelloWorld
①搭建Struts2的环境
- 加入jar包:复制struts\lib下的所有需要的jar包到当前web应用的lib目录下
- 在web.xml文件中配置struts2
- 在当前web应用的classpath下添加struts2的配置文件(D:\JavaWeb\JavaWeb-jar包\struts2\struts-2.3.16.1\src\core\src\main\resources\struts-2.3.dtd) 注意:key type是URI
②action VS Action类
action:代表一个struts2的请求。
Action类:能够处理Struts2请求的类。(普通的Java类,可以有属性和方法,同时必须遵守下面这些规则)
- 属性的名字必须遵守与JavaBean属性名相同的命名规则。属性的类型可以是任意类型,从字符串到非字符串(基本数据类型)之间的数据转换可以自动发生。
- 必须有一个不带参的构造器:通过反射创建实例。
- 至少提供一个struts在执行这个action时调用的方法。
- 同一个Action类可以包含多个action方法。
- Struts2会为每一个HTTP请求创建一个新的Action实例,即Action不是单例的,是线程安全的。
5、在Action中访问Web资源
①什么是Web资源:HttpSerletRequest、HttpSession、ServletContext等原生的Servlet API。
②为什么访问Web资源:B\S的应用的Controller中必然需要访问WEB资源(例:向域对象中读写属性、读写Cookie、获取realPath...)
③如何访问:
---和Servlet API解耦的方式:只能访问有限的Servlet API对象,且只能访问其有限的的方法(读取请求参数、读写域对象属性、使session失效.....)。
>使用ActionContext:Action执行的上下文对象,在ActionContext中保存了Action执行所需的所有对象。
>实现XxxAware接口
>选用建议:若一个Action类中有多个action方法,且多个方法都需要使用域对象的Map或parameters,则建议使用Aware接口的方式。
>session对应的Map实际上是SessionMap类型的!强转后若其调用其invalidate()方法,可以使session失效。
---和Servlet API耦合的方式:可以访问更多的Servlet API对象,且可以调用其原生的方法。
>使用ServletActionContext
>实现ServletXxxAware接口
6、关于Struts2请求的扩展名问题
①打开org.apache.struts2包下的default.properties中配置了Struts2应用的一些常量
②有一个常量struts.action.extension定义了当前Struts2应用可以接受的请求的扩展名
③可以在struts.xml文件中以常量配置的方式修改default.properties所配置的常量
<constant name="struts.action.extension" value="action,do,"></constant>
7、ActionSupport
①ActionSupport是默认的Action类:若某个action节点没有配置class属性,则ActionSupport即为待执行的Action类,而execute方法即为默认执行的action方法
<action name="testActionSupport">
<result>/testActionSupport.jsp</result>
</action>
②在手工完成字段验证,显示错误消息,国际化等情况下,推荐继承ActionSupport
8、result
①result是action节点的子节点
②result代表action执行后可能去的一个目的地
③一个action节点可以配置多个result子节点
④result的name属性值对应的action方法可能有的一个返回值
<result name="success">/success.jsp</result>
<result name="index">/index.jsp</result>
⑤result一共有2个属性,还有一个type:表示结果的响应类型
⑥result的type属性值在struts-default包的result-types节点的name属性中定义
常用的结果类型有:dispatcher(默认的):转发
redirect :重定向。注意:通过redirect的响应类型也可以便捷的实现redirectAction的功能。
redirectAction:重定向到一个Action
chain:转发到一个Action。注意:不能通过type=dispatcher的方式转发到一个Action!
转发到一个Action只能是:
<result name="test" type="chain">
<param name="actionName">testAction</param>
<param name="namespace">/atguigu</param>
</result>
不能是:
<result name="test">/atguigu/testAction.do</result>
9、通配符映射
一个web应用可能有成百上千个action声明,可以利用struts提供的通配符映射把多个彼此相似的映射关系简化为一个映射关系。
<action name="UserAction-*" class="com.struts2.actions.UserAction"
method="{1}">
<result name="{1}-success">/success.jsp</result>
</action>
①通配符时的映射规则:
---若找到多个匹配,没有通配符的那个将胜出。
---若指定的动作不存在,Struts将会尝试把这个URI与任何一个包含着通配符*的动作名及进行匹配
---被通配符匹配到的URI字符串的子串可以用{1},{2}来引用,{1}匹配第一个子串,{2}匹配第二个子串
---{0}匹配整个URI
---若Struts找到的带有通配符的匹配不止一个,则按先后顺序进行匹配
---*可以匹配零个或多个字符,但不包括/字符,如果想把/字符包括在内,需要使用**,如果需要对某个字符进行转义,需要使用\
10、OGNL
OGNL:在JSP页面上可以利用OGNL(Object-Graph-Navigation Language:对象-图导航语言)访问到值栈(ValueStack)里的对象的属性。
若希望访问值栈中contextMap的数据,需要给OGNL表达式加上一个前缀字符#,如果没有前缀字符#,搜索将在ObjectStack里进行。
①关于值栈:
---helloworld时,${productName} 读取productName值,实际上该属性并不在request等域对象中,而是从值栈中获取的
---ValueStack:
>可以从ActionContext中获取值栈对象
>值栈分为两个逻辑部分
Map栈:实际上是一个OgnlContext类型,实际是个Map,也是对ActionContext的一个引用,里边保存
各种Map:requestMap、sessionMap、applicationMap、parametersMap、attr
对象栈:实际上是CompoundRoot类型,是一个使用ArrayList定义的栈,里边保存各种和当前Action实例相关的对象
是一个数据结构意义的栈
②Struts2 利用s:property标签和OGNL表达式来读取值栈中的属性值
---值栈中的属性值:
>对于对象栈:对象栈中某一个对象的属性值
>Map栈:request,session,application的一个属性值或一个请求参数的值
---读取对象栈中对象的属性:
>若想访问Object Stack里的某个对象的属性,可以使用以下几种形式之一:
object.propertyName; object['propertyName']; object["propertyName"]
>ObjectStack里的对象可以通过一个从零开始的下标来引用,ObjectStack里的栈顶对象可以用[0]来引用,它下面的那个对象可 以用[1]引用
[0].message
>[n]的含义是从第n个开始,而不是只搜索第n个对象
>若从栈顶对象开始搜索,则可以省略下标部分:message
>结合s:property标签: <s:property value="[0].message" />
---默契情况下,Action对象会被Struts2自动的放到值栈的栈顶
11、声明式异常处理
异常处理:exception-mapping元素
①exception-mapping元素:配置当前action的声明式异常处理
②exception-mapping元素中有两个属性
---exception:指定需要捕获的异常类型,异常的全类名
---result:指定一个响应结果,该结果将在捕获到指定异常时被执行,既可以来自当前action声明,也可以来自global- results声明
③可以通过global-exception-mappings元素为应用程序提供一个全局性的异常捕获映射,但在global-exception-mappings元素下 声明的任何exception-mapping元素只能引用在global-results元素下声明的某个result元素
④声明式异常处理机制由ExceptionMappingInterceptor拦截器负责处理,当某个exception-mapping元素声明的异常被捕获到时,ExceptionMappingInterceptor拦截器就会向ValueStack中添加两个对象:
---exception:表示被捕获异常的Exception对象
---exceptionStack:包含着被捕获异常的栈
注:可以在视图上通过<s:property/> 标签显示异常消息
12、通用标签
①property标签:用来输出一个值栈属性的值
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
default | String | 可选,如果value值为null或没有给定,将显示该属性值 | |
escape | boolean | true | 可选,是否要对HTML特殊字符进行转义 |
value | String | <来自栈顶对象> | 将要显示的值 |
示例:
---输出Action属性customerId的值:<s:property value="customerId" />
---输出session属性userName的值:<s:property value="#session.userName" />
如果value属性没有给出,ValueStack值栈栈顶对象的值被输出
在许多情况下,JSP EL可以提供更简洁的语法。
②url标签:用来动态的创建一个URL
名字 | 类型 | 默认值 | 说明 |
action | String | 可选,指定生成的url为哪个action | |
anchor | String | 可选,指定被创建的url的链接点 | |
encode | boolean | true | 可选,是否要对参数进行编码 |
escapeAmp | boolean | true | 可选,是否要对“#”进行转义 |
IncludeContext | boolean | true | 可选,是否要把当前的上下文包括进来 |
IncludeParam | String | get | 可选,指定是否包含请求参数,可以取3个值之一:one、get、all |
method | String | 可选,指定action的方法,当用action属性来生成url时,如果指定该属性,url将链接到指定的action方法 | |
namespace | String | 可选,指定url的命名空间 | |
portletMode | String | 可选,指定结果页面的partlet模式 | |
portletUrlType | String | 可选,指定将被创建的URL是一个partlet,还是actionURL | |
scheme | String | 可选,指定使用什么协议:http、https | |
value | String | 可选,指定将生成的url值(如果新建URL的不是一个action的话) | |
var | String | 可选,指定用来被压入ContextMap中的键值 | |
windowState | String | 可选,当用在一个portlet环境里时,用来指定portlet的窗口状态 |
③param标签:用来把一般参数传递给包含着它的那个标签
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | String | 将传递给外层标签的参数的名字 | |
value | String | 将传递给外层标签的参数的值 |
---无论在给出value值时有没有使用%{},Struts都会对它进行OGNL解析。
---如果想传递一个String类型的字符串作为参数值,必须把它用单引号括起来。
---可以把value属性的值卸载开始标签和结束标签之间,利用这种方式来传递一个EL表达式的值。
④set标签:用来在以下Map对象里创建一个键值对
---ValueStack值栈的ContextMap值栈
---Map类型的session对象
---Map类型的application对象
---Map类型的request对象
---Map类型的page对象
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | String | 将被创建的属性的值 | |
value | String | 该键所引用的对象 | |
scope | String | default | 目标变量的作用范围,可取值是application、session、request、page和default |
⑤push标签:功能和set相似
---push标签把一个对象压入ValueStack而不是压入ContextMap
---push标签在标签起始时把一个对象压入栈,标签结束时将对象弹出栈。
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
Value | String | 将被压入Value Stack栈的值 |
⑥if,else标签和elseif标签
这三个标签用来进行条件测试,它们的用途和用法类似于if,else,elseif关键字,其中if和elseif必须有test属性
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
test* | Boolean | 测试条件 |
⑦iterator标签:用来遍历一个数组,Collection或一个Map,并把这个可遍历对象里的每一个元素依次压入和弹出ValueStack栈
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | 将被遍历的可遍历对象 | |
struts | org.apache.struts2.views.jsp.IteratorStruts | ||
var | String | 用来引用这个可遍历对象中的当前元素的变量 |
在开始执行时,iterator标签会先把IteratorStruts类的一个实例压入ContextMap,并在每次遍历循环是更新它,可以将一个指定IteratorStruts对象的变量赋给struts属性.
iterator标签的status属性的属性值
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
index | integer | 各此遍历的下标值(从零开始) | |
count | integer | 当前遍历的下标值域或“index+1” | |
first | boolean | 如果当前元素时可遍历对象里的某一个元素,这个值将为true | |
last | boolean | 如果当前元素时可遍历对象里的最后一个元素,这个值将为true | |
evn | boolean | 如果count属性的值是一个偶数,这个值将为true | |
odd | boolean | 如果count属性的值是一个奇数,这个值将为true | |
modulus | int | 这个属性需要一个输入参数,它的返除以那个熟人参数的余数回值是count属性值 |
⑧sort标签:用来对一个可遍历对象里的元素进行排序
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
comparator* | java.util.Comparator | 在排序过程中使用的比较器 | |
source | String | 将对之进行排序的可遍历对象 | |
var | String | 用来引用因排序而新生成的可遍历对象的变量 |
⑨date标签:用来对Date对象进行排版
名字 | 类型 | 默认值 | 说明 |
---|---|---|---|
format | String | 可选,日期的格式 | |
name* | String | 将被排版的日期值 | |
nice | boolean | false | 可选,指定是否输出指定日期和当前日期之间的时间差 |
var | String | 可选,用来引用被压入ValueStack栈的日期值的变量 |
⑩a标签
a标签将呈现为一个HTML连接,这个标签可以接受HTML语言中的a元素怒所能接受的所有属性。