Struts标签、ongl表达式与值栈

通常 我们都是
Struts标签和ognl表达式组合使用、
jstl(java核心标签库)标签和EL表达式组合使用

Struts2主要将标签分为以下几类

引入struts标签库 <%@taglib prefix=”s” uri=”/struts-tags” %>
控制标签
用于完成输出流程控制
例如:分支、循环等操作,也可以完成对集合的合并、排序等操作
主要有以下几种
if、elseif/elseif、else、append、generator、iterator、merge、sort、subset

条件控制:

标签体


标签体


标签体

循环标签

用于对象集合进行迭代
集合可以是List、Set和数组,也可以对Map类型的对象进行迭代输出
常用属性
value:指定被迭代的的集合,被迭代的集合通常都是OGNL表达式指定,若没有指定value属性,则使用ValueStack栈顶的集合
id:指定集合元素里面的id
status:指定迭代时的IteratorStatus实例,通过该实例可判断当前迭代元素的属性,status.index代表循环下标,从0开始,status.count代表数量,从1开始。

<s:iterator value="#request.students" var="student" status="st">
<s:if test="#st.even">
<tr style="background: red"><td><s:property value="#student.name"/></td><td><s:property value="#student.age"/></td></tr>
</s:if>
<s:else>
<tr style="background: #abcdef"><td><s:property value="#student.name"/></td><td><s:property value="#student.age"/></td></tr>
</s:else>
</s:iterator>

数据标签

用于提供各种数据访问相关的功能
包含显示一个Action里面的属性,以及生成国际化输出功能
主要用于访问ValueStack中的数据
主要包含如下标签
action:用于在jsp页面直接调用一个Action
bean:用于创建JavaBean实例
date:用于格式化输出一个日期

debug :用于在页面上生成一个调试链接,当单击该链接时,可以看到当前ValueStack和StackContext中的内容
i18n :用于指定国际化资源文件的baseName
include :用于在jsp界面中包含其他的jsp或Servlet资源
param :用于设置一个参数,通常作为bean、url标签的子标签
push :将某值放入ValueStack栈顶
set :设置新变量,并将变量放入指定范围内
text :输出国际化消息
url :生成URL地址
property:用于输出某个值

一些例子


1.  s:action ------------在页面上直接执行action,并把返回的结果包含到该页面。
调用第一个Action,并将结果包含到本页面<br />
    <div style="width:300px;height:300px;border:1px solid blue">
    <s:action name="logic1" executeResult="true" />
     </div> 
    <hr />
    调用第二个Action,并将结果包含到本页面<br />
    阻止本页面请求参数传入Action<br />
    <s:action name="logic2" executeResult="true" ignoreContextParams="true" />
    <hr />
    调用第二个Action,不将结果包含到本页面<br />
    <s:action name="logic2" executeResult="false" />
2.  s:bean—定义一个javabean对象,并把它放到ognl上下文,访问用#
<!-- 使用Student创建对象,并指定id -->
    <s:bean name="com.jmt.bean.Student" var="stu">
        <s:param name="name" value="'张三'" />
        <s:param name="age" value="23" />       
    </s:bean>
    <!-- 根据Student实例指定的id访问JavaBean实例 -->
    我是 <s:property value="#stu.name" />,今年
    <s:property value="#stu.age" />岁!
3.  程序控制逻辑的标签之一:if  elseif else

    <s:if test="#month>9">
        第四季度
    </s:if>
    <s:elseif test="#month>6">
        第三季度
    </s:elseif>
    <s:elseif test="#month>3">
        第二季度
    </s:elseif>
    <s:else>
        第一季度
    </s:else>
4.  程序控制逻辑标签之二:循环标签
<%
   List<Student> lst=new ArrayList<Student>();
   Student stu=new Student();
   stu.setName("zhagnsan");
   stu.setAge(18);
   lst.add(stu);
   Student stu1=new Student();
   stu1.setName("lisi");
   stu1.setAge(28);
   lst.add(stu1);
   request.setAttribute("students", lst);

%>
<body>
    <ol>    
    <s:iterator value="#request.students" var="student">
        <li><s:property value="#student.name"/> </li>
    </s:iterator>
    </ol>



5.  date
<%
        Date date = new Date();
        pageContext.setAttribute("datetime", date);
    %>
    1.nice="false",日期格式设置为yyyy/MM/dd<br />
    <s:date name="#attr.datetime" format="yyyy/MM/dd" nice="false"/>
    <hr/>

    4.nice="false"<br />
    <s:date name="#attr.datetime" nice="false" format="yyyy-MM-dd hh:mm:ss"/>
    <hr/>
6.  include
1.无param
    <s:include value="include_file.jsp" />
    <hr/>
    2.有param
    <s:include value="include_file.jsp">
        <s:param name="num" value="100" />
    </s:include>

UI标签:
日期控件
1.用struts-dojo-tags,需要引入一个struts-dojo.jar
2. <%@ taglib prefix=”sx” uri=”/struts-dojo-tags” %>
3.
4.在html的head中加一句,目的是为了给日期框加样式
另一个日期插件
下面的代码直接就实现了日历选择框:
1. 先将datepicker文件夹复制到webcontent下面。
2. 页面引入
3.
推荐使用WdatePicker.js


表单系列

**struts的form表单**
<s:form action="register" namespace="/">

<s:textfield name="username" label="用户名" ></s:textfield>
<s:password name="password" label="密码" ></s:password>
<s:textfield name="age" label="年龄"></s:textfield>

<s:submit></s:submit>

</s:form>


注意:
如果不想采用Struts默认样式,可以加theme=”simple”
加样式不能直接加style,在Struts标签中用:cssStyle=””

**Select标签:**
<s:form>
   <%-- <s:textfield name="username" label="用户名"></s:textfield>
   <s:textfield name="password" label="密码"></s:textfield>
   <s:select list="{'Java','C','C++','C#','php'}" label="书籍" name="book"></s:select>
   <s:checkboxlist list="{'Java','C','C++','C#','php'}" label="爱好" name="hobby"></s:checkboxlist>
   <s:radio list="{'男','女'}" label="性别" name="sex"></s:radio>

   <s:select list="#{'01':'Java','02':'C','03':'C++'}" listKey="key" listValue="key" label="书籍" name="book"></s:select>
   <s:checkboxlist list="#{'01':'Java','02':'C','03':'C++'}" listKey="key" listValue="value"  label="爱好" name="hobby"></s:checkboxlist>
   <s:radio list="#{'0':'男','1':'女'}" label="性别" listKey="key" listValue="value"  name="sex"></s:radio> --%>

 <s:select list="books" label="书籍" name="book" listKey="bookNum" listValue="bookName"></s:select>
   <s:checkboxlist list="books" label="爱好"  listKey="bookNum" listValue="bookName" name="hobby"></s:checkboxlist>
</s:form>
上述也可以是后台数据填充到下拉框和勾选框等等。

要什么包之类的可以评论里要

ognl

OGNL 是一个开源的项目。
全称是Object Graphic Navigation Language,对象图导航语言
它是一种强大的表达式语言,可以通过简单一致的表达式语法来读取和设置Java对象的属性值、调用对象的方法、遍历整个对象的结果图、实现字段类型转换等功能
它是一个开源项目,官方站点为www.ognl.org
OGNL表达式的计算是围绕OGNL上下文来进行的
OGNL上下文实际就是个Map对象,由ognl.OgnlContext类(实现了java.util.Map接口)
OGNL上下文包含多个JavaBean对象,其中包含一个特殊对象,称为根对象(root)
在写表达式时,若没指定使用上下文中的某个对象,则根对象作为表达式所依据的对象
在写表达式时,访问根对象的属性property就直接书写属性,否则需要使用#key作为前缀,如:#javabean.property
OGNL表达式中的属性(property)是JavaBean的属性,而不是类中的实例变量

Ognl项目使用?

// ognl访问对象 
//      1.构建一个容器OgnlContext
        OgnlContext ctx=new OgnlContext();
//      2.创建数据
        User user=new User();
        user.setUsername("xiaoming");
        user.setPassword("ok");
        User ruser=new User();
        ruser.setUsername("rxiaoming");
        ruser.setPassword("ok");
        List<User> users=new ArrayList<>();
        users.add(user);
        users.add(ruser);
//      3.向容器中放入数据
        ctx.put("aa","aaaa");
        ctx.put("user", user);
        ctx.put("users", users);
        ctx.setRoot(ruser);//设置根元素
//      4.模拟页面获取ognl表达式值
        Object rexp=Ognl.parseExpression("username");//返回UI个表达式
        Object exp1=Ognl.parseExpression("#user.username");//返回非根表达式
        Object exp2=Ognl.parseExpression("#users[1].username");//返回非根表达式
//      5.求值
        Object rval=Ognl.getValue(rexp, ctx,ctx.getRoot());
        System.out.println("根元素的名字:"+rval);
        Object val1=Ognl.getValue(exp1, ctx,ctx.getRoot());
        System.out.println(val1);
        Object val2=Ognl.getValue(exp2, ctx,ctx.getRoot());
        System.out.println(val2);

如何在struts中使用ognl表达式?

要结合struts标签
而OGNL上下文等价于Action上下文。
属性名
例如,student.name
方法调用
例如,student.sayHi()
数组索引
例如,arrays[0],返回数组中的第一个元素
上代码吧
action

package king.zyt.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;

import king.zyt.entity.User;

public class OgnlAction {

    private int age=100;
    private User fuser;

    public User getFuser() {
        return fuser;
    }
    public void setFuser(User fuser) {
        this.fuser = fuser;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }



    public String ognl(){

        //造数据
        User user=new User();
        user.setUsername("小日");//user 小日
        user.setPassword("ok");
        User ruser=new User();//ruser 小月
        ruser.setUsername("小月");
        ruser.setPassword("ok");
        List<User> users=new ArrayList<>();//List  明
        users.add(user);
        users.add(ruser);

        //向页面返回数据
        ActionContext ctx = ActionContext.getContext();
        ctx.put("user", user);//小日
        Map request = (Map)ctx.get("request");//用上下文返回数据
        request.put("requestUsername", "requestUsername");//requestUsenrame  用request返回数据
        Map session=ctx.getSession();
        session.put("sessionUsername", "sessionUsername");//requestUsenrame  用session返回数据
        request.put("list", users);//明
        fuser=new User();
        fuser.setUsername("rootusername");//设置一个用户的用户名为
        //获取值栈
        ValueStack vs = ctx.getValueStack();

        vs.push("zyt");//向栈顶加数据

        return "ognl";
    }
}

jsp调用 重点重点

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Ognl表达式</title>
</head>
<body>
<s:debug></s:debug>
<h2>显示action返回的响应数据</h2>
<h3>获取ctx作用域的username</h3>
<s:property value="#user.username"/>
<hr>
<h3>获取request作用域的username</h3>
<s:property value="#request.requestUsername"/>

<hr>
<h3>获取session作用域的username</h3>
<s:property value="#session.sessionUsername"/>
<hr>
<h3>获取req作用域的list</h3>
<s:property value="#request.list[0].username"/>
<s:property value="#request.list[1].username"/>
<hr>
<h3>创建集合</h3>
<s:property value="{'你','大','爷'}[1]"/>

<h3>创建Map集合</h3>
<s:property value="#{'1':'success','2':'fail' }.get('2')"/>

<hr>
<h3>投影</h3>
 <s:property value="#request.list.{password}"/>


<hr>
<h3>投影过滤</h3>
 <s:property value="#request.list.{?#this.username=='小日'}.{username}"/>

 <s:property value="#request.list.{?#this.password=='ok'}[0].username"/>
 <s:property value="#request.list.{?#this.password=='ok'}.{username}"/>
<s:property value="#request.list.{?#this.username=='小月'}.{username}"/>

<hr>
<h3>访问action属性,action在值栈中</h3>
 <s:property value="age"/>
<s:property value="fuser.username"/>


<hr>
<h3>获取栈顶元素</h3>

<s:property/>


<hr>
</body>
</html>

1:#作为前缀———-位于OGNL上下文(ActionContext)
2:不用#——————-访问上下文的root节点

OGNL支持访问静态方法

OGNL支持调用类中的静态方法和静态字段,语法如下:
调用静态方法
@class@method
访问静态字段
@class@field
说明
其中的class必须是完整的类名,例如:将字符串“120”转换为数字,则使用Integer.valueOf(“120”);
若省略class,则默认调用的类是java.lang.Math
调用java.lang.Math类的静态成员先对简单,例如
调用Math类的min()方法,@@min(10,8)

访问前提,需要修改struts.xml文件:在package上面加一句:

解释下投影和过滤集合

上方jsp代码部分有提到
投影
OGNL提供了一种简单方式在一个集合上对每个元素调用相同的方法,并将其结果保存为一个新的集合
例如
persons是一个包含了person对象的列表,#persons.{name}将返回所有人的名字
投影期间可以使用#this表示当前元素的引用
objects.{ #this instanceof java.lang.String ? #this : #this.toString() }
表示将对象列表中的元素作为字符串值产生一个新的元素列表

过滤结合
OGNL提供了一种简单的方式来使用表达式从集合中选择某些元素,并将其结果保存到新的集合中
例如

persons.{?#this.age > 20}

persons表示包含了person对象的列表,返回年龄大于20的所有用户

persons.{?#this.age > 20}[0]

表示返回年龄大于20的所有用户中的第一个用户
需要注意防止发生ArrayIndexOutOfBoundsException异常

注意符号的含义:
?:表示选取匹配逻辑的所有元素
例如,#persons.{?#this.age > 20}
persons表示包含了person对象的列表,返回年龄大于20的所有用户
^:表示选取匹配选择逻辑的第一个元素
例如, #persons.{^#this.age > 20}
persons表示包含了person对象的列表,返回年龄大于20的所有用户中的第一个
:表示选取匹配选择逻辑的最后一个元素  
例如, #persons.{
#this.age > 20}
persons表示包含了person对象的列表,返回年龄大于20的所有用户中的最后一个

值栈 ValueStack

Struts2将OGNL上下文设置为Struts2中的ActionContext,并将值栈作为OGNL的根对象
值栈类似于正常的栈,遵循后进先出的栈特点
可以在值栈中存入、删除和查询对象,它是Struts2的核心
值栈是通过接口(com.opensymphony.xwork2.util.ValueStack)来定义,对应的实现类是com.opensymphony.xwork2.ognl.OgnlValueStack
ActionContext对象中还放置了其他对象,包括表示application、session和request的Map对象。这些对象共存于ActionContext中,靠在值栈(OGNL根对象)的旁边

如何访问值栈?
OGNL上下文中的值栈对象可以直接访问,但引用上下文中其他对象需要使用井号(#)来标记
在Struts2中,可以自动从栈顶到栈底查找栈内所有的对象,直到查找到一个具有指定查找属性的对象
即,值栈中的任意对象都可以直接访问,而不需要使用井号(#)
例如
有Person和Student对象,都具有name属性,先往栈里存入Person对象,再存入Student对象, Student对象位于栈顶
那对于表达式name,则表示访问Student中的name属性,因为Student位于栈顶,先找到Student对象

Action是值栈的根,访问其中属性
Struts2框架总是把Action实例放置在栈顶
由于Action在值栈中,而值栈又是OGNL的根,所以在引用Action属性时可以省略“#”标记
例如

表示输出栈顶的Action实例的xxx属性,但访问其他对象时,需要使用“#”标记

代码呢?还是上面的jsp呀!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值