Struct2入门四

OGNL表达式使用和值栈
1、 值栈在开发中应用
主流应用 : 值栈 解决 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方法就可以了
2)ModelDriven 接口 有一个单独拦截器

<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
在拦截器中 ,将model对象 压入了 值栈 stack.push(model);
* 如果Action 实现ModelDriven接口,值栈默认栈顶对象 就是model对象 

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

StrutsPreparedAndExecuteFilter的doFilter代码中 request = prepare.wrapRequest(request);  
    * 对Request对象进行了包装 ,StrutsRequestWrapper 
    * 重写request的 getAttribute 
        Object attribute = super.getAttribute(s);
        if (attribute == null) {
           attribute = stack.findValue(s);
        }
  访问request范围的数据时,如果数据找不到,去值栈中找 

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

3、 OGNL表达式 常见使用
(#、 % 、$ 符号使用 )
1) # 的 使用
用法一 # 代表 ActionContext.getContext() 上下文
————> ActionContext().getContext().getRequest().get(“name”);
#request
#session
#application
#attr
#parameters

用法二 : 不写# 默认在 值栈中root中进行查找
在root中查找name属性
* 查询元素时,从root的栈顶元素 开始查找, 如果访问指定栈中元素 访问栈中第二个元素name属性
* 访问第二个元素对象

用法三 :进行投影映射 (结合复杂对象遍历 )
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 标签用来生成 select、checkbox、radio

<h1>使用#构造map集合 遍历</h1>
    <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表达式,进行解析

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

3) 使OGNLpropertiesmsg=, {#request.username}
在页面



* 自动将值栈的username 结合国际化配置信息显示
用法二 :在Struts 2配置文件中,引用OGNL表达式

contentType {contentType} 读取值栈中contentType数据,在Action提供 getContentType 因为Action对象会被压入值栈,
contentType是Action属性,从值栈获得

结论: #使用ognl表达式获取数据,% 控制ognl表达式是否解析 ,$ 用于配置文件获取值栈的数据
struts2 标签库
tag-reference.html 就是 struts2 标签规范
1、 通用标签库 的学习

<s:property> 解析ognl表达式,设置默认值,设置内容是否HTML转义
<s:set> 向四个数据范围保存数据 
<s:iterator> 遍历值栈中数据 
<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>

OGNL 了解部分 : 支持赋值操作和表达式串联 、 操作集合对象
1) 在值栈中保存一个对象
自动查找值栈中 price 和 name 属性 为其赋值
2) ognl操作集合
访问集合第一个元素name属性
访问map中key为name的值
{} 直接构造List 元素、 #{} 直接构造 Map元素





2、 UI标签库的学习 (Form标签)
使用struts2 form标签 好处 : 支持数据回显 , 布局排班(基于Freemarker 模板定义 )
struts2 表单标签 value属性。 必须写 %{} 进行设值
* 使用struts2表单标签前, 必须配置

StrutsPrepareAndExecuteFilter 
  The Struts dispatcher cannot be found.  This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag

<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
修改主题
方式一 : 只对当前元素有效
方式二 : 对form中所有元素有效
方式三 : struts.xml
修改默认主题样式,页面所有元素都有效
优先级 : 方式一 > 方式二 > 方式三

防止表单重复提交原理
表单防止重复提交
表单重复提交 危害: 刷票、 重复注册、带来服务器访问压力(拒绝服务)

1、 在jsp 通过 生成令牌号
生成表单隐藏域
将令牌号保存到Session

2、 通过struts2 提供 tokenIntercetor 拦截器 完成请求中令牌号 和 session中令牌号 比较

<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/> 
        <action name="token" class="cn.itcast.struts2.TokenAction">
            <result>/index.jsp</result>
            <!-- 重新定义拦截器 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <interceptor-ref name="token"></interceptor-ref>
        </action>

3、 当表单重复提交时,token拦截器自动跳转 result name=”invalid.token”
通过 显示错误信息

覆盖重复提交信息 struts.messages.invalid.token=您已经重复提交表单,请刷新后重试

Struts2 内置json插件
知识点 :struts2 的 Ajax 开发
Ajax开发客户端 和 服务器交互数据格式 ————— json
* json 是最轻量级,体积最小

服务器将程序处理结果,转换为json格式发送给 客户端
* json-lib 、 flexjson 工具类库

  • struts2-json-plugin-2.3.7.jar

案例一: 输入用户名,鼠标点击密码(触发用户名元素离焦事件),使用Ajax 将用户名发送到服务器 判断是否存在
jquery 1.4 、 1.6 新特性比较多 (企业主流 1.4 )

使用struts2 json插件
要点1 : extends 继承 json-default
要点2 : type 类型写 json

**** struts2 json插件 ,默认将值栈root顶端对象 所有属性返回(get方法)

不想将company属性返回 ,在get方法上 @JSON(serialize=false)

案例二 :服务器将 商品对象 List列表返回
如果Action 实现ModelDriven , model对象就是值栈栈顶对象,struts2 json插件默认 将model返回

通过设置root属性,修改插件返回 根对象

<param name="root">action</param> 将Action作为根对象返回 

只想要每个商品的 name 属性
方案一: 在pnum 、price 的get方法上 添加 @JSON(serialize=false) ========= 只要@JSON注解,属性将永远不能参与 json返回
方案二: 设置 includeProperties 属性

<param name="includeProperties">products[\d+\]\.name</param>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值