- 浏览: 676937 次
- 性别:
- 来自: 安徽
文章分类
- 全部博客 (252)
- Html/Div+CSS (12)
- Js/Jquery (34)
- Flex (2)
- Ajax (3)
- Java (35)
- C# (15)
- Spring (16)
- Hibernate (13)
- Struts2 (12)
- Struts1 (7)
- DWR (1)
- iBatis/myBatis (9)
- Tag(JSTL、EL) (1)
- Android (44)
- SQL (7)
- SEO (7)
- Exception (3)
- Tool (10)
- Other (3)
- WebService (9)
- Apache (7)
- Ext (0)
- Utils (12)
- thinking in programme (2)
- Hadoop (0)
- ActiveMQ (0)
- HTML5/CSS3 (0)
- WPF (1)
- NodeJs (1)
- 设计模式 (0)
- 程序人生 (1)
- 随笔 (1)
- Linux (1)
- Load Balance (0)
最新评论
-
drinkjava2:
太复杂了而且不通用,利用ThreadLocal可完美解决这一问 ...
JDBC的多条件动态查询 -
u013107014:
multipartRequest.getFiles(" ...
多文件上传 by MultipartFile and Multiple -
liyys:
可惜没讲你mysql数据库的表的设计
iBatis入门 -
Mapple_leave:
效果还是挺不错的,谢谢了。
中文简体与繁体的转换 -
arcpad:
JS禁用浏览器退格键
OGNL ,作为Struts2 一大亮点,感觉也是Struts2 中相对最难理解的一部分了。所以这里认真的总结学习一下。
值栈分析:
MVC 请求处理流程中,牵涉的数据种类比较多,框架使用ValueStack 数据结构对这些数据结构进行有机的整合,便于统一管理。充分认识ValueStack 数据结构可以便于框架使用者轻松自如获取所需的数据。
ValueStack 由ValueStack Contents 和Stack Context 两部分构成
每个请求都会生成一个对应的Action 实例,每一个动作在执行相应方法( 默认execute 方法) 之前,都会创建一个ValueStack 的对象。ValueStack 用来保存这个动作对象和其他对象( 请求处理所涉及的数据);
ValueStack 对象相当于一个栈,它贯穿整个Action 的生命周期,每个Action 类的对象实例都会拥有一个ValueStack 对象。
当Struts2 接受到一个*.action 请求后,并不是直接调用Action 方法,而是先将Action 类的相应属性放到ValueStack 对象的顶层节点
值栈也是位于内存中,它也是和parameters 、request 、session 、application 、attr 对象放在一起的。值栈属于ONGLContext 里面的根对象。也就是说它位于整个内存中最最重要的地方,所以叫根对象
根对象和另外五个对象是有区别的,根对象可以省写# 号,比如<s:property value="user.username"/> 。值栈的生命周期与request 请求相关,每次请求产生一个值栈。默认所有的Action 会被自动放到值栈里
生命周期内置对象被封装在一个Map 结构中。
在跳转的页面上加一个struts 标签-<s:debug/> 可以看到ValueStack 结构。
假设从一个Action1 通过服务器跳转到Action2 的话,就意味着这两个Action 是共享一个值栈的,因为一次请求只使用一个值栈。这时内存中情况是这样的:首先接收到Action1 请求后,会产生一个值栈,在栈顶存放Action1 对象以及它所有的属性,然后经过服务器跳转到Action2 ,这时就会把Action2 对象压入值栈的栈顶位置,此时Action1 对象以及它的所有属性就位于栈底了。
取值过程(原则:后进先出):
栈的特征是后进先出。所以首先到栈顶的对象里查找是否存在这个属性,如果栈顶的Action2 对象中不存在这个属性的话,它就会继续向下寻找直至栈底对象,一直查找是否存在这个属性,如果最后找到该属性的话,那么就会在JSP 页面中通过<s:property value="username"/> 输出属性值。如果在Action2 和Action1 都有一个同名的同类型的username 属性的话,那么将输出Action2 中的属性值。因为它是先从栈顶开始寻找属性的,值栈的特征就是后进先出 ,但有个前提:请求过程是通过服务器跳转的。
三个语法:
假设此时想要获取Action11
中的username
属性的话,就可以使用值栈的Top
语法
或者N
语法
。
1
、使用Top
语法
获取值栈中的第二个对象的属性:
<s:property
value="[1].top.username"/>
2
、使用N
语法
获取值栈中的第二个对象的属性:<s:property value="[1].username"/>
3
、@
语法
,例如使用@
语法调用Action
中的静态方法:<s:property
value="@vs@getVOMethod()"/>
@vs@get()
等价于@vs1@getVOMethod()
,指的是栈顶对象的静态getVOMethod()
方法
同理@vs2@getVOMethod()
就是取值栈中第二个对象的静态getVOMethod()
方法
客户端跳转时使用各自的值栈:
假如中间某一个步骤中出现了客户端跳转的话,那么两个Action
所使用的就是两个不同的值栈了。所以在Action2
中就不能再使用Action1
中的属性了,在最后跳转到的JSP
页面中也就无法获取Action1
的属性了。即从Action2
跳转到JSP
页面时使用的是redirect
的话,那么最后值栈中是没有任何的Action
对象的。这个时候我们可以通过链接传参,比如<result
type="redirect">test.jsp?netname=${username}</result>
意思就是取出Action2
中的username
属性作为参数,通过浏览器地址栏传递到JSP
页面中
然后使用OGNL
中的#
号
获取Paraments
对象的属性,即<s:property
value="#parameters.netname"/>
就可以取到值了。
手工向值栈中压入对象:
正 常情况下值栈保存的是Action 对象,而我们也可以直接往值栈中添加其它对象,这时可以在Action 中添加如下代码向值栈中添加对象:
ActionContext.getContext.getValueStack().push(new
Student("xdwang",23));
而且我们手工往值栈中添加的Student
对象会位于栈顶
。这是因为Struts2
会首先初始化Action
,然后才能调用它的方法。初始化Action
的时候,便把Action
放到值栈中了,然后在执行它的execute()
方法时,就又往值栈中添加了Student
对象。
OGNL 历史:
OGNL 最初是为了能够使用对象的属性名来建立 UI 组件 (component) 和 控制器 (controllers) 之间的联系,简单来说就是:视图与控制器之间数据的联系 。后来为了应付更加复杂的数据关系。
什么是OGNL :
OGNL 是 Object-Graph Navigation Language 的缩写, 对象图形导航语言 , ,从语言角度来说:它是一种 操作复杂数据结构的常用语言 ,它旨在提供一个更高抽象度语法来对 java 对象图进行导航。
可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性;
对象通过OgnlContext上下文对象来管理。
OGNL可以让我们用非常简单的表达式访问对象层。
OGNL 应用:
1 、作为 GUI 元素(textfield,combobox, 等)到模型对象的绑定语言;
2 、数据库表到 Swing 的 TableModel 的数据源语言;
3 、web 组件和后台 Model 对象的绑定语言 (WebOGNL,Tapestry,WebWork,WebObjects) ;
4 、作为 Jakarata Commons BeanUtils 或者 JSTL 的表达式语言的一个更具表达力的替代语言;
表达式语言(EL)本质上被设计为:帮助你使用简单的表达式来完成一些“常用”的工作。通常情况下,ELs 可以在一些框架中找到,它被是用来简化我们的工作。例如:大家熟知的 Hibernate,使用 HQL(Hibernate Query Language) 来完成数据库的操作,HQL 成了开发人员与复查的 SQL 表达式之间的一个桥梁。 在 web 框架下,表达式语言起到了相似的目的。它的存在消除了重复代码的书写。例如:当没有 EL 的时候,为了从 session 中得到购物车并且将 ID 在网页上呈现出来,当直接在 jsp 中使用 java 代码来完成的时候,一般是:
<% ShoppingCart cart = (ShoppingCart) session.get("cart"); int id = cart.getId(); %> <%= id%>
你也可以将这些 code 压缩成一句,如下,但是现在代码就很不直观,且不可读。另外,虽然变成了一句,但是与上面的原始的例子一样,也包含了同样的表达式。例如:类型转换:转换 成 ShoppingCart 。这里只不过是将原来的三个表达式变成了一句,其复杂度是没有得到简化的。
<%= ((ShoppingCart) session.get("cart")).getId() %>
当在 web 框架中使用表达式语言的时候,则可以有效的处理这种代码的复杂性。而不需要你,调用 servelet API,类型转换,然后再调用 getter 方法,多数的 Els 都可将这个过程简化为类似于:#session.cart.id 这中更可读的表达式。 表达式:#session.cart.id 与 java 代码不一样的是:没有 java 代码的 get 方法调用和类型转换。因为这些操作是非常“常用”的,这时候使用 EL 就顺理成章了,使用 EL 可以“消除”这些代码。
OGNL标识符:
“$”有两个主要的用途:
1、 用于在国际化资源文件中,引用OGNL表达式:
validation.require=${getText(fileName)} is required
2、 在Struts 2配置文件中,引用OGNL表达式:
<action name="AddPhoto" class="addPhoto"> <result type="redirect"> ListPhotos.action?albumId=${albumId} </result> </action>
“# ”, 一般用于取出堆栈上下文中存放的对象和过滤、投影集合。这里我们可以将 # 理解为 ActionContext.getContext()
1 、取出堆栈上下文:
名称 |
作用 |
Demo |
attr |
用于按 request>>session>>application 顺序访问其属性 |
#attr.userName 相当于按顺序从三个范围读取 userName 属性直到找到为止 |
request |
包含当前 HttpServletRequest 的属性的 Map |
#request.userName 相当于 request.getAttribute("userName") |
session |
包含当前 HttpSession 的属性的 Map |
#session.userName 相当于 session.getAttribute("userName") |
application |
包含当前应用的 ServletContext 的属性的 Map |
#application.userName 相当于 application.getAttribute("userName") |
parameters |
包含当前 HTTP 请求参数的 Map |
#parameters.id[0] 相当于 request.getParameter("id") |
2、 用于过滤和投影(projecting)集合
如person.{?#this.age>20}
? -- 获取集合中所有满足选择逻辑的对象( 拿sql 来做比例就是"select * from xxx where age>20")
^ -- 获取集合中第一个满足选择逻辑的对象( 拿sql 来做比例就是"select top(1) from xxx where age>20")
$ -- 获取集合中最后一个满足选择逻辑的对象
%:用途是在标识的属性为字符串类型时,计算OGNL表达式的值,即将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用
<s:url value="test.jsp?age=#userlist['admin']">→test.jsp?#userlist['admin']---可见当字符串与OGNL表达式串起来时,只会被当作字符串对待,并不执行 <s:url value="test.jsp?age=%{#userlist['admin']}">→test.jsp?age=44---使用了该符号,就可以使得OGNL表达式被执行
<s:set name="hello" value="5"></s:set> <s:property value="#hello" /> <s:property value="%{#hello}" /> <s:if test="%{#hello==5}">你好</s:if> <s:if test="#hello==5">你好</s:if> <s:set name="china" value="'你好'"></s:set> <s:property value="#china" /> <s:property value="%{#china}" /> <s:if test="%{#china=='你好'}">你好1</s:if> <s:if test="#china=='你好'">你好2</s:if>
注意上面的你好需要加引号,否则没有值;
获取Action 中的属性值或Action 对象的某某属性值
利用
Struts2
标签的
<s:property>
可以直接获取
Action
中的引用类型
user
里面的
name
属性。同样可以通过
user.address.addr
获取
user
中引用类型
address
中的
addr
属性的值
像这种一层一层往下传递的访问方式
,
即所谓的导航
,
也就是一步步的往下调用
调用Action 的对象里面的普通方法:
默认的会把
Action
放到值栈里面
,
而值栈在访问的时候
,
并不需要值栈的名字
当我们调用
<s:property
value="user.getVOMethod()"/>
的时候。它会自动到值栈里面查找Action对象里面有没有user对象,然后它就发现有user。然后它就再找user里面有没有getVOMethod()方法,然后它发现有,于是调用getVOMethod()。实际上调用User中的getVOMethod()方法的过程与获取表单中的姓名密码的方式都是相同的,
都是到值栈里面查找
,找是否存在user对象,如果存在,接着查找user中是否存在某某属性或方法。
调用Action 中的静态方法:
同样我们也可以在 JSP 页面中写一个 OGNL 表达式调用 Action 中的静态方法 , 调用 Action 中的静态方法时 , 与调用 user 对象的 getVOMethod() 方法的过程 , 是截然不同的。此时 value 的写法是固定的 , 以 @ 开头 , 后面跟上具体的包名 , 然后 @ 加上静态方法 ,比如 <s:property value="@com.jadyer.action.LoginAction@getStatic()"/> 。 另外 user 对象是 LoginAction 中的一个属性 , 这个属性会自动的放到值栈里面, 而值栈调用的时候 , 不用加上 @ 或者包名等等 , 所以直接 user.getVOMethod() 就可以了。
调用JDK 类中的静态方法:
可 以使用 <s:property value="@@floor(46.58)"/> 输出 floor() 的执行结果。这就意味着 如果不在@@中指定类 的话, 默认的就表示java.lang.Math类 ,当前大多数情况下,我们都不会省略这个类,都会写全了的,然后在后面加上静态方法。
集合的伪属性:
OGNL
能够引用集合的一些特殊的属性
,
这些属性并不是
JavaBean
模式
,
例如
size()
、
length()
。当表达式引用这些属性时,OGNL会调用相应的方法,这就是伪属性
比如获取List的大小:
<s:property
value="testList.size"/>
List的伪属性:
size、isEmpty、iterator
Set的伪属性:
size、isEmpty、iterator
Map的伪属性:
size、isEmpty、keys、values
Iterator的伪属性:
next、hasNext
Enumeration伪属性:
next、hasNext、nextElement、hasMoreElements
说明:
1 、获取集合中元素的实质就是调用它的toString() 方法;
2 、当OGNL 取不到值的时候,它是不会报错的,而是什么都不显示出来;
3 、<s:property value="[0]"/> 返回的是ValueStack 中从上至下的所有的Object ,<s:property value="[1]"/> 返回的是ValueStack 中从上至下的第二个Object ;
4 、<s:property value="[0].username"/> 返回的是成员变量username 的值。假设ValueStack 中存在两个Action 的话,如果第一个Action 如果没有username 变量,那么它会继续找第二个Action 。那么在什么情况下ValueStack 中会存在两个Action 呢?答案是在struts.xml 中配置的是从一个Action 通过<result type="chain"> 跳转到另一个Action ;
5 、<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
在Struts2.1.6 、Struts2.2 中必须设置struts.ognl.allowStaticMethodAccess 为true 之后才允许使用OGNL 访问静态方法。而在Struts2.0.11 则无需设置,即可直接访问;
通过下面的Demo发现2.2版本中如果不在Struts.xml中配置< constant name = "struts.ognl.allowStaticMethodAccess" value = "true" /> 会出现普通类中的静态属性和方法可以访问,而Action中的静态属性和方法以及jdk中的静态属性方法都无法访问。
Demo :
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>OGNLDemo</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
struts.xml :
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <constant name="struts.ognl.allowStaticMethodAccess" value="true"/> <package name="ognl" extends="struts-default"> <action name="login" class="com.iflytek.action.LoginAction"> <result name="input">/login.jsp</result> <result name="success">/loginSuc.jsp?netname=xdwang</result> <!-- <result name="success" type="redirect">/loginSuc.jsp?netname=xdwang</result> <result name="success" type="redirect">/loginSuc.jsp?netname=${user.username}</result> --> </action> </package> </struts>
Address.java:
package com.iflytek.entity; /** * @author xdwang * * @ceate 2012-6-27 上午12:29:38 * * @description Address实体 * */ public class Address { public static final String TIPS = "xdwang"; private String addr; public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } }
Student.java:
package com.iflytek.entity; /** * @author xdwang * * @ceate 2012-6-27 上午12:31:07 * * @description Student实体 * */ public class Student { private String username; private int grade; public Student() { } public Student(String username, int grade) { this.username = username; this.grade = grade; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } @Override public String toString() { // 如果不重写它的toString()方法的话,默认调用toString()将输出【类型+@+内存地址的哈希值】 return "{学生姓名:" + username + ",成绩:" + grade + "}"; } }
User.java:
package com.iflytek.entity; /** * * @author xdwang * * @ceate 2012-6-27 上午12:29:11 * * @description User实体 * */ public class User { private String username; private String password; private Address address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String getVOMethod() { return "这是User类中的一个普通方法"; } }
LoginAction.java:
package com.iflytek.action; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.struts2.interceptor.RequestAware; import org.apache.struts2.interceptor.SessionAware; import com.iflytek.entity.Student; import com.iflytek.entity.User; import com.opensymphony.xwork2.ActionSupport; /** * @author xdwang * * @ceate 2012-6-27 上午12:33:18 * * @description 登陆Action * */ @SuppressWarnings("serial") public class LoginAction extends ActionSupport implements RequestAware, SessionAware { private User user; private List<String> testList = new ArrayList<String>(); private Set<String> testSet = new HashSet<String>(); private Map<String, String> testMap = new HashMap<String, String>(); private List<Student> stus = new ArrayList<Student>(); private Map<String, String> request; private Map<String, String> session; public void setRequest(Map request) { this.request = request; } public void setSession(Map session) { this.session = session; } public static String getStatic() { return "这是LoginAction中的一个静态方法"; } public String getCommon() { return "这是LoginAction中的一个普通方法"; } @Override public String execute() throws Exception { if (user.getUsername().trim().equalsIgnoreCase("xdwang") && user.getPassword().equals("1111")) { testList.add("list11"); testList.add("list22"); testList.add("list33"); testList.add("list44"); testList.add("list55"); testSet.add("set11"); testSet.add("set22"); testSet.add("set33"); testSet.add("set22"); testSet.add("set11"); testMap.put("m11", "map11"); testMap.put("m22", "map22"); testMap.put("m33", "map33"); testMap.put("m44", "map44"); testMap.put("m55", "map55"); stus.add(new Student("张三", 88)); stus.add(new Student("李四", 77)); stus.add(new Student("王五", 66)); stus.add(new Student("马六", 55)); request.put("req", "这是通过OGNL中的#号获取的request属性范围的值"); session.put("ses", "这是通过OGNL中的#号获取的session属性范围的值"); request.put("BB", "这是通过OGNL中的#号获取的request属性范围的BB"); session.put("BB", "这是通过OGNL中的#号获取的session属性范围的BB"); return SUCCESS; } else { return INPUT; } } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public List<String> getTestList() { return testList; } public void setTestList(List<String> testList) { this.testList = testList; } public Set<String> getTestSet() { return testSet; } public void setTestSet(Set<String> testSet) { this.testSet = testSet; } public Map<String, String> getTestMap() { return testMap; } public void setTestMap(Map<String, String> testMap) { this.testMap = testMap; } public List<Student> getStus() { return stus; } public void setStus(List<Student> stus) { this.stus = stus; } }
login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <title>OGNL Demo</title> </head> <body> <h1>这是测试OGNL使用的登录页面</h1> <h3> <font color="red">提示:</font>程序设定的用户名和密码各为<font color="blue"><strong>xdwang</strong></font>和<font color="blue"><strong>1111</strong></font> </h3> <h3> <font color="red">注意:</font>用户名和密码不正确时将停留在页面不动 </h3> <form action="<%=request.getContextPath()%>/login.action" method="POST"> <%--这里user.username匹配的是LoginAction中的引用类型user里面的username属性--%> <%--查看标签库说明的话,就知道name中指定的是对象。这里它不是字符串,而是OGNL表达式--%> 姓名:<input type="text" name="user.username"><br> 密码:<input type="text" name="user.password"><br> 地址:<input type="text" name="user.address.addr"><br> <input type="submit" value="测试OGNL的输出"> </form> </body> </html>
loginSuc.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"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <title>OGNL Demo</title> </head> <body> <h1>这是使用OGNL输出的结果页面</h1> <table border="9"> <tr> <td align="right">获取姓名属性:</td> <td align="left"><s:property value="user.username" /></td> <%-- 另外还有两种写法也是可以正常输出值栈中对象的普通属性的 --%> <%-- <s:property value="user['username']"/> --%> <%-- <s:property value="user[/"username/"]"/> --%> <%-- 但是如果写成下面这种形式的话,就什么都不会输出了 --%> <%-- <s:property value="user[username]"/> --%> </tr> <tr> <td align="right">获取地址属性:</td> <td align="left"><s:property value="user.address.addr" /></td> </tr> <tr> <td align="right">调用值栈中的对象的普通方法:</td> <td align="left"><s:property value="user.getVOMethod()" /></td> </tr> <tr> <td align="right">调用值栈中Action的普通方法:</td> <td align="left"><s:property value="getCommon()" /></td> </tr> </table> <hr /> <table border="9"> <tr> <td align="right">获取普通类的静态属性:</td> <td align="left"><s:property value="@com.iflytek.entity.Address@TIPS" /></td> </tr> <tr> <td align="right">访问普通类的构造方法:</td> <td align="left"><s:property value="new com.iflytek.entity.Student('xdwang',23).username" /></td> </tr> <tr> <td align="right">调用Action中的静态方法:</td> <td align="left"><s:property value="@com.iflytek.action.LoginAction@getStatic()" /></td> </tr> <tr> <td align="right">调用JDK中的类的静态方法:</td> <td align="left"><s:property value="@java.util.Calendar@getInstance().time" /></td> </tr> <tr> <td align="right">调用JDK中的类的静态方法:</td> <td align="left"><s:property value="@java.lang.Math@floor(46.58)" /></td> </tr> <tr> <td align="right">调用JDK中的类的静态方法:</td> <td align="left"><s:property value="@@floor(46.58)" /></td> </tr> </table> <hr /> <table border="9"> <tr> <td align="right">获取List中的所有元素:</td> <td align="left"><s:property value="testList" /></td> </tr> <tr> <td align="right">获取Set中的所有元素:</td> <td align="left"><s:property value="testSet" /></td> </tr> <tr> <td align="right">获取Map中的所有元素:</td> <td align="left"><s:property value="testMap" /></td> </tr> <tr> <td align="right">获取Map中的某个m22元素:</td> <td align="left"><s:property value="testMap['m22']" /></td> <%-- 另外还有两种写法也是可以正常获取Map中的某个具体元素的 --%> <%-- <s:property value="testMap.m22"/> --%> <%-- <s:property value="testMap[/"m22/"]"/> --%> </tr> <tr> <td align="right">获取Set中的某个元素:</td> <%-- 由于Set中的元素是无顺序的,所以不能使用下标获取数据,所以这里什么也得不到 --%> <td align="left"><s:property value="testSet[2]" /></td> </tr> <tr> <td align="right">获取List中的某个元素:</td> <td align="left"><s:property value="testList[2]" /></td> </tr> </table> <hr /> <table border="9"> <tr> <td align="right">获取List的大小:</td> <td align="left"><s:property value="testList.size" /></td> </tr> <tr> <td align="right">获取Set的大小:</td> <td align="left"><s:property value="testSet.size" /></td> </tr> <tr> <td align="right">获取Map的大小:</td> <td align="left"><s:property value="testMap.size" /></td> </tr> <tr> <td align="right">获取Map中所有的键:</td> <td align="left"><s:property value="testMap.keys" /></td> </tr> <tr> <td align="right">获取Map中所有的值:</td> <td align="left"><s:property value="testMap.values" /></td> </tr> <tr> <td align="right">Lambda计算4的阶乘:</td> <td align="left"><s:property value="#f= :[#this==1?1 : #this*#f(#this-1)],#f(4)" /></td> </tr> </table> <hr /> <table border="9"> <tr> <td align="right">获取List中的所有对象:</td> <td align="left"><s:property value="stus" /></td> </tr> <tr> <td align="right">利用投影获取List中对象的名字:</td> <td align="left"><s:property value="stus.{username}" /></td> </tr> <tr> <td align="right">利用投影获取List中第二个对象的名字:</td> <%-- 使用<s:property value="stus[1].{username}"/>获取到的值为:[李四] --%> <%-- 二者的区别在于:后者比前者多了一个中括号 --%> <td align="left"><s:property value="stus.{username}[1]" /> <s:property value="stus[1].{username}" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的所有对象:</td> <td align="left"><s:property value="stus.{?#this.grade>=60}" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的第一个对象:</td> <td align="left"><s:property value="stus.{^#this.grade>=60}" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的最后一个对象:</td> <td align="left"><s:property value="stus.{$#this.grade>=60}" /></td> </tr> </table> <hr /> <table border="9"> <tr> <td align="right">利用选择获取List中成绩及格的所有对象的名字:</td> <td align="left"><s:property value="stus.{?#this.grade>=60}.{username}" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的第二个对象的名字:</td> <td align="left"><s:property value="stus.{?#this.grade>=60}.{username}[1]" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的第一个对象的名字:</td> <td align="left"><s:property value="stus.{^#this.grade>=60}.{username}" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的最后一个对象的名字:</td> <td align="left"><s:property value="stus.{$#this.grade>=60}.{username}" /></td> </tr> <tr> <td align="right">利用选择获取List中成绩及格的第一个对象然后求大小:</td> <td align="left"><s:property value="stus.{^#this.grade>=60}.{username}.size" /></td> </tr> </table> <hr /> <table border="9"> <tr> <td align="right">利用OGNL中的#号获取attr中的属性:</td> <td align="left"><s:property value="#attr.BB" /></td> </tr> <tr> <td align="right">利用OGNL中的#号获取request范围中的属性:</td> <td align="left"><s:property value="#request.req" /></td> </tr> <tr> <td align="right">利用OGNL中的#号获取session范围中的属性:</td> <td align="left"><s:property value="#session.ses" /></td> </tr> <tr> <td align="right">利用OGNL中的#号获取Paraments对象的属性:</td> <td align="left"><s:property value="#parameters.netname" /></td> </tr> <tr> <td align="right">使用<%=request.getParameter("")%>或者${param.name}获取链接参数值:</td> <td align="left">${param.netname} <%=request.getParameter("netname")%> </td> </tr> <tr> <td align="right">查看值栈中的信息:</td> <td align="left"><s:debug /></td> </tr> </table> </body> </html>
发表评论
-
Struts2标签与JSTL标签混用
2012-07-16 00:07 2996项目中遇到JSTL标签(需要standard.jar和jstl ... -
NoClassDefFoundError: org/apache/commons/io/FileUtils
2012-06-27 00:58 4733在做Struts Demo中出现: Exception ... -
Struts2.2 Tags
2012-06-28 00:48 1851Struts2 标签,这玩意没什么可说的,直接把以前做的 ... -
Struts2.2 Type Conversion
2012-06-26 23:51 2138Struts2 的转换器: ... -
Struts2.2 Localization
2012-06-25 23:55 1720今天来说说Struts2 ... -
Struts2.2 Validation
2012-06-11 00:59 2826数据验证的方式: ... -
Struts2.2 Results Types
2012-06-10 01:11 1696视图返回类型详细的信息可以查看 struts2-c ... -
Struts2.2 Action
2012-06-09 00:13 1835在说 Struts2 中的 Actio ... -
Struts2.2 Interceptors
2012-06-08 01:52 1628AOP 中的 aspect ... -
Struts2.2 Configuration
2012-06-07 23:39 2007在前面的 Struts2.2 CURD Dem ... -
Struts2.2入门By CRUD
2012-06-06 21:49 2369SSH中Struts可谓是比较 ...
相关推荐
Struts2.2.3.1是Apache软件基金会下的一个开源框架,主要用于构建基于Java的Web应用程序。这个框架是MVC(模型-视图-控制器)设计模式的实现,极大地简化了开发流程,并且提供了丰富的功能来处理HTTP请求、表单提交...
Struts2.2 必须的 JAR 包是开发基于Apache Struts 2.2框架的应用程序所需的核心库集合。Struts 2是一个流行的Java开源MVC(模型-视图-控制器)框架,用于构建企业级Web应用程序。它简化了开发流程,提供了一种结构化...
Struts2.2到Struts2.3的升级是一个重要的更新过程,涉及到多个方面的改动和优化,包括性能提升、安全增强以及新特性的引入。在升级过程中,我们需要关注以下几个关键知识点: 1. **依赖包的更新**:Struts2.3.32...
Struts2.2 JAR包是Java开发中的一个重要组件,它是Apache Struts框架的一个特定版本。Struts2是一个开源的MVC(Model-View-Controller)框架,用于构建基于Java的Web应用程序。这个框架旨在提供一种更高效、更灵活的...
Struts2.2是Java Web开发中常用的MVC框架,其在处理用户请求时具有显著的优势。本笔记主要探讨了Struts2.2的核心概念,包括Action、拦截器、过滤器、国际化以及struts.xml配置文件的解析,尤其是类型转换的细节。 ...
对于Struts2.2.3.1版本的API,我们可以通过以下几大方面来探讨其核心概念和功能: 1. **Action类**:在Struts2中,Action类是业务逻辑处理的核心,它继承自com.opensymphony.xwork2.ActionSupport类。开发者需要在...
Struts2.2.4.1 是一个流行的Java Web应用程序框架,它基于Model-View-Controller(MVC)设计模式,用于构建动态、数据驱动的Web应用。此完整资源包包含了许多必要的组件和文档,帮助开发者高效地开发企业级应用。 ...
Struts2.2和SSH是Java Web开发中的两个重要框架,它们在构建高效、可维护的Web应用程序中扮演着核心角色。Struts2是一个强大的MVC(Model-View-Controller)框架,而SSH则通常指的是Struts2、Spring和Hibernate的...
通过阅读Struts2.2.1.1.chm帮助文档,开发者可以深入了解这些特性的具体使用方法,包括Action配置、拦截器编写、结果类型定义、OGNL表达式运用等。此外,文档还包含详细的API参考,对每一个类和接口的功能、方法进行...
Struts 2.2.3.1 是一个流行的开源MVC框架,用于构建企业级Java Web应用程序。这个压缩包“struts-2.2.3.1-lib.zip”包含了Struts 2框架的库文件,这些文件对于理解和使用Struts 2框架至关重要。下面将详细解释其中...
struts2.2.jar(一共7个基本包) commons-fileupload-1.2.1.jar commons-io-1.3.2.jar freemarker-2.3.8.jar javassist-3.7.ga.jar ognl-3.0.jar struts2-core-2.2.1.1.jar xwork-core-2.2.1.1.jar
Struts2.2.3.1 API文档是一个重要的资源,对于深入理解和开发基于Struts2框架的应用程序至关重要。Struts2是一个流行的Java开源MVC框架,用于构建企业级Web应用程序。2.2.3.1是该框架的一个版本,包含了众多的改进和...
Struts2.2.1.1 是一个经典的 Struts2 框架版本,它在Web开发领域中被广泛使用,特别是在Java企业级应用中。Struts2 是一个基于MVC(Model-View-Controller)设计模式的开源框架,旨在简化Java Web应用程序的开发过程...
这个"struts2.2.1.1帮助文档——英文"是开发者的重要参考资料,它提供了关于Struts2框架核心组件、配置、拦截器、插件以及API的详细信息。以下是基于该文档和Struts2.2.1.1版本的一些关键知识点: 1. **MVC设计模式...
Struts2.2.1.1的Javadoc文档是一个极其重要的资源,对于任何正在或计划使用这个版本的Struts框架的开发者来说,都是不可或缺的工具。Javadoc是一种标准的Java文档注解方式,它能够自动生成关于代码的详细文档,包括...
Struts2.2.1.1是Apache软件基金会下的一个流行的Java Web开发框架,用于构建MVC(模型-视图-控制器)架构的应用程序。这个框架极大地简化了Java Web应用程序的开发过程,提供了丰富的功能和良好的可扩展性。在...
Struts2.2.3.1是Apache Struts框架的一个版本,它是一个开源的MVC(Model-View-Controller)框架,广泛应用于Java Web开发中。这个帮助文档提供了该版本Struts框架的详细指南和API参考,对于开发者来说是极其宝贵的...
总的来说,"struts2.2所需要的全部jar包"包含了运行Struts2框架所需的各种核心组件和库,这些库为开发人员提供了强大的工具,使得构建功能丰富的、可扩展的Java web应用变得更加简单。通过熟练掌握Struts2的这些核心...
- **OGNL(Object-Graph Navigation Language)**: Struts 2使用OGNL作为表达式语言,用于访问和操作对象属性,包括在视图层展示数据和在控制器层传递参数。 - **配置文件**: XML配置文件(struts.xml)用于定义...
Struts2.2.x版本是该框架的一个重要迭代,引入了许多增强特性和性能优化。在这个"struts2.2.x 最小jar包"中,我们聚焦于必要的库文件,以实现最小化部署,同时确保兼容性和稳定性。 首先,Struts2的核心组件包括...