以下是个人学习笔记
ValueStack (特征先进后出)
Struts2将XWork对Ognl的扩展这一套机制封装起来,这个对象叫ValueStack。ValueStack实际上就是一个容器。它由Struts框架创建,当前端页面如jsp发送一个请求时,Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶。
OGNL表达式:全称Object-Graph Navigation Language(对象导航图语言)Struts 2默认的表达式语言是OGNL,原因是它相对其它表达式语言具有下面几大优势:
支持对象方法调用,如xxx.doSomeSpecial();
支持类静态的方法调用和值访问,支持赋值操作和表达式串联,
访问OGNL上下文(OGNL context)和ActionContext;
操作valuestack
- 获取值栈
//获取值栈 ValueStack vs=ActionContext.getContext().getValueStack(); //获取值栈中的name System.out.println(vs.findString("name")); |
从栈顶开始查找,找到符合条件的‘name’输出
测试结果:
- 在栈顶添加一个user后再来执行代码查看变化
User类的属性
private String name; |
Action的execute方法
public String execute() { if("abc".equals(name)&&"123456".equals(pwd)) { //将action的name放入session ActionContext.getContext().getSession().put("name", name); //获取值栈 ValueStack vs=ActionContext.getContext().getValueStack(); //创建一个user并且set name User user=new User(); user.setName("李四"); //将user放入栈顶 vs.push(user); //获取值栈中的name System.out.println(vs.findString("name"));
return "success"; } return "error"; } |
使用ognl时需要在jsp页面添加以下代码
<%@taglib prefix="s" uri="/struts-tags" %> |
在login.Jsp中使用ognl表达式获取输入的name
<h1>登陆成功</h1><br/> 用户名:<a> <s:property value="name"/> </a> <a>--- action中的name </a> |
执行结果
这里我输入的是‘abc’然后获取name变为了放入栈顶的user的name,原因很简单应为我们添加的user此时是在栈顶action在user的下面,这时候从栈顶查找符合条件的name找到了就不会往下走,所以输出的是user的name
在login.jsp中添加以下
用户名:<a> <s:property value="#session.name"/> </a> <a>--- ActionCentexe中的name </a> |
添加以后的结果
这里结果正确是我们输入的结果。由此可见直接写name会从栈顶查找符合条件的name 而在文章的第一步没有放入user到值栈中时,位于栈顶的时action。
在添加了#的时候像上面那样,session是在actionContext里的。
结论:在不添加数据到值栈的情况下,不添加#时是查找action里的属性,在添加了#的情况下是查找actionContext里的属性.
关于ognl表达式在jsp页面中的问题:
在核心过滤器中的url-pattern中设置如下
<url-pattern>*.action</url-pattern> |
然后在登陆后的login.jsp页面用${}取出数据的情况下访问jsp页面
<a>用户名:${user } </a><br> |
结果
直接访问jsp页面没有name的值但是仍然能正常访问
但是使用ongl之后
用户名:<a> <s:property value="#session.name"/> |
直接访问jsp页面会有一个http500的错误
但是通过action转发却能正常访问。
显然在项目中通过action转发的方式更加安全,而且不会暴露项目文件的路径
以上全部是个人观点有错误欢迎指正