原作者:尚硅谷-佟刚
ValueStack
在 ValueStack 对象的内部有两个逻辑部分:
ObjectStack: Struts 把 Action 和相关对象压入 ObjectStack 中
ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中. 实际上就是对 ActionContext 的一个引用
ObjectStack:
MapStack:
Struts 会把下面这些映射压入 ContextMap 中
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性:pageContext, request, session, application
<!-- 调用数组对象的属性 -->
<%
String[] names=new String[]{"aa","bb","cc","dd"};
pageContext.setAttribute("names",names);
%>
length:<s:property value="#attr.names.length"/>
<br><br>
names[2]:<s:property value="#attr.names[2]"/>
<br><br>
<%
Map<String,String> letters=new HashMap<String,String>();
request.setAttribute("letters",letters);
letters.put("AA","a");
letters.put("BB","b");
letters.put("CC","c");
%>
<!-- 使用OGNL访问Map -->
<br><br>
<s:property value="#request.letters.size"/>
<br><br>
AA:<s:property value="#request['letters']['AA']"/>
StrutsTag
表单标签:
<!--
表单标签:
1.使用和html的form标签的感觉差不多
2.Struts2的form标签会生成一个table,以进行自动的排版
3.可以对表单提交的值进行回显:从栈顶对象开始匹配属性,并把匹配的属性值赋到对应的标签的value中,
若栈顶对象没有对应的属性,则依次向下找对应的属性.
-->
<%
List<City> cities=new ArrayList<City>();
cities.add(new City(1,"北京"));
cities.add(new City(2,"北京"));
cities.add(new City(3,"北京"));
cities.add(new City(4,"北京"));
pageContext.setAttribute("cities", cities);
%>
<s:form action="save" theme="xhtml">
<s:hidden name="userId"/>
<s:textfield name="userName" label="UserName"/>
<s:password name="password" label="Password" showPassword="true"/>
<s:textarea name="desc" label="Desc"/>
<s:checkbox name="married" label="Married"/>
<s:radio name="gender" list="#{'1':'Male','0':'Female' }" label="Gender"/>
<!-- 服务端需要使用集合类型,以保证能够被正常的回显! -->
<s:checkboxlist name="cities" list="#attr.cities"
listKey="cityId" listValue="cityName"
label="City"/>
<s:select list="{11,12,13,14,15,16,17,18,19,20}"
headerKey=""
headerValue="请选择"
name="age"
label="Age">
<!--
s:optgroup 可以用作s:select的子标签,用于显示更多的下拉框
注意:必须使用键值对,而不能使用一个集合,让其值即作为键,又作为值.
-->
<s:optgroup label="21-30" list="#{21:21,22:22}"/>
<s:optgroup label="31-40" list="#{31:31,32:32}"/>
</s:select>
<s:submit/>
</s:form>
通用标签:
<s:url value="/getProduct" var="url3">
<!-- 对于value值会自动的进行OGNL解析 ,不解析单引号引起来-->
<s:param name="productId" value="'GGGGKKK'"/>
</s:url>
${url3 }
<br><br>
<!-- 构建一个请求action的地址 -->
<s:url action="testAction" namespace="/helloWorld" method="save" var="url4">
<s:param name="name" value="'sss'"/>
</s:url>
${url4 }
<br><br>
<!-- includeParams:none:不包含 get:get请求 all:get/post请求 -->
<s:url value="/testUrl" var="url5" includeParams="get"/>
${url5 }
s:set:向page,request,session,application域对象中加入一个属性值
<br><br>
<!-- 对value属性值自动进行OGNL解析 -->
<s:set name="productName1" value="productName" scope="request"/>
<s:property value="#request.productName1"/>
<br><br>
s:push:把一个对象在标签开始后压入到值栈中,标签结束时,弹出值栈
<br><br>
<%
Person person=new Person();
person.setName("atguigu");
person.setAge(11);
request.setAttribute("person", person);
%>
<s:push value="#request.person">
<s:property value="name"/>
----${name }----
</s:push>
<br><br>
<s:if test="#request.person.age>10">
大于10岁
</s:if>
<s:else>
小于或等于10岁.
</s:else>
s:iterator:遍历集合的,把这个可遍历对象里的每一个元素依次压入和弹出
<%
List<Person> persons=new ArrayList<Person>();
persons.add(new Person("AA",10));
persons.add(new Person("BB",20));
persons.add(new Person("CC",30));
persons.add(new Person("DD",40));
persons.add(new Person("EE",50));
request.setAttribute("persons", persons);
%>
<br><br>
<s:iterator value="#request.persons" status="status" var="temp">
index:${status.index }--count:${status.count }--<s:property value="#request.temp.name"/>----<s:property value="#request['temp']['age']"/><br>
</s:iterator>
<br><br>
s:sort :可以对集合中的元素进行排序
<br><br>
<%
PersonComparator pc=new PersonComparator();
request.setAttribute("comparator", pc);
%>
<s:sort comparator="#request.comparator" source="#request.persons" var="persons2"/>
<s:iterator value="#attr.persons2">
<s:property value="name"/>---<s:property value="age"/><br>
</s:iterator>
s:date 可以对Date对象进行排版
<br><br>
<s:date name="#session.date" format="yyyy-MM-dd HH:mm:ss" var="date2"/>
s:date<s:property value="#request.date2"/>
<br><br>
<s:iterator value="persons">
<!-- 可以使用%{}把属性包装起来,使其进行强制的OGNL解析 -->
<s:a href="getPerson.action?name=%{name}">${name }</s:a>
</s:iterator>
<br><br>
Interceptor
defaultStack
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
***
1. <interceptor-ref name="prepare"/>
***
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<***
2. interceptor-ref name="modelDriven"/>
***
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
***
3. <interceptor-ref name="params"/>
***
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
<interceptor-ref name="deprecation"/>
</interceptor-stack>
paramsPrepareParamsStack
<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
***
1. <interceptor-ref name="params"/>
***
<interceptor-ref name="servletConfig"/>
***
2. <interceptor-ref name="prepare"/>
***
<interceptor-ref name="chain"/>
***
3. <interceptor-ref name="modelDriven"/>
***
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
***
4. <interceptor-ref name="params"/>
***
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
<!--配置使用 atguiguStack 作为默认的拦截器栈 -->
<!-- 修改PrepareInterceptor拦截器的alwaysInvokePrepare属性值为false -->
<interceptors>
<interceptor-stack name="atguiguStack">
<interceptor-ref name="paramsPrepareParamsStack">
<param name="prepare.alwaysInvokePrepare">false</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="atguiguStack" />