struts2 request内幕 为什么在struts2用EL表达式可以取值
不知道大家有没有想过这样一个问题:为什么在action中的实例变量,没有使用request.setAttribute()方法将值添加到request范围内,却能在jsp中用EL表达式取出?
众所周知,EL表达式只能取出pageContext,request,session,application属性范围的值。然而,在struts2中能突破这一个限制,成功的取出action中的实例变量值。
请看例子:
这是一个action
package com.wuyou.action; import com.opensymphony.xwork2.ActionSupport;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller; @Controller
@Scope(value = "prototype")
public class TestAction extends ActionSupport { private Integer id = 123;
private String name = "无忧之路"; public String execute() {
return "success";
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
对应的struts配置文件:
<package name="default" extends="struts-default" namespace="/">
<action name="test" class="testAction">
<result>/success.jsp</result>
</action>
</package>
对应的success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title></title>
</head>
<body> ${id} </body>
</html>
页面输出:123
其实,在struts2中使用的request并非为tomcat提供的,而是经过了struts2所包装过的org.apache.struts2.dispatcher.StrutsRequestWrapper对象。
这个类做了些什么事情呢?
原来,我们在调用EL表达式的时候,或者request.getAttribute(String key)方法的时候,struts2会先在原来的request中调用request.getAttribute()方法获取该值,如果查找不到,则继续往OgnlValueStack查找,由于action对象在ognl值栈,返回action里名为"id"的实例变量值,即可显示在页面上。
我们可以尝试在jsp中输出request的类名:
<%=request.getClass()%>
也可以在action里面输出:
System.out.println(ServletActionContext.getRequest().getClass());
均输出:class org.apache.struts2.dispatcher.StrutsRequestWrapper
这下真相大白了吧!
附StrutsRequestWrapper类源代码:(点击展开)
public class StrutsRequestWrapper extends HttpServletRequestWrapper {
/**
* The constructor
* @param req The request
*/
public StrutsRequestWrapper(HttpServletRequest req) {
super(req);
}
/**
* Gets the object, looking in the value stack if not found
*
* @param s The attribute key
*/
public Object getAttribute(String s) {
if (s != null && s.startsWith("javax.servlet")) {
// don't bother with the standard javax.servlet attributes, we can short-circuit this
// see WW-953 and the forums post linked in that issue for more info
return super.getAttribute(s);
}
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);
if (ctx != null) {
if (attribute == null) {
boolean alreadyIn = false;
Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute");
if (b != null) {
alreadyIn = b.booleanValue();
}
// note: we don't let # come through or else a request for
// #attr.foo or #request.foo could cause an endless loop
if (!alreadyIn && s.indexOf("#") == -1) {
try {
// If not found, then try the ValueStack
ctx.put("__requestWrapper.getAttribute", Boolean.TRUE);
ValueStack stack = ctx.getValueStack();
if (stack != null) {
attribute = stack.findValue(s);
}
} finally {
ctx.put("__requestWrapper.getAttribute", Boolean.FALSE);
}
}
}
}
return attribute;
}
}
struts2 request内幕 为什么在struts2用EL表达式可以取值的更多相关文章
- java实体类的属性名首字母不能大写,不然el表达式无法取值
摘要:Java命名规范中,实体类属性名以小写字母开头,但并没有说不能以大写字母开头,然而事实告诉我,大写真不行 https://www.cnblogs.com/jnhs/p/10025757.html
- struts2的@Result annotation 如何添加params,并且在页面取值
http://www.bubuko.com/infodetail-2492575.html .............................................. 标签:lai ...
- Struts2技术内幕----深入解析Struts2架构与设计(一)
Struts2的核心入口程序,从功能上来说必须能够处理Http请求,这是表示层框架的基本要求.为了达到这一目的,Struts2毫无例外地遵循了Servlet标准,通过实现标准的Filter接口来进行H ...
- EL表达式详解(常用表达式以及取值)
EL表达式 学习总结 一. El表达式概念 二. El中的表达式 1. 算术表达式 2. 比较表达式 3. 逻辑表达式 4. 三元表达式 5. 判空表达式 三.EL 从四个作用域中取值 1. 概念 2 ...
- EL表达式获取属性值的原理
EL表达式获取对象属性的原理是这样的:以表达式${user.name}为例EL表达式会根据name去User类里寻找这个name的get方法,此时会自动把name首字母大写并加上get前缀,一旦找到与 ...
- 如何将数据库中的值经过servlet传入到jsp页面,并且用EL表达式显示出值
方法一:通过id查询某一数据库表中具体的行,将值封装在相应的对象中,如下面的对象Notice servlet中 String noticeId=request.getParameter("n ...
- jsp使用EL表达式回传boolean值出错的问题
在最近做的一个项目中使用session回传的属性中有一个为boolean,报出错. 属性名字为"isAdmit",布尔类型.后来我上网查了一下,是因为我使用了Myeclipse的自 ...
- HTML5中的时间类型,另外EL表达式的时间值来读取时间,并且还可以更改时间
HTML5规范里只规定date新型input输入类型,并没有规定日历弹出框的实现和样式.所以,各浏览器根据自己的设计实现日历.目前只有谷歌浏览器完全实现日历功能.相信这种局面很快就会结束,所有的浏览器 ...
- 简述jsp之EL表达式和jstl及其使用
Jsp的指令之include指令include指令:代表的是页面的包含. 作用:可以把一些jsp的页面包含在一起,对外展示. 页面的布局,现在已经不用了,现在都用css+div进行布局.include ...
随机推荐
- iOS - 基于蓝牙数据交换的环境监测(温度、湿度、光照、粉尘、噪声)
一.蓝牙外设的数据接收 二.App端显示获取数据
- Swift泛型和泛型函数
泛型(generic)可以使我们在程序代码中定义一些可变的部分,在运行的时候指定.使用泛型可以最大限度地重用代码.保护类型的安全以及提高性能.在Swift集合类中,已经采用了泛型.一.一个问题的思考怎 ...
- 获取bundle目录下的所有图片文件名
今天在写代码时候,偶然发现自己忘记了一些oc的基础知识(这里指的是获取bundle目录下的所有图片),感到很不爽.在百度了几次,发现自己的领悟能力实在不行,感觉萌萌的::>_<:: 好了, ...
- Object-C基础学习笔记(1)
1.苹果公司将Cocoa.Carbon.QuickTime和OpenGL等技术作为框架集:提供Cocoa组成部分有: (1)Foundation框架(有很多有用的,面向数据的低级类和数据结构): (2 ...
- javascript笔记——js面试问题
1:javascript中的变量提升(先使用再声明,js中的函数也存在函数提升) 2:js中的事件捕获和事件冒泡(是两个相反的过程) 3:js中的动画队列(比如animate动画没有在点击的时候阻止正 ...
- 一些常用sqlite语句
1,如果表不存在就新建一个 CComBSTR bstrCreatBat(L”CREATE TABLE IF NOT EXISTS tb_Name (\ rowIdIndex INTEGER PRIM ...
- linux之cat命令
1. cat 接普通文件名,会把文件内容打印到屏幕:2. cat > file,这个可以向文件“file”写入内容,最后按 Ctrl + D 结束输入,会将你输入的数据保存到文件. cat主要有 ...
- SpecFlow教程--快速入门
原文http://www.specflow.org/getting-started/ 一.安装 为了能正确安装SpecFlow所需要的东西,你必须安装集成IDE的插件以及设置你的项目使用SpecFlo ...
- thinkphp操作数据库
1.实现or操作: $where=array( 'city'=>array('like',array('%'.$_GET['city'].'%')); 'hangye'=>array('l ...
- 给虚拟机中的CentOS7配置固定ip
在虚拟机中安装完了CentOS7之后,使用了DHCP来获取ip,vmware的网络连接使用了NAT模式.但是在把Linux设置为固定ip地址后,虚拟机里的linux可以ping通全网段的ip地址,但是 ...