Struts标签、ongl表达式与值栈

来源:互联网 发布:医疗网络咨询工资待遇 编辑:程序博客网 时间:2024/06/06 02:48

通常 我们都是
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.  include1.无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