struts2

struts的入门:
    1.下载struts
    2.新建项目
        导入jar包.
            struts解压目录/apps/struts-blank.war
            解压以后就有所须要的jar包
    3.配置struts前端控制器
        在web.xml中配置filter
        <filter>
            <filter-name>struts</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>struts</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    4.新建一个index.jsp
        编写一个a标签 
            <a href="/s2_day01/hello">a_入门</a>
    5.新建一个类(action)
        一个普通的类
        提供一个公共的有返回值的,返回值类型string,名称为execute的方法
    6.建立配置文件
        名称:struts.xml
        位置:src目录
        导入约束
            <!DOCTYPE struts PUBLIC
                "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
                "http://struts.apache.org/dtds/struts-2.3.dtd">
        package 标签:
            name属性:起个包名,保证这个项目中惟一
            extends属性:声明当前包继承于某个包 通常使用的默认值"struts-default"
            namespace属性:和action标签的name属性组成访问路径的 
            action标签:建立路径和类的对应关系 
                name属性:和namespace属性组成访问路径的
                class属性:自定义的action的全限定名
                result标签:配置逻辑视图(action的返回值)和资源的跳转的
                    name属性:action中方法的返回值(逻辑视图)
    7.跳转到1.jsp
        a.让action中的方法有一个返回值 返回值任意 bb
        b.在struts.xml配置返回值对应的页面 默认使用的是请求转发

struts的简易的执行流程(只是方便你们理解的,过程是不许确.在第四天的时候讲准确的执行流程)
    参考excle
经过刚才的执行流程:
    filter的init方法主要的做用之一:加载配置文件
    filter的doFilter方法的做用,才是执行拦截器和action的

加载的配置文件有那些?
    struts提供好的
        default.properties    :提供了一些常量
        struts-default.xml    :配置了默认的拦截器及跳转方式等操做
        struts-plugin.xml    :struts的一些插件的配置文件(如今暂时没有)
        
    咱们本身编写的
        ★struts.xml         :主要配置action和路径的对应关系等一系列主要信息
        struts.properties:提供了一些常量(通常咱们不提供)
        web.xml中过滤器的初始化参数
        
    注意:
        由于咱们配置加载是有顺序的,全部后面配置的同名配置会把以前的配置覆盖掉.
------------------------------------------
配置文件详解
    常量的配置:
        咱们能够在struts.xml,struts.properties,web.xml中配置
        推荐在struts.xml
        
        在struts.xml中经过 <constant name="" value=""/>
        例如:
            <!-- action的后缀名 -->
            <constant name="struts.action.extension" value="abc"/>
            
        了解:
            在struts.properties配置常量
            在src下本身建立一个struts.properties
                struts.action.extension=abc
                
        理解:
            在web.xml中配置过滤器的初始化参数
            <!-- 配置filter的初始化参数 -->
            <init-param>
                <param-name>struts.action.extension</param-name>
                <param-value>xyz</param-value>
            </init-param>前端

        常见的常量:
            struts.action.extension:配置后缀名
            struts.devMode:开发中模式 这个版本的默认值 false(若值为true的时候,配置文件修改后不须要重启服务器,可是有安全问题)
    ----------------------------
    action的配置:
        package标签:
            name属性:起个包名,保证这个项目中惟一,方便让别人继承用的.
            extends属性:声明当前包继承于某个包 通常使用咱们直接或者间接继承"struts-default" 就可使用这个包下的全部内容
            namespace属性:和action标签的name属性组成访问路径的  
                写法:
                    不写        等价于 namespace=""
                    根路径    namespace="/"
                    带路径    namespace="/customer" ★
                    
            action标签:建立路径和类的对应关系 
                name属性:和namespace属性组成访问路径的 注意:版本不一样,写法不同.咱们的版本中不能出现 "/"   (其实就是一个常量的配置问题:struts.enable.SlashesInActionNames)
                class属性:自定义的action的全限定名
                method属性:配置action要执行的方法名称 默认值:execute
    -------------------------------
    include的配置
        将其余的自定义struts的配置文件包含到struts.xml中.方便团队开发维护.
        例如:
            <include file="cn/itcast/a_hello/struts_hello.xml"></include>
--------------------------------------------------
action的编写方式    
    (了解)方式1:普通的类
    (理解)方式2:实现Action接口
        提供了5个字符串常量(逻辑视图)
            success:成功访问的时候
            error:错误的时候
            login:往登陆页走的时候
            none:页面不跳转
            input:struts内部使用,当struts内部发生错误的时候,返回input 
    ★方式3:继承ActionSupport类
   
action的访问方式    
    (了解)方式1:经过设置method访问
    ★★方式2:通配符配置
        <!-- 通配符配置  -->
        <action name="demo2_*" class="cn.itcast.c_access.Demo2AccessAction" method="{1}"></action>
        
        变态的写法:
            类名:ProductAction,OrderAction
            方法名:save ,update
            访问路径:
                /ProductAction_save.action
                /OrderAction_save.action
                
            配置文件:
                <action name="*_*" class="cn.itcast.c_access.{1}" method="{2}"></action>
                
    ★方式3:动态方法执行方式
        前提:
            开启容许动态方法执行
            在struts.xml中配置一个常量
                struts.enable.DynamicMethodInvocation=true
        路径写法:
            /user!方法名.action
        配置文件
            <action name="user" class="cn.itcast.c_access.UserAction"></action>

案例分析:
    看图
    技术点:
        获取request对象
            ServletActionContext.getRequest();
            
-----------------------------------------
struts入门
    获取请求
    页面跳转
    
入门案例:
    导入jar包:解压目录下/apps/struts-blank.war
    编写action类:
        方式3:继承ActionSupport类
    配置文件:
        web.xml中配置核心过滤器 StrutsPrepareAndExecuteFilter
        在src下本身建立一个struts.xml
            导入约束
            package标签
                name属性
                namespace属性
                extends属性
                
                action标签
                    name属性
                    class属性
                    method属性
                    
                    result标签
                        name属性
                        标签体:服务器内部路径
    ----------------------
    简易执行流程
    配置文件及其加载顺序
        struts提供好的
        咱们本身编写的
    注意:
        后面的同名配置会覆盖以前的配置
        
    配置文件中:
        常量的配置
            在struts.xml经过constant标签配置
            
        include配置
            包含其余的struts文件.团队开发中使用
            
    action的访问方式
        方式2:通配符配置
        方式3:动态方法执行方式
        *-*-*--*-*-*-*-*-*-*-**-*-*-*-*--*-*-*-*-*-*-*-*-*-java

 

访问servlet的api方式    
    ★方式1:经过ServletActionContext的静态方法访问
        getRequest()
        getResponse()
        getServletContext()
    (了解)方式2:经过接口注入的方式
        咱们须要让本身的action实现如下几个接口
            ServletRequestAware
            ServletResponseAware
            SessionAware
            ServletContextAwareweb

    (理解)方式3:经过ActionContext的方法访问
        获取ActionContext对象(当成工具类使用)
            ActionContext context = ActionContext.getContext();
        获取请求参数
            Map<String , Object > context.getParameters()
            
        域操做:
            (至关于)往request域中放入数据:put(String key,Object Value)
            往session域中放入数据: getSession().put(String key,Object Value)
            往application域中放入数据: getApplication().put(String key,Object Value)

★action是多实例的

result配置:
    action标签下有result标签:用来配置页面跳转
        name属性:逻辑视图的名称(方法的返回值) 默认值:success
        type属性:跳转的方式
            经常使用值:
                dispatcher    转发到jsp上 默认值
                redirect    重定向到jsp上
                
                chain            转发到action上
                redirectAction    重定向到action上
                
                扩展:
                    stream        文件下载
        标签体:跳转的路径的
            跳转到jsp上 写jsp的内部路径  
            跳转到当前包下的action上 直接写action的名字
            
    配置方式分类:
        全局结果页面配置:供当前包下的全部action共享.
            经过package标签下的子标签 
                global-results
        局部结果页面配置:仅当前action可使用的
            就是在action下配置result标签

封装数据
    ★方式1:属性驱动set方式(适用参数个数少,例如分页)
        表单以前怎么写 如今还怎么写
        在action中须要提供一些属性的set方法
        
    ★方式2:属性驱动页面表达式方式(ognl表达式,封装到多个对象中)
        修改表单里面的每一个子标签的name属性 javabean对象名称.属性名称
        在action中提供一个javabean对象且提供他的get和set方法
        
        例如:
            action中提供一个成员属性  private User uu; //提供get和set方法
            标签子标签中name属性写法  <input type="text" name="uu.username"/>
    ★★方式3:模型驱动(ModelDriven)
        页面写法仍是之前的写法
        1.要求action实现ModelDriven接口
        2.在action要提供一个javabean的成员字段且必须初始化
        3.重写接口中getModel的方法
        4.经过getModel方法将javabean的成员字段返回
    
        批量封装
        大前提:
            须要在action提供给一个集合(list仍是map),提供集合的set和get方法
        
        批量封装成list
            页面表达式写法:
                name="集合属性名称[index].bean属性名"
                例如: name="ll[1].username"
        批量封装成map
            页面表达式写法:
                name="集合属性名称['键名'].bean属性名"
                例如:
                    name="mm['aa'].age"
        

搭建环境:
    导入jar包
        hibernate
        驱动
        日志
        struts
    导入页面
    配置文件:
        hibernate.cfg.xml 
        log4j.properties
        struts.xml 
        web.xml中配置核心过滤器
    建立持久化类和映射文件(复制)
    建立action,service,dao
    配置action
    
展现全部的客户
    
客户保存        
    步骤:
        1.修改menu.htm中 "新增客户"的链接
            /crm_/jsp/customer/add.jsp(不推荐)
            可使用转发的方式访问jsp
            /crm/customer_addUI.action
        2.在action中提供一个addUI的方法
            直接转发到jsp便可
        3.修改add.jsp中表单信息
            action属性
            子标签的name属性
        4.在action提供一个保存的方法 save方法
            模型驱动
            在save方法中获取封装后的对象
            调用service完成保存操做
            重定向到customer_findAll.actionapache

 

 

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-编程

ognl表达式:咱们主要用它在页面上来获取值栈的数据.el也能够获取值栈中的数据
值栈:ValueStack    自己就是一个容器(一系列集合),存放请求参数和各大域中的数据及其它的数据

ognl表达式:
    对象图导航语言,是一种表达式语言
    struts2的默认表达式语言是ognl
    主要做用:
        调用对象的方法
        访问类的静态属性
        访问类的静态方法
        ★获取值栈中的数据.
        ....
    演示一下在jsp中使用ognl表达式(了解)
        
        调用对象的方法:获取 字符串"hello"的长度 <s:property value="'hello'.length()"/><br>
    
        <!-- 格式:@类的全限定名@属性名 -->
        访问类中的静态属性:获取 π 的值 <s:property value="@java.lang.Math@PI"/><br>
        
        <!-- 
            格式:@类的全限定名@方法名() 
            注意:配置容许ognl访问静态方法 struts.ognl.allowStaticMethodAccess
        -->
        访问类中的静态方法:获取随机数 <s:property value="@java.lang.Math@random()"/><br>

值栈:
    ValueStack
    百度百科上:
        ValueStack实际上就是一个容器。它由Struts框架建立,当前端页面如jsp发送一个请求时,
        Struts的默认拦截器会将请求中的数据进行封装,并放入ValueStack
    个人理解:
        我把他称之为 struts的临时数据中转站.当请求来的时候,struts框架会为每个请求建立一个值栈.
        struts会将请求中的数据及其余域中的数据封装到值栈中.当请求结束的时候,值栈也就销毁了.
            以前获取参数的时候,找request对象,今天咱们经过值栈获取请求参数
            以前获取域中的数据的时候,找各个域,今天咱们经过值栈获取各个域中的数据
            以前咱们往域中放入数据的时候,找各个域.今天咱们也能够经过值栈放到各个域中数据.
    ValueStack是一个接口,咱们使用的是实现类 OgnlValueStack,ValueStack是贯穿action的生命周期的.

值栈的结构
    一系列集合,主要分红两部分
        root    本质上就是一个list集合(咱们之后主要往root中存放数据)
        context 本质上就是一个map集合 map<String ,Object >
            主要存放的数据有如下内容
            key                value
            request            request域中的数据(map)    
            session            session域中的数据(map)    ★
            application        application域中的数据(map)    ★
            attr            四个域中的数据按顺序又存放了一遍. map
            parameters        请求的参数 (map)
            root            root对象(地址值)
            自定义key        自定义value        至关于往request中存放数据

    ActionContext和值栈的关系.
        actioncontext叫作action的上下文.咱们就把它当成是一个工具类
        源码描述:
            当一次请求来的时候,struts框架会为每个请求建立一个值栈.还会建立一个ActionContext对象.
                将全部的数据放入值栈的context区域,将值栈再放入ActionContext中
                继续将ActionContext绑定到当前线程中.(ThreadLocal) 上面的操做都是struts帮咱们完成的
                
            最后,咱们获取数据或者操做数据的地方 在action中或者jsp中.如何在action中获取ActionContext对象.
            由于一次请求对应的是一个线程.只须要经过获取当前线程绑定的actioncontext对象便可.就是咱们以前学习的 
                ActionContext.getContext();
    ActionContext中有全部的数据(请求参数及各个域中的数据).
        咱们把值栈中的Context赋值给了ActionContext中的context集合.以后获取域中数据或请求参数的时候直接找actoincontext中的context集合便可.

获取值栈
    ActionContext.getContext().getValueStack();

往值栈中存放数据(通常是在action存放)
    往root中存数据(★★)
        方式1:经过值栈的api的api
            push(Object obj)
            set(String key,Object value):底层是先建立一个map集合,而后将数据放入map集合中,而后再将map放入root中
            结论:
                push对象,set集合.
        方式2:经过Action的成员属性
            由于action自己就放在root中.
    
    往context中存数据
        注意:
            操做值栈的Context 只须要操做ActionContext中的context
        往request域中放入数据 至关于 put(String,Object)
        往session域中放入数据 getSession().put(String,Object)
        往application域中放入数据 getApplication().put(String,Object)
        
        struts往值栈的context中放入数据的时候,给一些域起个两个key,一个是长名字的key,一个是短名字的key.
            长名字的key是struts底层使用的.为了方便咱们获取数据另外起个短名字的key
从值栈中获取数据(通常是在jsp上获取)
    获取root中的数据
        经过 <s:property value="ognl表达式"/> 获取数据
        ognl直接写对象的属性名称或者写key名称
    获取context中的数据
        经过 <s:property value="ognl表达式"/> 获取数据
        ognl #key名
        

el获取context中的数据,也能够获取root中的数据.
    ${username}
        以前在web这样写的时候,依次从小到大四个域中查询指定名称的值.底层调用的是pageContext中findAttribute(key)的方法
        findAttribute方法的底层:
            先调用pageContext.getAttribute(key)
                判断是否能获取到值.
                    若获取到了,直接返回,且结束该次查找.
                    若没有获取到,调用request.getAttribute(key)
                        判断是否能获取到值.
                            若获取到了,直接返回,且结束该次查找.
                            若没有获取到,调用session.getAttribute(key)
                                判断是否能获取到值.
                                    若获取到了,直接返回,且结束该次查找.
                                    若没有获取到,调用application.getAttribute(key)
                                        判断是否能获取到值.
                                            若获取到了,直接返回,且结束该次查找.
                                            若没有获取到,返回null
                                            
    咱们的${username}对findAttribute方法返回值进行了改造,若返回值为null则返回一个""
    ${}或者ognl方式不存在空指针异常和角标越界异常.
    
今天咱们使用el的时候也能够获取到root中的数据,这是怎么作的呢?
    获取的顺序:
        pageContext--request--root--context(大map)--session--application
    就是struts对request.getAttribute方法进行了加强
        使用的是装饰者模式对request进行了包装
            先调用request原来的方法,看看是否有返回值,若没有返回值调用valuestack对象的findValue(key)
                findValue方法是先找root中数据,root中没有再去找context(大map)中的数据.
        从而也就能解释下put到context中的数据 至关于放入request域中了
            <s:property/>标签的底层也是java代码,代码其实也是调用了findValue(key)
            
            例如:
                获取put到context中的数据:<s:property value="#rkey"/><br/> 
                获取put到context中的数据:<s:property value="#request.rkey"/><br/> 
                获取put到context中的数据:<s:property value="rkey"/><br/>

★最终的结论
    使用ognl获取root中的数据 <s:property value="属性名称或者key的名称"/>
    使用ognl获取context中的数据 <s:property value="#key名称"/>
    最重要的一句话 使用el也能够获取值栈中的数据.

ognl的特殊符号使用
    #    
        ★主要做用:
            获取context中的数据
            手动构建一个map集合 在struts的form标签中使用
            
    %
        主要做用:
            强制计算ognl表达式
            struts标签的文本框:<s:textfield value="%{#request.username}" name=""></s:textfield>
    $    
        主要做用:
            在struts的配置文件(xml或者properties)中获取值栈中的数据.
        例如在文件下载时使用.
        
        <result name="aa" type="stream">
            <param name="content-disposition">attachment;filename=${filename}</param>
        </result>
    

★循环:
     <s:iterator value="{'男','女'}" var="s">
        <s:property value="#s"/>
    </s:iterator>
    
    <s:iterator value="{'男','女'}">
        <s:property/>
    </s:iterator>
    
    s:iterator有begin,end,step,var,value,status(至关于c标签中varStatus)
    
★判断:
    <s:if test=""></s:if>
    <s:elseif test=""></s:elseif>
    <s:else test=""></s:else>
    

使用值栈和ognl替代以前的request域和el|jstl
    以前查询客户list放入request域中,今天放入值栈(root)中
    以前在list.jsp遍历的时候使用的el|jstl,今天咱们可使用ognl和struts标签配置 api

 

*-*-*-**-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*浏览器

struts的注解开发

拦截器:只能拦截对action的访问,struts的核心.
    和咱们以前过滤器很类似
    filter:能过滤全部的请求和响应
    拦截器:只能拦截对action的访问
    
    其实就是在action(方法)执行以前或者以后,加入一些可重用的代码,也能够阻止方法的执行.(aop:面向切面编程)
        动态代理
        
    一次请求有可能匹配到多个过滤器,咱们把这些过滤器称之为过滤器链 FilterChain
    访问某一个方法的时候也会匹配到多个拦截器,咱们把这些拦截器称之为拦截器链.在struts中通常称之为拦截器栈
    
    Interceptor:接口
        intercept(ActionInvocation invocation) :执行拦截操做的----相似于filter的doFilter
            invocation.invoke();至关于放行操做            ----        相似于 chain.doFilter(..)
----------------------------------------
struts的简易执行流程(不许确)            
struts的较为详细执行流程(准确)
    请求-->核心过滤器-->doFilter方法中作了一系列操做(设置编码,建立actioncontext和值栈,包装request),而后判断
        这次请求访问的是不是actoin
            若不是action:放行
            如果action:继续往struts的核心中走
    ---------------------------------------------------------
    是action:继续往struts的核心中走-->建立一个action的代理对象-->将执行权交个ActionInvocation对象,将这次访问全部执行
    的拦截器放入一个集合中,顺序执行这些拦截器-->执行目标action中方法-->根据result再跳转到相应的资源上-->倒序执行这些
    拦截器-->走核心过滤器放行方法以后的操做,到达咱们的服务器-->服务器拿到数据以后,解析成响应行,头,体,返回给浏览器

自定义拦截器:
    1.编写一个拦截器(实现Interceptor或者继承Interceptor的实现类:例如,MethodFilterInterceptor,这个拦截器能够指定对某些方法拦截,也能够指定对某些方法进行忽略)
    2.配置拦截器
        方式1:
            a.注册拦截器
            b.绑定路径(在action中使用拦截器)
        方式2:
            a.注册拦截器栈
            b.绑定路径(在action中使用拦截器栈)
            
            
        例如:
            方式1:
                --<package name="demo1" namespace="/" extends="struts-default">
                --    <!-- 配置拦截器 -->
                --    <interceptors>
                --        <!-- 1.注册拦截器 -->
                --        <interceptor name="Demo1MyInterceptor" class="cn.itcast.interceptor.a_hello.Demo1MyInterceptor"></interceptor>
                --    </interceptors>
                --
                --
                --    <action name="demo1" class="cn.itcast.interceptor.a_hello.Demo1Action">
                --        
                --        <!-- 2.绑定路径,配置这个action执行的时候会执行那些拦截器 -->
                --        <interceptor-ref name="Demo1MyInterceptor"></interceptor-ref>
                --        
                --        <!-- 注意:一旦在action中显式的声明了使用某个拦截器,默认的拦截器就再也不执行了.咱们须要显式的配置下默认的拦截器 -->
                --        <interceptor-ref name="defaultStack"></interceptor-ref>
                --    </action>
                --</package>
                
        方式2:
            --<package name="demo1" namespace="/" extends="struts-default">
            --    <!-- 配置拦截器栈 -->
            --    <interceptors>
            --        <!-- 注册拦截器 -->
            --        <interceptor name="Demo1MyInterceptor" class="cn.itcast.interceptor.a_hello.Demo1MyInterceptor"></interceptor>
            --        <interceptor name="Demo2MyInterceptor" class="cn.itcast.interceptor.a_hello.Demo2MyInterceptor"></interceptor>
            --        <interceptor name="Demo3MyInterceptor" class="cn.itcast.interceptor.a_hello.Demo3MyInterceptor"></interceptor>
            --        
            --        
            --        <!-- 注册拦截器栈 -->
            --        <interceptor-stack name="MyStack">
            --            <interceptor-ref name="Demo1MyInterceptor"></interceptor-ref>
            --            <interceptor-ref name="Demo2MyInterceptor">
            --                <!-- 对execute方法进行忽略,就是不拦截,多个方法用逗号隔开便可 -->
            --                 <param name="excludeMethods">execute</param>
            --            </interceptor-ref>
            --            <interceptor-ref name="Demo3MyInterceptor"></interceptor-ref>
            --        </interceptor-stack>
            --    </interceptors>
            --
            --
            --    <action name="demo1" class="cn.itcast.interceptor.a_hello.Demo1Action">
            --        
            --        <!-- 2.绑定路径,配置这个action执行的时候会执行那个拦截器栈 -->
            --        <interceptor-ref name="MyStack"></interceptor-ref>
            --        
            --        <!-- 注意:一旦在action中显式的声明了使用某个拦截器,默认的拦截器就再也不执行了.咱们须要显式的配置下默认的拦截器 -->
            --        <interceptor-ref name="defaultStack"></interceptor-ref>
            --    </action>
            --</package>

案例-权限拦截
    步骤:
        1.先作登陆
            建立User表,插入一条记录
            建立user的持久化类和映射文件(hibernate 03)
            建立user的action,service,dao;配置action
            
            把login.htm改为login.jsp
            修改表单的提交路径: /crm_/user_login.action
                须要给用户名和密码提供name属性
                
            须要在Action提供一个login方法
                调用service的find4login(user),查询有无此对象
                    如有:将用户放入session中,重定向到 index.htm上. 在页面上取出session中用户名称
                    若无:生成错误提示信息,请求转发到login.jsp上.在页面上取出错误信息.
        2.再作拦截
            自定义拦截器
                判断session中有无用户
                    如有:放行
                    若无:生成错误提示信息,转发到登陆页面,放行
            拦截那些action
                客户里面的全部action
                用户里面的全部action
                
        细节:
            1.在拦截器中获取action
                ActionSupport action = (ActionSupport) invocation.getAction();
                
            2.添加错误提示信息及在页面上展现错误信息
                action中:    addActionMessage("权限不足,请先登陆");  或者 addActionError("权限不足,请先登陆");
                jsp中:    使用struts标签获取<s:actionmessage/> 或者 <s:actionerror/>
            
            3.在login.jsp中写一段js代码
                判断login.jsp是否在最大的窗口中打开,若不是的话,就让他是最大的窗口
                
                if(top.location != self.location){
                    top.location = self.location;
                }

struts的注解开发
    xml中配置了
        package 继承于谁,名称空间
            action 访问路径和类的对应,要执行的方法,结果页面跳转
            拦截器
            
    注解:
        导入jar包.
            struts的解压目录下/lib/struts2-convention-plugin-2.3.24.jar
        
        
        须要在action中提供注解
            
            类上的注解
                @ParentPackage("struts-default")//声明父包 至关于extends属性
                @Namespace("/")//声明名称空间
                扩展:
                    @Results({@Result(name="",type="",location="")})//至关于全局的结果配置,仅适用于当前action下的全部方法
            
            方法上的注解
                @Action(value="user_save")
                
                还有:
                    @Action(value="user_save",results={
                            @Result(name="aa",location="/1.jsp"),
                            @Result(name="bb",type="redirect",location="/2.jsp")
                        }
                    )
            
            扩展:
                拦截器没有注解,拦截器还须要在xml中配置,咱们能够经过注解配置访问那个方法的时候使用某个拦截器
                    @Action(value="save",interceptorRefs={
                            @InterceptorRef(value="Demo1MyInterceptor")
                    })
                
            
            
        注意:
            action必须存在于 action | actions | struts | struts2这些包下安全

相关文章
相关标签/搜索