zoukankan      html  css  js  c++  java
  • Java中的值栈

    OGNL表示式使用 和 值栈

    OGNLObject Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

    * xwork 提供 OGNL表达式

    * ognl-3.0.5.jar

    OGNL 是一种比EL 强大很多倍的语言

    OGNL 提供五大类功能

       1、支持对象方法调用,如xxx.doSomeSpecial()

       2、支持类静态的方法调用和值访问

       3、访问OGNL上下文(OGNL context)和ActionContext; (重点 操作ValueStack值栈 )

       4、支持赋值操作和表达式串联

       5、操作集合对象。

    1、 使用OGNL访问 对象方法 和 静态方法

    * OGNL jsp 结合 struts2 标签库 使用 , <s:property value="ognl表达式" /> 执行 ognl表达式

    调用 实例方法 对象.方法()  ----  <s:property value="'hello,world'.length()"/>

    调用 静态方法 @[类全名(包括包路径)]@[方法名]  --- <s:property value="@java.lang.String@format('您好,%s','小明')"/>

    * 使用 静态方法调用 必须 设置 struts.ognl.allowStaticMethodAccess=true

    2、 访问OGNL上下文(OGNL context)和ActionContext

    OGNL上下文(OGNL context) 对象 ----- 值栈 ValueStack

    什么是值栈 ValueStack ?

    值栈:简单的说,就是存放action的堆栈,当我们提交一个请求到服务器端 action时,就有个堆栈,如果action在服务器端进行跳转,所有action共用一个堆栈,当需要保存在action中的数据时,首先从栈顶开始 搜索,若找到相同的属性名(与要获得的数据的属性名相同)时,即将值取出,但这种情况可能出现找到的值不是我们想要的值,那么解决此问题需要用TOP语法 和N语法来进行解决。

    0

    ValueStack struts2 提供一个接口,实现类 OgnlValueStack ---- 值栈对象 (OGNL是从值栈中获取数据的 )

    每个Action实例都有一个ValueStack对象 (一个请求 对应 一个ValueStack对象 )

    在其中保存当前Action 对象和其他相关对象 (值栈中 是有Action 引用的 

    Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中,request中 (值栈对象 request一个属性

    valueStack vs = request.getAttribute("struts.valueStack");

    问题二 值栈的内部结构

        值栈由两部分组成

    ObjectStack  (root): Struts  把动作和相关对象压入 ObjectStack --List

    ContextMap   (context): Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap

    Struts 会把下面这些映射压入 ContextMap

    parameters: Map 中包含当前请求的请求参数  ?name=xxx

    request: Map 中包含当前 request 对象中的所有属性

    session: Map 中包含当前 session 对象中的所有属性

    application:Map 中包含当前 application  对象中的所有属性

    attr: Map 按如下顺序来检索某个属性: request, session, application

    ValueStack中 存在root属性 (CompoundRoot) context 属性 (OgnlContext

    * CompoundRoot 就是ArrayList

    * OgnlContext 就是 Map

    context 对应Map 引入 root对象

    * context中还存在 requestsessionapplicationattrparameters 对象引用

    * OGNL表达式,访问root中数据时 不需要 #, 访问 requestsessionapplicationattrparameters 对象数据 必须写 #

    * 操作值栈 默认指 操作 root 元素

    问题三 值栈对象的创建 ValueStack ActionContext 是什么关系 ?

    值栈对象 是请求时 创建的

    doFilterprepare.createActionContext(request, response);

    * 创建ActionContext 对象过程中,创建 值栈对象ValueStack

    * ActionContext对象 对 ValueStack对象 有引用的 (在程序中 通过 ActionContext 获得 值栈对象 )

    DispatcherserviceAction 方法中 将值栈对象保存到 request范围

    request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

    问题四 如何获得值栈对象

    获得值栈对象 有两种方法

    ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

    ValueStack valueStack2 = ActionContext.getContext().getValueStack();

    问题五: 向值栈保存数据 (主要针对 root

    两种方式

    // 将数据保存root的索引0位置,放置到第一个元素 ArrayList add(0,element);

    valueStack.push("itcast");

    // 在值栈创建参数map, 将数据保存到map

    valueStack.set("company", "数据");

    jsp中 通过 <s:debug /> 查看值栈的内容

    问题六: JSP中获取值栈的数据

        访问root中数据 不需要#

        访问 其它对象数据 #

    通过下标获取root中对象

       <s:property value="[0].top"/> //取值栈顶对象

    直接在root中查找对象属性 (自上而下自动查找)

      valueStack:<s:property value="username"/>

    OgnlContext中获取数据

    request:<s:property value="#request.username"/>

    session:<s:property value="#session.username"/>

    application:<s:property value="#application.username"/>

    attr:<s:property value="#attr.username"/>

    parameters:<s:property value="#parameters.cid[0]"/>

    valueStack对象 保存在request范围, 值栈生命周期 就是 request的生命周期 ,值栈的内部结构(rootognlContext

    3、 值栈在开发中应用

    主流应用 值栈 解决 Action JSP 传递 数据问题

    Action JSP 传递数据处理结果 ,结果数据有两种形式

    1) 消息 String类型数据

    this.addFieldError("msg", "字段错误信息");

    this.addActionError("Action全局错误信息");

    this.addActionMessage("Action的消息信息");

    * fieldError 针对某一个字段错误信息 (常用于表单校验)、actionError (普通错误信息,不针对某一个字段 登陆失败)actionMessage 通用消息

    jsp中使用 struts2提供标签 显示消息信息

    <s:fielderror fieldName="msg"/>

    <s:actionerror/>

    <s:actionmessage/>

    2) 数据 (复杂类型数据)

    使用值栈  valueStack.push(products);

    哪些数据默认会放入到值栈 ???

    1)每次请求,访问Action对象 会被压入值栈 ------- DefaultActionInvocation init方法 stack.push(action);

    * Action如果想传递数据给 JSP,只有将数据保存到成员变量,并且提供get方法就可以了 

    2ModelDriven 接口 有一个单独拦截器

    <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

    在拦截器中 ,将model对象 压入了 值栈 stack.push(model);

      user.usernae ---------------?><input name="username"/>

    * 如果Action 实现ModelDriven接口,值栈默认栈顶对象 就是model对象

    4、 值栈的数据 通过EL访问

    问题七:为什么 EL也能访问值栈中的数据

        ActionContext.getContext().getSession().setAttribute("key","value");

        ${requestScope.username}----------->requst.getAttribute("username");------>重写getAttribute()方法,没有找到数据的情况下,继续找ValueStack

    StrutsPreparedAndExecuteFilterdoFilter代码中 request = prepare.wrapRequest(request);

    * Request对象进行了包装 ,StrutsRequestWrapper

    * 重写requestgetAttribute

    Object attribute = super.getAttribute(s);

    if (attribute == null) {

       attribute = stack.findValue(s);

    }

          访问request范围的数据时,如果数据找不到,去值栈中找

    * request对象 具备访问值栈数据的能力 (查找root的数据)

    5OGNL表达式 常见使用

    #% $ 符号使用

    1# 的 使用

    用法一  # 代表 ActionContext.getContext() 上下文

      <s:property value="#request.name" />  ------>  ActionContext().getContext().getRequest().getAttribute("name");

      #request

      #session

      #application

      #attr

      #parameters

    用法二 不写# 默认在 值栈中root中进行查找

       <s:property value="name" /> root中查找name属性

    * 查询元素时,从root的栈顶元素 开始查找, 如果访问指定栈中元素    <s:property value="[1].top.name" />  访问栈中第二个元素name属性

    * 访问第二个元素对象 <s:property value="[1].top" />

    用法三 :进行投影映射 (结合复杂对象遍历

         s:iterator标签在进行遍历时,会将var中保存的这个对象,在root中,和context中都放一份

            所以在<s:property  value=""/>  value属性加不加#都可以访问

       1)集合的投影(只输出部分属性

       <h1>遍历集合只要name属性</h1>

    <s:iterator value="products.{name}" var="pname">

    <s:property value="#pname"/>

    </s:iterator>

       2)遍历时,对数据设置条件

    <h1>遍历集合只要price大于1500商品</h1>

    <s:iterator value="products.{?#this.price>1500}" var="product">

    <s:property value="#product.name"/> --- <s:property value="#product.price"/>

    </s:iterator>

       3)综合

       <h1>只显示价格大于1500 商品名称</h1>

    <s:iterator value="products.{?#this.price>1500}.{name}" var="pname">

    <s:property value="#pname"/>

    </s:iterator>   

    用法四: 使用#构造map集合

    经常结合 struts2 标签用来生成 selectcheckboxradio

    <h1>使用#构造map集合 遍历</h1>

                      #{key:value,kye1:value1}

    <s:iterator value="#{'name':'aaa','age':'20', 'hobby':'sport' }" var="entry">

    key : <s:property value="#entry.key"/> , value:  <s:property value="#entry.value"/> <br/>

    </s:iterator>

    2) %的使用

       用法一: 结合struts2 表单标签使用, 通过%通知struts%{}中内容是一个OGNL表达式,进行解析

       <s:textfield name="username" value="%{#request.username}"/>

       <s:textfield name="username" value="<s:property value='#request.username'/>"  />是错误的

       用法二: 设置ognl表达式不解析 %{'ognl表达式'}

       <s:property value="%{'#request.username'}"/>

    3$的使用

       用法一 :用于在国际化资源文件中,引用OGNL表达式

    properties文件 msg=欢迎您, ${#request.username}

    在页面

        <s:i18n name="messages">

    <s:text name="msg"></s:text>

    </s:i18n>

    * 自动将值栈的username 结合国际化配置信息显示

       用法二 :在Struts 2配置文件中,引用OGNL表达式

    <!-- Action 提供 getContentType方法 -->

    <param name="contentType">${contentType}</param>

           *  ${contentType} 读取值栈中contentType数据,在Action提供 getContentType 因为Action对象会被压入值栈,

          contentTypeAction属性,从值栈获得

    结论: #用于写ognl表达式获取数据,% 控制ognl表达式是否解析 ,$ 用于配置文件获取值栈的数据

    五、 struts2 标签库

    tag-reference.html 就是 struts2 标签规范

    1、 通用标签库 的学习

    <s:property> 解析ognl表达式,设置默认值,设置内容是否HTML转义

    <s:set> 对比c:set向四个数据范围保存数据

    <s:iterator> 遍历值栈中数据 <c:forEach  />

    <s:if> <s:elseif> <s:else> 进行条件判断 -------- elseif 可以有多个

    <s:url> 进行URL重写(追踪Session ) ,结合s:param 进行参数编码

    *   <s:url action="download" namespace="/" var="myurl">

    <s:param name="filename" value="%{'MIME协议简介.txt'}"></s:param>

        </s:url>

        <s:property value="#myurl"/>

    <s:a> 对一个链接 进行参数编码

        * <s:a action="download" namespace="/" >下载MIME协议简介.txt

    <s:param name="filename" value="%{'MIME协议简介.txt'}"></s:param>

      </s:a>

    2UI标签库的学习 (Form标签)

        使用struts2 form标签 好处 : 支持数据回显 , 布局排版(基于Freemarker 模板定义 )

    struts2 表单标签 value属性。 必须写 %{} 进行设值

     使用struts2表单标签前, 必须配置 StrutsPrepareAndExecuteFilter

    <s:form> 表单标签

    <s:form action="regist" namespace="/" method="post" theme="xhtml">  ---   theme="xhtml" 默认布局样式

    <s:textfield> 生成 <input type="text" >

    <s:password > 生成 <input type="password" >

    <s:submit type="submit" value="注册"/> 生成 <input type="submit" >

    <s:reset type="reset" value="重置" /> 生成 <input type="reset" >

    * struts2 除了支持JSP之外,支持两种模板技术 Velocity (扩展名 .vm ) Freemarker (扩展名 .ftl

    <s:textarea> 生成 <textarea> 多行文本框

    <s:checkboxlist> 生成一组checkbox

    * 使用ognl构造 Map (看到值和提交值 不同时)

    * <s:checkboxlist list="#{'sport':'体育','read':'读书','music':'音乐' }" name="hobby"></s:checkboxlist>

    <s:radio> 生成一组radio

    * 使用 ognl构造 List  (看到内容和提交值 相同时)

    * <s:radio list="{'',''}" name="gender"></s:radio>

    <s:select> 生成一个<select>

    * <s:select list="{'北京','上海','南京','广州'}" name="city"></s:select>

    struts2 开发 密码框 默认不回显

          <s:password name="password" id="password" showPassword="true"/>

    3、 页面元素主题设置

        default.properties  ----  struts.ui.theme=xhtml 设置struts2 页面元素使用默认主题

                              struts.ui.templateSuffix=ftl 默认模板引擎 Freemarker

    修改主题

         方式一 <s:textfield name="username"  label="用户名“ theme="simple"></s:textfield> 只对当前元素有效

     方式二 <s:form  action="" method="post" namespace="/ui“    theme="simple"> form中所有元素有效

     方式三 struts.xml

         <constant name="struts.ui.theme" value="simple"></constant>  修改默认主题样式,页面所有元素都有效

         优先级 方式一 > 方式二  > 方式三

  • 相关阅读:
    golang GC(二 定位)
    MySQL的安装与配置——详细教程
    js实现关闭浏览器
    解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
    如何将将本地电脑部署成服务器
    Mysql统计每年每个月的数据——详细教程
    博客、笔记
    JAVAWEB实现修改功能
    JAVAWEB实现添加功能
    JavaWeb实现删除功能
  • 原文地址:https://www.cnblogs.com/MessiAndDream/p/5869319.html
Copyright © 2011-2022 走看看