<?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">

<struts>

 <!-- 这里是打开structs的开发模式,默认是true -->
    <constant name="struts.devMode" value="true" />
    <!-- 方法感叹号动态调用,必须把这个打开 -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <!--structs2 国际化,编码问题 -->
    <constant name="struts.i18n.encoding" value="utf-8" /><!-- internationalization
        18个字母 -->
    <include file="/com/jaovo/struts2/ognl/ognl.xml"/><!--包含,把指定文件的xml,包含到当前xml文件中-->
    <!--========================================================================= -->

    <package name="front" namespace="/front" extends="struts-default"><!--(1)模块名字,(2)在地址栏写的那个包名(并不是写前面的包名,是这里的,一般都和前面的包名(name)一致),(3)继承于底层的"struts-default"-->
        <!--name是包名,但是目录要打namespace里面的值(建议是包名前面加个/)-->
        <action name="index"><!--action名字-->
            <result><--这里不写 后面默认是result name="success"-->
                /Hello.jsp<!--要跳转的页面-->
            </result>
        </action>
    </package>
    <!--===============默认主页=======================================-->
        <package name="default" namespace="/" extends="struts-default">
            <default-action-ref name="index" /><!--默认自动跳转到name为index的action中,指定的页面-->
        <!--  没有上面这一句,url中就必须加index,要不然访问不到,默认就用这个
        在web.xml中,通过
        <welcome-file-list>
          </welcome-file-list>
          来指定默认主页
          但是也可以去调用,通过struts2指定
        -->
        <action name="index">
            <result>/default.jsp</result>
        </action>
    </package>
    <!--========================================================================= -->
     <!--  这里是默认是匹配不到的就匹配这里,但是和配置相关
    F:\Step06_JavaEE\_01_Strust2\struts-2.3.24-all\struts-2.3.24\src\core\src\main\java\org\apache\struts2\dispatcher\mapper
    这个类里面有相关源码
    -->
    <!-- 如果namespace为空的话,就是所有匹配不上的,都匹配到这里来
        我这里只管namespace,不管的别的,和action无关
     -->
    <package name="fron" namespace="" extends="struts-default"><!--前面怎么错都行,后面的index对应上,就行,别的都匹配不上的时候,就匹配到这个-->
        <action name="index">
            <result>
                   /404.jsp
            </result>
        </action>
    </package>
    <!--========================================================================= -->
    <package name="front" namespace="/" extends="struts-default">
        <action name="index" class="com.jaovo.structs2.front.action.IndexAction3"><!--action跳转到指定类,在从类中的方法的返回值中,获得一个字符串,去匹配下面这个result name=success-->
            <!-- 这里的返回值是success,然后回去匹配result为success的result -->
            <!--类返回这个字符串有三种方法,看./Struts2.java里面的execute :-->
            <result name="success">
                /404.jsp
            </result>
        </action>
    </package>
<!--==================================方法调用============================================-->
        <!--========第一种,指定名字调用userAdd,一个方法,要对应一个action====-->
        <package name="user" namespace="/user" extends="struts-default">
        <!--两个a超链接是在jsp里面要跳转时候写的-->
        <a href="user/userAdd">action调用add方法添加用户</a><br /> 调用第一种action方法
        <action name="userAdd" class="com.jaovo.structs2.user.action.UserAction"
                method="add"><!--method 是调用方法,后面是方法名-->
            <result name="success">
                /user_add_success.jsp
            </result>
        </action>
            <!--==========第二种 !感叹号调用============-->
         <!--a超链接是在jsp里面要跳转时候写的-->
        <a href="user/user!add">URL动态传参调用相关的方法执行</a><br /> 调用第二种action方法,user定位到类,!后面跟方法名
        <action name="user" class="com.jaovo.structs2.user.action.UserAction">
            <result>
                /user_add_success.jsp
            </result>
        </action>
    </package>
    <!--=========================第三种,推荐,通配符===================-->
    <package name="actions" namespace="/actions" extends="struts-default">

        <!-- 记得sql语句中的?通配符吗,嘿嘿,一样的,{1},第一个星,{2}第二个星 -->
          <!--jsp文件,a链接写法-->
    <a href="actions/Studentadd">添加学生</a>
    <a href="actions/Studentdelete">删除学生</a>
    <br /> 不过,一定要遵守"约定优于配置"的原则

        <action name="Student*" class="com.jaovo.structs2.action.StudentAction"
                method="{1}"><!--如上面,是不是类名后面跟着是方法名,这个是方法名我用*代替,别管你输入什么方法,只要我有,*号就代替什么方法,然后再去匹配,就不用好多action了吧,method后面跟方法名,要换成{1},就是第一个星号的意思-->
            <result name="success">
                /Student{1}_success.jsp<!--然后找到对应的jsp(注意:jsp命名,一定要和这个一致,名字加方法名,要么找不到对应的jsp文件),就行了,-->
            </result>
        </action>
                    两个**号匹配一切,------------------------------
        <!--jsp文件,a链接写法-->
    <br /> 不过,一定要遵守"约定优于配置"的原则
    <a href="actions/Teacher_add">添加老师</a>
    <a href="actions/Teacher_delete">删除老师</a>
    <a href="actions/Course_add">添加课程</a>
    <a href="actions/Course_delete">删除课程</a>
        <!-- 两个星号,匹配规则的一切,前面截胡一切uri的类名和方法名的请求 -->
        <action name="*_*" class="com.jaovo.structs2.action.{1}Action"
                method="{2}"><!--第一个*号是类名把,第二个*号是方法名,注意细节,这个是类后面加_再加方法名,一定要和自己的跳转a链接对应上-->
            <result>
                /{1}_{2}_success.jsp
            </result>
        </action>
    </package>
    <!--========================方法调用和传参====================================-->
                <!--jsp文件传参写法-->
                <a href="user/User_add?name=a&age=8">添加用户</a>
                <!-- 领域传值模型,本质才uri中,加上具体的对象 -->
                ModelDriven传值.默认是实现ModelDriven接口,实现getModel方法,
                然后在uri传值中,就可以不用在封装数据,会自动封装到实体类中,这个要在类中实例化实体类对象
                <a href="user/User_add?user.name=dongrege&user.age=18">添加用户</a>//封装到对象里面了,对象是谁new的?底层.....
                --------------------------
                <package name="actions" namespace="/user" extends="struts-default"><!--name是包名,但是目录要打/user-->
        <!-- 两个星号,匹配规则的一切 -->
        <action name="*_*" class="com.jaovo.structs2.user.action.{1}Action"
            method="{2}">
            <result name="success">
                /{1}_{2}_success.jsp
            </result>
        </action>
    </package>
    <!--=============================四种方式跳转==========================================-->
    <!--=============================dispatcher=========================================-->
            地址栏不显示要跳转的**.jsp   是同一个栈,是同一个线程内局部变量
     <package name="resultTypes" namespace="/r" extends="struts-default">
        <!-- 这一个的跳转,就是同一个栈,也就是同一个ThreadLocal,线程内局部变量,传过来的那个参数,保存request,在整个请求过程中都能用-->
        <action name="r1">
            <!--这里的result,并不是我们传统意义上,方法的那个返回值(是方法的返回值,只不过是预定义的),而是,通过预定义返回值的方式,进行不同页面间的跳转控制-->
            <!-- 不指定,默认就是这个 : 运用服务器跳转, forward(),用服务器跳转到结果页面,不能是action-->
            <result type="dispatcher">/r1.jsp</result>
        </action>
        <!--=============================redirect=========================================-->
                地址栏显示**.jsp  就是跳转页面,没有经过action  
        <!-- 这个,就是跳转到一个简单的jsp页面,没有经过action -->
        <action name="r2">
        <!-- 不能是action 就是底层那个redirect,相当于我要发送到客户端浏览器,这是浏览器跳转
        浏览器端的jsp
        -->
            <result type="redirect">/r2.jsp</result>
        </action>
        <!--=============================chain=========================================-->
                链式跳转,chain指定的是r1  意思是跳转到另一个action的name为r1的那个跳转页面,再由r1action 跳转到指定页面,地址栏不会显示**,jsp   可以跳转到action中,也可以直接跳转到一个jsp页面,但是action可以传参,但是jsp页面不可以传参   action的内容保存在valuestack中  jsp中属性在actioncontext中保存
        
        <!-- 下面这一个,是跳转到一个不同的action中,也就是不是同一个ThreadLocal,所以需要传递参数 -->
        <action name="r3">
            <!-- 可以跳转到action 相当于forward到另外一个action,跳转到r1 action,然后由r1action 跳转到r1.jsp-->
            <result type="chain">r1</result>
            <!--
            <param name="actionName">/方法名</param>
            <param name="namespace">/包名</param>
             -->
        </action>
    <!--=============================redirectAction=========================================-->
    先跳转到action的name为r2的,再有那个action跳转到指定页面,地址栏显示**.jsp
    可以跳转到action中,也可以直接跳转到一个jsp页面,但是action可以传参,但是jsp页面不可以传参   action的内容保存在valuestack中  jsp中属性在actioncontext中保存
        <!-- 这个是在服务器端先跳转到一个action,然后在在那个action决定跳转到那个jsp页面 -->
        <action name="r4">
        <!-- 客户端跳转 跳转到对应的action-->
            <result type="redirectAction">r2</result>
        </action>
        
    </package>
    <!--==========================跨包访问=======================================-->
      <!-- 如何访问到另外一个package中的,跨包访问 -->
    <!--  <package name="admin" namespace="/admin" extends="struts-default"> -->
    <package name="admin" namespace="/admin" extends="user"><!--默认继承struts-default  这里可以改为我们的包(自己的user包)-->
        <action name="admin" class="com.jaovo.struts2.user.action.AdminAction"><!--这里如果方法返回回来的不是success ,就会报错,继承于user 返回值返回回来的,就可以去继承的那个包里面找result对应的name为,返回回来的那个值,再匹配不到才会报错-->
            <result>/admin.jsp</result>
        </action>
    </package>
    <!--===================封装形式 ${值}-->
     <package name="user" namespace="/user" extends="struts-default">
        
          <!--
          实体类中这样写
              @Override
    public String execute() throws Exception {
        if(type == 1) r="/user_success.jsp";
        else if (type == 2) r="/user_error.jsp";
        return "success";
    }
      
      -->
        <action name="user" class="com.jaovo.struts2.user.action.UserAction">
            <!-- 动态的去读valueStack里面的内容 r里面的值,r的值根据默认常量值,动态赋予的jsp页面,当这里去读的时候,就能读出相应的内容-->
            <!-- 只要是成员变量,都会在值栈中,保存相应的值 -->
            <result>${r}</result><!--解析r的值,是一个地址,是在实体类中赋值的,这里解析出来,上面是实体类写法-->
        </action>        
    </package>
    <!--跳转传参-->
    <package name="user" namespace="/user" extends="struts-default">
        
        <action name="user" class="com.jaovo.struts2.user.action.UserAction">
            <!-- 这里是不能传递参数的,为什么? 接受方不是一个action,没有一个action,就没有成员变量这一说,所以没有 -->
            <result type="redirect">/user_success.jsp?t=${type}</result>
        </action>
        jsp中写法 :
        <s:property value="t"/>//访问action(valuestack值栈)中的t属性,(访问不到)因为上面跳转的是jsp,没有action,就没有t属性
        <s:property value="#parameters.t"/>//访问jsp中(actioncontext(页面所有信息,相当于堆内存))的t属性,就能访问到
    </package>
</struts>