Struts2 中, HTML 表单将被直接映射到一个 POJO,通过params拦截器,类中定义对应属性,及对应set方法即可。
Struts2 中,任何一个POJO都可以是一个action类。
Struts2 会为每一个 HTTP 请求创建一个新的 Action 类的实例,即 Action 不是单例的,是线程安全的。
:8080/contextPath
必须有一个不带参的构造器,struts.xml中通过全类名反射创建类实例
在jsp页面中,request.setCharacterEncoding("UTF-8")设置编码是无效的,因为在其之前已经调用了request.getparameter()方法,也就是在javaBena的set方法之前已经调用了,正确处理是,在web.xml中的filter之前加上一个filter,要加在struts2的filter之前。
导入Struts2标签:
Struts2 动态方法调用,修改dafault.properties 中的配置可达到,不常用,不推荐使用,使用方法是/user!save.action,加上个!save。
<!-- 打开允许动态方法调用的开关, 默认是 false -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
//**************************Struts2 访问 web 资源**************************
在 Action 中, 可以通过以下方式访问 web 的 HttpSession, HttpServletRequest, HttpServletResponse 等资源
1、——与Servlet API解耦的方式(只能访问有限的API对象,及方法,方便 Action 做单元测试)
· 1.1、通过使用ActionContext(是Action执行的上下文对象,保存了parameters, request, session, application 等)
ActionContext actionContext = ActionContext.getContext();
Map<String, Object> applicationMap = actionContext.getApplication();
Map<String, Object> sessionMap = actionContext.getSession();
Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
Map<String, Object> parameters = actionContext.getParameters();
System.out.println(((String[]) parameters.get("name"))[0]);
` 1.2、通过Action类中实现接口:ApplicationAware、RequestAware、SessionAware(Action 类通过可以实现某些特定的接口, 让 Struts2 框架在运行时向 Action 实例注入 parameters, request, session 和 application 对应的 Map 对象)
· 选用建议:若一个Action类中有多个 action 方法,且多个方法都需要使用Map或者parameters,则建议使用Aware接口的方式
· 备注:session对应的Map实际上是SessionMap类型的,强转后,若调用其invalidate()方法,可以是session失效。
· 备注:Struts2 对 HttpServletRequest, HttpSession 和 ServletContext 进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象, 在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext 对应的 Map 对象来保存和读取数据.
2、——与Servlet API耦合的方式(可以访问更多的Servlet API对象,及其原生方法,直接访问 Servlet API 将使 Action 与 Servlet 环境耦合在一起, 测试时需要有 Servlet 容器, 不便于对 Action 的单元测试.)
· 2.1、通过使用ServletActionContext类
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
ServletContext servletContext = ServletActionContext.getServletContext();//和application一样
· 2.2、通过Action类中实现接口:
**************************Struts2 访问 web 资源**************************//
//**************************Struts2 扩展名**************************
org.apache.struts2 包下面的 default.properties 中配置了 Struts2 应用的一些常量。
struts.action.extension 定义了当前 Struts2 应用可以接受的请求的扩展名。
配置 Struts2 可以受理的请求的扩展名:在 struts.xml 文件中以常量配置的方式修改 default.properties 所配置的常量。
在<package>标签上面加上一行:
<constant name="struts.action.extension" value="action,do," ></constant>
这样,Struts2 就可以应答以 .action、 .do、不带后缀的请求。
**************************Struts2 扩展名**************************//
ActionSupport 是Struts2 默认的处理类,默认方法是 execute ,在手工完成字段验证,显示错误消息,国际化等情况下,推进继承ActionSupport类。该类实现了一些接口,如Action,为开发提供了一定的便利。
//**************************Struts2 结果类型**************************
dispatcher:默认的,转发的一个页面
redirect:重定向到一个页面
redirectAction:重定向到一个Action,通过redirect 响应类型,也能实现该功能。
<result name="index" type="redirectAction">
<param name="actionName">testAction</param>
<param name="namespace">/atguigu</param>
</result>
OR
<result name="index" type="redirect">/atguigu/testAction.do</result>
chain:转发到一个action,不能通过type=dispatcher 的方式转发到一个Action,只能是
<result name="index" type="redirectAction">
<param name="actionName">testAction</param>
<param name="namespace">/atguigu</param>
</result>
**************************Struts2 结果类型**************************//
//**************************值栈**************************
ValueStack :贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象.
Struts2 实际上吧ValueStack 放到请求域中了,键是 “struts.valueStack”
ValueStack 其中两个重要组成部分是,context(ContextMap,map栈)和root(实际意义上的值栈,ObjectStack),ContextMap里面会存入(parameters, request, session, application等这些map)
若希望访问值栈中 ContextMap 中的数据, 需要给 OGNL 表达式加上一个前缀字符 #. 如果没有前缀字符 #, 搜索将在 ObjectStack 里进行.
Struts2 利用 s:property 标签和 OGNL 表达式来读取值栈中的属性值
页面上,${name} 读取 name 值, 实际上该属性并不在 request 等域对象中, 而是从值栈中获取的.
Struts2 利用 s:property 标签和 OGNL 表达式来读取值栈中的属性值
1). 读取对象栈中对象的属性:
> 若想访问 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" /> <s:property value="message" />
2). 读取ContextMap中的属性:(如: <s:property value="#request.message" />)
>#object.propertyName ; #object['propertyName'] ;#object["propertyName"]
示例:
返回 session 中的 code 属性: #session.code
返回 request 中的 customer 属性的 name 属性值: #request.customer.name
返回域对象(按 request, session, application 的顺序)的 lastAccessDate 属性: #attr.lastAccessDate
**************************值栈**************************//
//**************************OGNL(要搭配<s:property)**************************
1). 可以利用 OGNL 调用
任何一个 Java 类里的静态字段或方法.( 静态属性:<s:property value="@java.lang.Math@PI"/>、静态方法:<s:property value="@java.lang.Math@cos(0)"/>)
被压入到 ValueStack 栈的对象上的公共字段和方法.
默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置 struts.ognl.allowStaticMethodAccess 标记变量的值为 true.
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
2). 调用对象栈的方法为一个属性赋值
> <s:property value="setName('zhangsan')"/>(赋值)
> <s:property value="name"/>(获取值)
3). 访问数组类型的属性(list一样,多了个.isEmpry()或者.isEmptyy,map有一点小不同,是通过map[key]的方式获得)
> <s:property value="#attr.name.lenth"/>
> <s:property value="#arrt.name[2]"/>
如果仅仅是访问值栈中的一个值,还是用EL方便些。
**************************OGNL**************************//
//**************************异常处理: exception-mapping**************************
exception-mapping 元素: 配置当前 action 的声明式异常处理
在action的result上面加上
> <exception-mapping result="响应结果" exception="要捕获的异常类型,异常全类名"></exception-mapping>
> <result name="响应结果">/error.jsp</result>
在jsp页面,展示异常
<s:property value="exception"/>、<s:property value="exception.message"/>如果用JSP EL,这里会更简洁
${exception}、${exception.message}
也可以配置全局的异常,和全局的异常结果,顺序不能错。如下
<global-results>
<result></result>
</global-results>
<global-exception-mappings>
<exception-mapping result="" exception=""></exception-mapping>
</global-exception-mappings>
**************************异常处理: exception-mapping**************************//
//**************************常用通用标签**************************
1、property
2、url 标签用来动态地创建一个 URL
<s:url value="/testUrl" var="url"></s:url>
${url }//创建并打印url:/status/testUrl
<s:url value="/testUrl" var="url">
<s:param value="1001" name="id"></s:param>//类似/testUrl?id=1001
</s:url>
<s:url value="/testUrl" var="url">
<!-- 如果value是变量,则会自动的进行ognl解析 -->
<s:param value="id" name="id"></s:param>
</s:url>
<s:url value="/testUrl" var="url">
<!-- 如果value是变量,则会自动的进行ognl解析,用单引号括起来,则不进行OGNL解析 -->
<s:param value="'id'" name="id"></s:param>
</s:url>
<!-- 构建一个请求action的地址 -->
<s:url action="testAction" namespace="/hello" method="save" var="url4"></s:url>
<!-- 结果是 /struts/hello/testAction!save.action -->
${url4 }
<!-- null;get:如果传过来的请求是get;all:如果传过来的请求是post -->
<!-- 结果是testUrl?nema=xxx -->
<s:url value="testUrl" var="url5" includeParams="get"></s:url>
${url5}
<s:url value="/testUrl" var="url">
<!-- 如果value是变量,则会自动的进行ognl解析,用单引号括起来,则不进行OGNL解析 -->
<s:param value="'id'" name="id"></s:param>
<s:param name="date" value="#session.date"></s:param>
</s:url>
3、param
> 无论在给出 value 值时有没有使用 %{}, Struts 都会对它进行 ognl 求值
> 如果想传递一个 String 类型的字符串作为参数值, 必须把它用单引号括起来.
4、set,用来向session application request page 域对象中加入属性值
<!-- 会自动进行OGNL解析 -->
<s:set name="sex" value="sex" scope="request"></s:set>
sex : ${requestScope.sex }
5、push
push 标签的功能和 set 标签类似.
push 标签将把一个对象压入 ValueStack 而不是压入 ContextMap.
push 标签在标签起始时把一个对象压入栈, 标签结束时将对象弹出栈.
在标签内部才有用
5、if, else 和 elseif 标签
6、iterator
iterator 标签用来遍历一个数组, Collection 或一个 Map, 并把这个可遍历对象里的每一个元素依次压入和弹出 ValueStack 栈
<s:iterator value="#request.persons">
${name }<br>
</s:iterator>
在开始执行时, iterator 标签会先把 IteratorStatus 类的一个实例压入 ContextMap, 并在每次遍历循环时更新它. 可以将一个指向 IteratorStatus 对象的变量赋给 status 属性.
7、sort,点击表单标签,进行升降序排序这种
8、date
<s:date name="date" format="yyyy-MM-dd hh:mm:ss" var="date2"/>
9、a(a 标签将呈现为一个 HTML 连接. 这个标签可以接受 HTML 语言中的 a 元素所能接受的所有属性. )
<!-- 使用%{将属性包装起来,使其强制的进行OGNL解析} -->
<s:a href="getPerson.action?name=%{name}">${name }</s:a>
**************************常用通用标签**************************//
表单标签:有个好处,能自动的进行回显。
主题:可以在<s:form中或者某些元素中修改theme主题,如:simple,xhtml(默认),css,ajax
或者可以直接在form标签之前域对象上,加上request.setAttribute("theme","simple");
或者配置里全局修改:
<!-- 修改当前 Struts 应用的主题 -->
<constant name="struts.ui.theme" value="simple"></constant>