您的位置:首页 > 编程语言 > Java开发

Struts标签、ongl表达式与值栈

2016-12-14 16:23 501 查看
通常 我们都是

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呀!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  标签 ognl 值栈