<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- 定义了该xml文档语法的位置 -->
<struts>
<!-- 常量,这个常量改为true表示处于开发模式,所有在这个xml的修改可以马上获得反馈 -->
<constant name="struts.devMode" value="true" />
<!-- pacakge用于处理重名 -->
<!--
namespace对应访问路径,
可以“”和“/”表示所有作用(无论前面的地址到底是啥,囊括了其他namespace处理不了的所有action),
可以“/XX/YY”,访问的时候指定路径即可
-->
<package name="fuck" namespace="/FFFF" extends="struts-default">
<!-- 这里就是访问/fuck.action,可以化简为/fuck -->
<action name="fuck">
<!-- 不写名字的result默认就是success -->
<result>/hello.jsp</result>
</action>
</package>
<!-- Action -->
<package name="test" namespace="/path" extends="struts-default">
<!-- class属性制定之后访问该类中的execute方法,返回值只要是success就执行跳转 -->
<!-- 如果不配置class地址,则默认执行ActionSupport -->
<action name="test" class="com.test.Test">
<result name="success">/test.jsp</result>
</action>
</package>
<!-- 动态方法调用 -->
<package name="user" namespace="/user" extends="struts-default">
<!-- method参数指定了目标类中要执行的方法,如果没有则默认执行execute() -->
<action name="userAdd" class="com.test.UserAction" method="add">
<result name="success">/add_success.jsp</result>
</action>
<!--
即使不填method参数,也可以在访问的时候指定“/XXX/user/user!add”或者“user!add.action”
这就是DMI(动态方法调用)
-->
<action name="user" class="com.test.UserAction">
<result name="success">/add_success.jsp</result>
</action>
</package>
<!-- 通配符 -->
<package name="wild" namespace="/wild" extends="struts-default">
<!-- 如果有多个通配符都可以匹配,首先匹配最精确的(“*”最少的),精确度同样的时候排位靠前的匹配 -->
<!--
name上面可以使用“*”作为通配符使用,
出现一个“*”之后在action剩余部分可以使用{1}{2}...指定第一第二...个“*”所传输的内容
这样可以不但确定使用的方法,还可以确定结果页面
-->
<action name="student*" class="com.test.StudentAction" method="{1}">
<result name="success">/studentfuck.jsp</result>
</action>
<!--
约定优于配置,定制好“约定”!在同一个项目组之中必须要使用同一种方法名等等等
可以大大缩减配置文件的长度
-->
<action name="*_*" class="com.test.{1}Action" method="{2}">
<result name="success">/{1}{2}.jsp</result>
</action>
</package>
<!-- 接收参数 -->
<package name="para" namespace="/para" extends="struts-default">
<!--
访问的时候在URL后面增加属性值,可以有几种方法获取
1、Action属性接收参数:
偶尔用
在action类里面直接设置私有参数并且设置setter、getter(匹配的是set、get后面的字符)
struts会自动设置参数,类型转换都自动完成(要注意合法性)
/para/setPara?num=1234&name=Jack
(常用)2、DomainModel接收参数:
用得最多
在action里面放一个对象,URL上直接写对象名.对象属性即可(匹配的依然是各自的set和get后面的字符)
适用于参数比较多的时候,可以直接使用一个域模型包装起来
/para/setPara?user.age=12&user.name=Jack
注意:如果传入的参数比需要的参数要多,那么:
a、直接传action属性
b、使用vo(值对象),do(数据对象),dto(数据传输对象)
临时接收对象作为数据传输之用,之后在自己根据dto生成一个真正需要的对象
3、ModelDriven接收参数:
不常用
Action类实现ModelDriven接口,实现里面的getModel(),
可以直接不需要对象.属性,但是对象就需要自己new了
也即可以直接使用/para/setPara?num=1234&name=Jack,但事实上action里面放的是一个user对象
-->
<action name="setPara" class="com.test.ParaAction" method="add">
<result name="success">/hello.jsp</result>
</action>
<!--
中文问题:
1、尽量post,少用get
2、默认的配置可以在struts包里面的proprits文件里面看到
-->
<!-- constant name="struts.i18n.encoding" value="UTF-8" /-->
</package>
<!-- 参数校验,数值传递后往前 -->
<package name="check" namespace="/check" extends="struts-default">
<action name="checkPara" class="com.test.ParaCheckAction">
<result name="success">/hello.jsp</result>
<!-- 后台和前台通信的方法之一(后台传给前台) -->
<!--
·校验出错的时候可以将出错信息放在struts之中,在页面可以拿出来显示
在return ERROR之前写入:this.addFieldError("user", "user is null!!");
可以针对同一个名字添加多个errorMessage
可以再页面使用<s:fielderror fieldName="user"/>这种形式获得
但是这样使用的情况不多,因为或强制加载默认的css,难看
更常用的是使用<s:property value="errors.user[0]"/>可以直接取得之前放入的字符串
-->
<!--
观察struts的运行情况:<s:debug></s:debug>
标签<s:property value="errors.user[0]"/>
errors(map),errors.user(array),errors.user[0](value)
专门用于获取debug中Value Stack以及Stack Context里面的属性
Stack里面存储着这个action的所有属性
-->
<result name="error">/error.jsp</result>
</action>
</package>
<!-- 数值传递前往后,获取Map类型的request,session,application(Map类型)
HttpServletRequest,HttpSession,ServletContext -->
<package name="getWebElement" namespace="/webElement" extends="struts-default">
<action name="getEle*" class="com.test.WebElementAction{1}" method="getEle">
<!--
1、依赖于容器(struts)
在action中直接访问:
Map request = (Map)ActionContext.getContext().get("request");
Map session = ActionContext.getContext().getSession();
Map application = ActionContext.getContext().getApplication();
后台往里面放东西之后:
request.put("r1", "r111111");
session.put("r2", "r222222");
application.put("r3", "r3333333");
前台可以通过struts标签获取到,两个都可以:
<s:property value="#request.r1"/>
默认的jsp方式:<%=request.getAttribute("r1") %><br>
(最常用) 2、控制反转,依赖注入
依赖注入:我就有只一个setter,找其他人来帮忙给我个对象
控制反转:原来是我自己新建的值,现在是某个中介帮忙传入给我的
实现接口 RequestAware,SessionAware,ApplicationAware
分别实现旗下的一个方法,将传入的request,session,application复制即可
这样获取到的也是Map<String, Object>类型的
3、依赖于容器
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext application = session.getServletContext();
4、控制反转,依赖注入
实现ServletRequestAware接口并实现其中的方法
-->
<result name="success">/getEle.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
<!-- 默认action -->
<package name="default" namespace="/default" extends="struts-default">
<!-- 添加该语句之后,该namespace下所有找不到目的地的action都会被引导到这个action下 -->
<!-- 在这个配置里,由于namespace设置成了任意路径"/",所以任何找不着北的访问都会被引导到index -->
<default-action-ref name="index"></default-action-ref>
<action name="index">
<result>/index.jsp</result>
</action>
</package>
<!-- result -->
<package name="result" namespace="/result" extends="struts-default">
<!-- 全局结果集,这个package内的所有action都可以使用 -->
<!--
如果想要读取其他包里面的结果集,则可以让那个包继承这个包
只需要配置属性extends继承包就可以了
-->
<!-- 特别注意,package内对个元素的排序有着严格要求,action要放在最后 -->
<global-results>
<result name="allCanUser">hello.jsp</result>
</global-results>
<action name="index">
<!--
设置result的各种类型:
dispatcher(默认)服务器端跳转
redirect 客户端跳转
chain 服务器端跳转到一个action,前两个只能跳转到页面,访问action的时候不要加斜杠
redirectAction 客户端跳转到action
剩下还有几种不需要管
-->
<result type="redirect">/index.jsp</result>
</action>
<action name="index2">
<result type="chain">index</result>
</action>
<!-- 使用chain的时候,如果目标action在其他package里面,则可以在中间指定namespace以及actionName-->
<action name="index3">
<result type="chain">
<param name="namespace">/webElement</param>
<param name="actionName">getEle1</param>
</result>
</action>
</package>
<package name="result_son" namespace="/result_son" extends="result">
</package>
<!-- 特别的result -->
<package name="specresult" namespace="/spec" extends="struts-default">
<!--
比较少用
动态结果集,在这里使用action里面的变量,相当于从stack里面获取值
这个是专门用在配置文件里面的OGNL表达式
-->
<action name="res" class="com.test.ResultAction" method="execute">
<result>${asdf}</result>
</action>
<!--
只有在redirect的时候使用
带参数的结果集,从一个action向其他页面跳转的时候,想办法带上一些参数
1、一次request只有一个值栈,所以各个action使用服务器端forward的时候参数一直保留
2、使用客户端跳转的时候,参数无法保留,可以用这种方法传参
-->
<action name="res2" class="com.test.ResultAction" method="execute2">
<result type="redirect">/add_success.jsp?t=${asdf}</result>
</action>
</package>
<!-- OGNL: Object Graph Navigation Language 对象图导航语言 -->
<package name="ognl" namespace="/ognl" extends="struts-default">
<!--
一个表达式:<s:property value="username"/>
OGNL表达式代表着value的双引号之内的内容,至于前面的s:是标签
action里面的所有属性、对象,只要是设定了getter和setter,就都可以在struts的值栈里面看到
访问静态方法、静态属性之前必须在这里设定
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
访问时必须在OGNL语句的开头加上“@”,连续两个“@@”可以直接使用Math类的静态方法
可以指定访问某个类的某个构造方法,只要语法合适 new com.test.User('lalala')
-->
<action name="check" class="com.test.CheckOGNLAction">
<result>/ognl.jsp</result>
</action>
</package>
<!-- 设定允许访问静态方法 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<!-- 包含其他的配置文件,可以分模块开发 -->
<!--include file="out_struts.xml"/-->
</struts>
在页面上OGNL的使用
<body>
<ol>
<h6>属性访问</h6>
-----普通属性、对象访问----------------------------------------------------------------<br>
<li>访问值栈中的action的普通属性:username = <s:property value="username"/> | password = <s:property value="password"/></li>
<li>访问值栈中对象的普通属性:user = <s:property value="user"/> | user.age:<s:property value="user.age"/></li>
<li>访问值栈中对象的对象属性:biguser = <s:property value="biguser"/> | biguser.user = <s:property value="biguser.user"/></li>
<li>访问值栈中对象的普通方法:username.length() = <s:property value="username.length()"/></li>
<li>访问值栈中action的普通方法:CheckOGNLAction.shout() = <s:property value="shout()"/></li>
-----静态方法、属性访问----------------------------------------------------------------<br>
<li>访问静态方法:@com.test.Test.staticShout() = <s:property value="@com.test.Test@staticShout()"/></li>
<li>访问静态属性:@com.test.Test.staticTestValue = <s:property value="@com.test.Test@staticTestValue"/></li>
<li>访问Math类静态方法:@@max(3,4) = <s:property value="@@max(3,4)"/></li>
-----构造器访问------------------------------------------------------------------------<br>
<li>访问指定的构造方法:new com.test.User(lalala) = <s:property value="new com.test.User('AAA')"/>|<s:property value="new com.test.User(\"BBB\")"/></li>
-----容器访问--------------------------------------------------------------------------<br>
<li>访问list、数组: = <s:property value="userList"/></li>
<li>访问list、数组中某个属性集合(组成新List): = <s:property value="userList.{name}"/></li>
<li>访问list、数组中某个属性集合的特定值: = <s:property value="userList.{name}[0]"/>| 更常用的:<s:property value="userList[0].name"/></li>
<li>访问Set: = <s:property value="userSet"/></li>
<li>访问Set中某个元素(没有意义): = <s:property value="userSet[0]"/></li>
<li>访问Map: = <s:property value="userMap"/></li>
<li>访问Map中的某个元素: = <s:property value="userMap.map1"/>|<s:property value="userMap['map2']"/>|<s:property value="userMap[\"map4\"]"/></li>
<li>访问Map中所有的key: = <s:property value="userMap.keys"/></li>
<li>访问Map中所有的value: = <s:property value="userMap.values"/></li>
<li>访问容器的大小: = <s:property value="userMap.size()"/></li>
-----投影(过滤)----------------------------------------------------------------------<br>
<li>投影(符合条件的集合): = <s:property value="userList.{?#this.age>20}"/></li>
<li>投影(符合条件的第一个): = <s:property value="userList.{^#this.age>20}"/></li>
<li>投影(符合条件的最后一个): = <s:property value="userList.{$#this.age>20}"/></li>
<li>投影(结果是否为空): = <s:property value="userList.{$#this.age>20} == null"/></li>
-----方括号访问----------------------------------------------------------------------<br>
<li>【】值栈从上往下第一个对象的“位置”,进行服务器端跳转的话会有多个Action: = <s:property value="[0]"/></li>
<h6>标签</h6>
-----property----------------------------------------------------------------------<br>
<li>property: <s:property value="username"/> </li>
<li>property 取值为字符串(默认以对象对待): <s:property value="'username'"/> </li>
<li>property 设定默认值: <s:property value="admin" default="管理员"/> </li>
<li>property 设定HTML(true则不解析成HTML): <s:property value="'<hr/>'" escape="true"/> </li>
-----set----------------------------------------------------------------------<br>
<li>set 设定adminName值(默认为request 和 ActionContext): <s:set var="adminName1" value="'username'" /> | <s:set var="adminName2" value="username" /></li>
<li>set 从request取值: <s:property value="#request.adminName1" /> | <s:property value="#request.adminName2" /></li>
<li>set 从ActionContext取值: <s:property value="#adminName1" /> | <s:property value="#adminName2" /></li>
<li>set 设定范围: <s:set name="adminPassword" value="password" scope="page"/></li>
<li>set 从相应范围取值: <%=pageContext.getAttribute("adminPassword") %></li>
<li>set 设定var,范围为ActionContext: <s:set var="adminPassword" value="password" scope="session"/></li>
<li>set 使用#取值: <s:property value="#adminPassword"/> </li>
<li>set 从相应范围取值: <s:property value="#session.adminPassword"/> </li>
-----iterator----------------------------------------------------------------------<br>
<li>
遍历集合:<br>
<s:iterator value="{1,2,3,4,5,2,3,4}">
<s:property/> |
</s:iterator>
</li>
<li>自定义变量:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
<s:property value="#x"/> | <s:property value="#x.toUpperCase()"/>
</s:iterator>
</li>
<li>使用status:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
<s:property/> |
遍历过的元素总数:<s:property value="#status.count"/> |
遍历过的元素索引:<s:property value="#status.index"/> |
当前是偶数?:<s:property value="#status.even"/> |
当前是奇数?:<s:property value="#status.odd"/> |
是第一个元素吗?:<s:property value="#status.first"/> |
是最后一个元素吗?:<s:property value="#status.last"/>
<br />
</s:iterator>
</li>
<li>遍历map:<br />
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" >
<s:property value="key"/> | <s:property value="value"/> <br />
</s:iterator>
</li>
<li>使用自定义变量遍历Map:<br />
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/> <br />
</s:iterator>
</li>
<li>遍历action里的list:<br />
<s:iterator value="userList" var="x">
<s:property value="#x"/> |
</s:iterator>
</li>
<li>使用自定义变量遍历Map:<br />
<s:iterator value="userMap" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/> <br />
</s:iterator>
</li>
</ol>
调出debug页面
<s:debug></s:debug>
</body>