一、OGNL
Object Graphic Navigation Language 对象图导航语言
依赖于 ognl.jar包
OGNL不是Struts框架独有的,它是和框架独立的一种技术。
例如:这样一个java项目中也能用
package com.test.struts.entity; import java.io.Serializable; public class Person implements Serializable{ private String name; private Address address; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
package com.test.struts.entity; import java.io.Serializable; public class Address implements Serializable{ private String street; private String num; public Address(String street, String num) { super(); this.street = street; this.num = num; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getNum() { return num; } public void setNum(String num) { this.num = num; } }
package com.test.struts.entity; import ognl.OgnlException; public class Test { public static void main(String[] args) throws OgnlException { Person p = new Person(); p.setName("dawanganban"); p.setAddress(new Address("http://blog.csdn.net/dawanganban", "110")); //使用ognl工具对属性做操作 String val = (String) ognl.Ognl.getValue("address.street", p); System.out.println(val); //改变里面的值 ognl.Ognl.setValue("address.street", p, "http://www.baidu.com"); String val2 = (String) ognl.Ognl.getValue("address.street", p); System.out.println(val2); } }
其作用如下:
(1)对属性获取和设置
(2)调用对象方法
(3)调用静态属性和方法
(4)对集合进行过滤
(5)支持java中的运算符和操作符
(6)定义List常量{"男","女"}
(7)定义Map常量#{"M":"男","F":"女"}
二、Struts2标签
Struts2使用OGNL表达式来访问ValueStack中的信息。
struts2提供了很多的标签,有些标签需要指定OGNL表达式。
struts2标签库在jar包中的位置 :struts2-core/META-INF/struts-tags.tld
(1)通用标签
debug ,properties, date, if...else, iterator, bean, push, action
<s:debug></s:debug> :显示值栈状态
下面以一个例子来说明:
新建立一个工程,代码结构如下:
所添加的jar包如下(我下载的是struts-2.3.15.3-all.zip)
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>myproject</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="struts2.2" extends="struts-default"> <action name="sample01" class="com.test.ognl.action.Simple01Action"> <result>Simple01.jsp</result> </action> </package> </struts>Simple01Action
package com.test.ognl.action; import java.util.Date; import com.opensymphony.xwork2.ActionSupport; public class Simple01Action extends ActionSupport{ private String name; private Date dt; public String execute(){ name = "tom"; dt = new Date(); return "success"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getDt() { return dt; } public void setDt(Date dt) { this.dt = dt; } }
Simple01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s" %> <!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>Insert title here</title> </head> <body> <s:debug></s:debug> </body> </html>
注意:上面jsp需要引入标签 <%@taglib uri="/struts-tags" prefix="s" %>
最后的结果
如果想获取上面的name属性和dt属性
从Value Stack Contents中直接取,从Stack Context中取要用#key
<s:property value="name"/> <s:property value="dt"/>
如果想格式化日期,则可以用<s:date>标签
<s:date name="dt" format="yyyy年MM月dd日"/>
session信息位于Stack Context中,下面我们来从页面读取session中的值:
public String execute(){ name = "tom"; dt = new Date(); //Map<String, Object> session = ActionContext.getContext().getSession(); 或者 Map<String, Object> session = (Map<String, Object>) ActionContext.getContext().get("session"); session.put("msg", "Session Value Message"); return "success"; }
<s:debug></s:debug> 姓名:<s:property value="name"/><br/> 日期:<s:date name="dt" format="yyyy年MM月dd日"/><br/> session Message:<s:property value="#session.msg"/>
打开Debug可以看到如下内容
比较特殊的是attr先寻找request如果没有再找session(范围由小到大).
下面来看看if...else标签
添加一个int price属性,并初始化为10000
价格:<s:property value="price"/>( <s:if test="price>5000"> 太贵了 </s:if> <s:elseif test="price<5000"> 太便宜了 </s:elseif> <s:else> 很合适 </s:else> )那么如果有一个属性String sex = "M",想判断如果是"M"在页面显示“男”,"F"在页面显示“女”像上面这样用“==”判断行不行呢?答案是不行的。在struts标签里面可以用函数,应该这样做:
性别:<s:if test='sex.equals("M")'> 男 </s:if> <s:else> 女 </s:else>
下面来看看iterator迭代标签
新添加一个Address实体类
package com.test.ognl.action; import java.io.Serializable; public class Address implements Serializable{ private String street; public Address(String street) { super(); this.street = street; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } }添加一个集合属性并迭代赋值
private List<Address> adds = new ArrayList<Address>();标签里面:
<ul> <s:iterator value="adds" var="address"> <li> <s:property value="#address.street"/> </li> </s:iterator> </ul>
这里的value属性如果是在栈里面(Action中)则直接写,如果在session中则需要加“#”,var是临时创建的一个变量,该变量会保存在context中,所以下面取值的时候是#address.street.
最后的结果:
其实还可以这样写
<ul> <s:iterator value="adds"> <li> <s:property value="street"/> </li> </s:iterator> </ul>为什么可以这样写呢?
这是因为<s:iterator>这个标签在执行的时候会首先将要迭代的对象(如上面的adds)放入栈,当执行完后出栈。
<s:iterator>标签还有一个属性 status (迭代状态对象,存储迭代时候的状态信息)
<ul> <s:iterator value="adds" var="address" status="stat"> <li> <s:property value="#stat.index"/>: <!-- 索引 --> <s:property value="#stat.count"/>: <!-- 数量 --> <s:property value="#stat.even"/>: <!-- 是否是奇数 --> <s:property value="#stat.first"/>: <!-- 是否是第一个元素 --> <s:property value="#address.street"/> </li> </s:iterator> </ul>
接下来我们来看一下这个<s:bean>标签,这个标签可以创建一个对象放到context中。
先写一个Bean
package com.test.ognl.action; public class ModelBean { private String hello; public ModelBean() { hello = "http://blog.csdn.net/dawanganban"; } public String getHello() { return hello; } public void setHello(String hello) { this.hello = hello; } }标签中创建该对象,并取出属性。
<s:bean name="com.test.ognl.action.ModelBean" var="mBean"></s:bean> <s:property value="#mBean.hello"/>下来再了解一下<s:push>标签,这个标签是临时压栈标签
<s:push value="10">
//如果出了这个标签,压栈后的值会出栈。
</s:push>
最后再了解一下<s:action>标签
这个标签可以实现一个页面中分多个模块,各个模块可以分别请求。
<s:action name="" namespace="" executeResult="true"></s:action>
如果executeResult="false"只会执行业务方法,不会将返回页面显示。
(2)表单标签
form, textfield, password, checkbox, checkboxlist, radio,select, optgroup
这些表单标签比原始的html中的表单标签功能强大的多,可以实现默认填充等功能。下面我们来具体看一下。首先创建一个新的Action。
package com.test.ognl.action; public class Simple02Action { private String name; private String pwd; private int age; private String email; private String sex; private boolean marry; public String execute() { name="大碗干拌"; pwd="1234"; age=20; email="739299362@qq.com"; sex = "M"; marry = true; return "success"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public boolean isMarry() { return marry; } public void setMarry(boolean marry) { this.marry = marry; } }使用<s:form>标签
<s:form action="simple02" namespece="/"> </s:form>
查看页面源代码:
<!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>Insert title here</title> </head> <body> <h1>表单信息</h1> <form id="simple02" name="simple02" action="simple02" method="post" namespece="/"> <table class="wwFormTable"> </table></form> </body> </html>
我们发现struts标签默认为我们添加了很多属性,如:method=“post" ,但是有一点是我们不希望的,它在下面生成了<table>标签,这会影响我们对页面的设计,那么这该怎么办呢?其实很简单,可以添加一个属性theme="simple"
<s:form action="simple02" namespece="/" theme="simple"> </s:form>页面源代码:
<!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>Insert title here</title> </head> <body> <h1>表单信息</h1> <form id="simple02" name="simple02" action="simple02" method="post" namespece="/"> </form> </body> </html>下面我们来看一下表单中用到的标签
<s:form action="simple02" namespece="/" theme="simple"> 姓名:<s:textfield name="name"/><br/> 密码:<s:password name="pwd" showPassword="true"/><br/> 年龄:<s:textfield name="age"/><br/> Email:<s:textfield name="email"/><br/> 性别:<s:radio list='#{"M":"男","F":"女"}' name="sex"/><br/> 是否已婚:<s:checkbox name="marry"/><br/> <s:bean name="com.test.ognl.action.ModelBean" var="data"></s:bean> 个人爱好:<s:checkboxlist name="myloves" list="#data.loves" listKey="key" listValue="value"/> </s:form>
运行结果:
说明:上面的“性别”部分是一个标签中的Map集合, 个人爱好部分的name是选中的项目集合, data是所有项目集合。
源代码下载:http://download.csdn.net/detail/lxq_xsyu/6459689
请看下节.......