EL表达式获取值栈数据的源码分析



  Struts2是基于MVC的轻量级的web应用框架。所谓框架:就是能完成一定功能的半成品软件。在没有框架的时候,所有的工作都要乖乖的从零做起;有了框架,它为我们提供了一定的功能,就可以在框架的基础上做起,大大提高开发的效率和质量。

  将数据存入值栈中,在jsp页面上使用EL表达式也能获取值栈中的数据,是什么原因呢?当然要从源码看起。

  struts2框架的启动是从核心过滤器开始的。struts2的核心过滤器叫做StrutsPrepareAndExecuteFilter,并且肯定已经配置在web.xml文件中,打开web.xml文件,按住Ctrl键点击查看源码。如果没有关联源码,找到源码路径,关联一下。

  在核心过滤器中有个doFilter方法

  struts2核心过滤器doFilter方法

  在此有个小经验:在过滤器中一般最重要的就是doFilter方法。在核心过滤器的doFilter方法中,调用request的包装方法wrapRequest,返回request对象。按住Ctrl键,点击该方法。

  PrepaerOperation类request对象的包装方法

  在该方法中调用Dispather类对request对象的包装方法,返回request对象。按住Ctrl键,点击此方法

  Dispatcher类对request对象的包装

  在Dispatcher类中的request对象的包装类中首先判断request对象是否已经被该类包装,如果已经被包装,不需要再次包装,直接返回即可,如果没有被包装,执行下面的if-else语句,在if的判断中,判断其是否是文件上传,如果是创建文件上传的包装类对象,在此我们不讨论这种情况。如果不是文件上传,创建request对象的包装类StrutsReuqestWrapper对象,在参数中传入需要包装的request对象。按住Ctrl键,查看该包装类。

  因为上面的每个方法都返回request对象,那么如果执行到这里,核心过滤器中的request对象就是StrutsReuqestWrapper类的实例对象。

 

  StrutsReuqestWrapper该类中有个getAttribute方法,就是这个方法判断从Servlet容器中取值还是从值栈中取值

  

  由于getAttribute方法太长,截图不方便,这只是getAttribute方法的一部分,这部分判断如果成立就从Servlet容器中取值。首先是健壮性的判断,传入的参数key不能为空。disableRequestAttributeValueStackLookup是个boolean值,意思是不能从值栈中查询属性值,或者传入的key是以javax.servlet开头的。javax.servlet开头表示使用Servlet容器对request对象的包装类 javax.servlet.ServletRequestWrapper。

  

  这部分判断的是从值栈中取值。先获取ActionContext对象,再调用父类的getAttribute方法,其父类就是Servlet容器对request的包装类javax.servlet.ServletRequestWrapper 。如果可以获得ActionContext对象,并且父类的getAttribute方法取值为空,那么if判断成立,紧接着进行第二个if判断,传入的参数key中不包含"#"。如果包含"#"是从值栈的map结构中取值,可能造成死循环。第二个if如果也成立,调用getValueStack方法,获取值栈对象,再调用值栈对象的findValue方法从值栈中获取对应的值。

  到此使用EL表达式可以获取值栈中值的原因分析完了。总结就是获取request的包装类StrutsReuqestWrapper,获得该类的实例对象。类中有getAttribute方法,在该方法中判断是从Servlet容器中取值,还是从值栈中取值。先调用父类javax.servlet.ServletRequestWrapper的getAttribute方法,如果获取不到值,就获取值栈对象,调用值栈对象的findValue方法取值。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值