struts2 之ognl表达式与值栈(03)
来源:互联网 发布:石家庄手机数据恢复 编辑:程序博客网 时间:2024/05/16 09:05
ognl:
概述
是一种功能强大的表达式语言
struts2把它作为了默认的表达式语言(导入jar包)
作用:
(理解)可以调用对象的方法
可以访问类的静态属性
可以访问类的静态方法
★获取值栈中的数据
例如
调用对象的方法:
<s:property value="'hello'.length()"/><br>
访问类的静态属性:
<!-- @全限定名@属性名称 --><s:property value="@java.lang.Math@PI"/><br>
访问类的静态方法:
<!-- @全限定名@方法名称() 前提:允许ognl访问类的静态方法--><s:property value="@java.lang.Math@random()"/>
获取值栈的数据
这个在后面讲
值栈:
ValueStack:接口 我们使用的是他的实现类:OgnlValueStack
ValueStack实际上就是一个容器。它由Struts框架创建,当前端页面如jsp发送一个请求时,
Struts的默认拦截器会将请求中的数据进行封装,并入ValueStack的栈顶
我把他称之为struts的临时数据中转站.当请求来的时候,struts框架会为每一次请求创建一个valuestack,
把请求中的数据(请求参数,域中的数据)获取,放入值栈.我们若向获取请求的参数可以找request拿,也可以找ValueStack拿;
我们若向往域中放入数据,可以先找到相应的域对象,然后操作;也可以通过值栈操作域中的数据.
当响应生成的时候,值栈就销毁了.
值栈的组成部分:
主要有两个东西:
root:本身是一个list
context:本身是一个map key:string value:Object
主要存放的是:
ActionContext和ValueStack的关系
我们可以把ActionContext看成是一个工具类
请求来的时候,struts会在核心过滤器中为每一次请求创建一个ActionContext,也会创建一个ValueStack
下面是核心过滤器的doFilter的代码
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { prepare.setEncodingAndLocale(request, response);//设置编码格式,防止乱码 prepare.createActionContext(request, response);//创建ActionContext把request都传入当参数 prepare.assignDispatcherToThread(); if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) { chain.doFilter(request, response);//放行不拦截的资源 } else { request = prepare.wrapRequest(request); ActionMapping mapping = prepare.findActionMapping(request, response, true); if (mapping == null) { boolean handled = execute.executeStaticResourceRequest(request, response); if (!handled) { chain.doFilter(request, response); } } else { execute.executeAction(request, response, mapping); } } } finally { prepare.cleanupRequest(request); } }
我们可以继续看一下createActionContext()方法
public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) { ActionContext ctx;//先声明 Integer counter = 1; Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER); if (oldCounter != null) { counter = oldCounter + 1; } ActionContext oldContext = ActionContext.getContext(); if (oldContext != null) { //分布式里用到的 // detected existing context, so we are probably in a forward ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap())); } else { //创建值栈 ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack(); //dispatcher.createContextMap()方法是把所有的数据都放入,把request的参数,已经request获取域中数据都放入context中,request对象,response对象 //然后在把这个Context放入stack对象中 stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext)); 把这个这个stack对象通过context的构造器,传入,再创建对象 ctx = new ActionContext(stack.getContext()); } request.setAttribute(CLEANUP_RECURSION_COUNTER, counter); //下面这句话是绑定当前线程(ThreadLocal中) ActionContext.setContext(ctx); return ctx; }
将请求的参数和域中的数据放入ValueStack中.然后将ValueStack放入ActionContext中.
ActionContext会绑定到当前线程.方便我们在自己的action中获取到所有的数据.
这个是我做个了简单的流程图
获取值栈:
获取值栈:ActionContext.getContext().getValueStack();
往值栈中存数据:
方式一:通过 push对象 set集合
★往root中放数据:
方式1:值栈的api
push(Object obj)
set(String key,Object value):底层创建了一个hashmap,将key/value作为map的键值对,然后将map放入root中
//获取值栈 ValueStack vs = ActionContext.getContext().getValueStack(); //操作 User user = new User(); user.setAge(18); user.setUsername("三三"); vs.push(user); //在user上面 底层是一个map集合,然后把map放入root中 vs.set("name", "思思");
方式2:通过Action的成员属性
(理解)往context中放数据:
我们看源码的时候,看到struts将值栈的context放入到了ActionContext中,我们只需要操作ActionContext就可以值栈的Context了
put(key,value) 相当于往request域中放入数据
getSession().put(key,value) 放入Session中
getApplication.put(key,value) 放入Application
例如:
private String hobby; public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } @Override public String execute() throws Exception { hobby="抽烟喝酒烫头"; return super.execute(); }
在jsp获取值栈
★el也可以获取值栈中所有的数据
之前使用el 例如:${username}
依次从pageContext,request,session,application中查找数据,找到之后立即返回,找不到返回””
底层调用的是: pageContext.findAttribute(“username”)
先去找pageContext域中的数据
若找到立即返回
若找不到继续往下一个域中找
不在struts中ei标签的查找顺序:
找request域中
若找到立即返回
若找不到继续往下一个域中找
找session域中
若找到立即返回
若找不到继续往下一个域中找
找application域中
若找到立即返回
若找不到返回null
在struts中el 查找顺序:
pageContext – request – root – context(大map) – session – application
在核心过滤器中增强了request.getAttribute(..) 找的范围:request – root – context(大map)
底层调用了值栈的findValue方法:先查root,root中没有的话继续找context(大map)
总结:
从值栈中取数据:
获取root中的数据,ognl表达式直接写属性名称即可
<s:property value="ognl表达式"/>
扩展:先找root中的数据,找不到继续查找context(大map)中的数据,找不到返回””
获取context中数据,ognl表达式需要加”#”
<s:property value="#ognl表达式"/>
- struts2 之ognl表达式与值栈(03)
- Struts2之 OGNL表达式和值栈
- Struts2使用之值栈与OGNL
- Struts2与OGNL表达式
- Struts2与OGNL表达式
- struts2与OGNL表达式
- struts2之ognl表达式
- struts2之OGNL表达式
- struts2之ognl表达式
- struts2之OGNL表达式
- Struts2之OGNL表达式与值栈对象及常用标签的使用
- 道听途说Struts2之18:OGNL表达式访问值栈
- Struts2-03-OGNL表达式
- Struts2-OGNL与值栈
- ognl表达式与struts2标签
- Struts2-Ognl表达式与ValueStack
- struts2总结之 OGNL表达式
- Struts2之OGNL表达式语言
- 全局变量的替换方式
- Thinkphp5学习(35)图像处理
- Xcode无法启动虚拟机项目DTAssetProviderService... DTXConnection...
- 漫画告诉你什么是DDoS攻击?
- 内部类调用局部参数为何用final关键字
- struts2 之ognl表达式与值栈(03)
- SpringMVC札集(01)——SpringMVC入门完整详细示例(上)
- 【宏观】长期中的通货膨胀与货币
- Activity的4种启动模式
- 输入框延时调接口(防止不停调用)
- js怎么让浏览器自动全屏显示
- viewpager布局复用中FragmentPagerAdapter的坑,源码分析,控件id的一些思考
- AtomicInteger源码分析
- promise的用法