偶然中存在着必然,必然中存在着偶然

偶然出现的bug,必然存是由代码的不合理甚至错误的

代码逻辑越长,越复杂,就越容易出现bug

之前项目里几次偶然出现了一个bug,简单的描述就是第一次新增了之后进行一个B操作,之后在新增一次,页面中的一个隐含变量会"记住"这个新增之后的id,因为这个需要连续两次新增且在第一次新增之后进行B操作之后才会出现,所以很长时间里面都是偶然出现.

定位问题的过程就是进行很多次的操作,然后逐个排除.尝试自己的猜测,再次进行代码级的排除.定位这种问题一定要有一定的测试量.就像有一个入口和一个出口的迷宫,答案就是有偶发性bug的路径.

最后发现问题是当时model中的id为null,而在B操作中session中也存了id.

下面一起来看一下,El读取变量的顺序

后台代码

package com.my.innerParam.test;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; /**
 * 测试几个内置变量中在EL读取的顺序
 * @author rocky
 *
 */
@Controller
public class InnerParam
{
    @RequestMapping("/innerParamTest")
    public String innerParamTest(HttpServletRequest request,HttpServletResponse response,Model model)
    {
        HttpSession session = request.getSession();
        session.setAttribute("session", "session223");
        
        ServletContext application = request.getServletContext();
       // application.setInitParameter("appicationParam", "appicationParam");
        //Initialization parameters can not be set after the context has been initialized
        application.setAttribute("appicationAttr", "applicationAttr");
        request.setAttribute("request", "request");
       
        
        model.addAttribute("model", "model123");
        return "/testParam/testParam1";
    }
    
    //当变量名字相同时判断EL表达式用哪一个
    @RequestMapping("/innerParamTest2")
    public String innerParamTest2(HttpServletRequest request,HttpServletResponse response,Model model)
    {
        HttpSession session = request.getSession();
        session.setAttribute("test", "session223");
        
        ServletContext application = request.getServletContext();
       // application.setInitParameter("appicationParam", "appicationParam");
        //Initialization parameters can not be set after the context has been initialized
        application.setAttribute("test", "applicationAttr");
 
        request.setAttribute("test", "request");
        model.addAttribute("test", "model123");
        return "/testParam/testParam2";
    }
    
    //当model是null的时候
    @RequestMapping("/innerParamTest3")
    public String innerParamTest3(HttpServletRequest request,HttpServletResponse response,Model model)
    {
        HttpSession session = request.getSession();
        session.setAttribute("test", "session223");
        
        ServletContext application = request.getServletContext();
       // application.setInitParameter("appicationParam", "appicationParam");
        //Initialization parameters can not be set after the context has been initialized
        application.setAttribute("test", "applicationAttr");
 
        request.setAttribute("test", "request");
        model.addAttribute("test", null);
        return "/testParam/testParam3";
    }
}

第一种情况,显示

代码

<h3>session : ${session}</h3>
<h3>appicationAttr : '${appicationAttr}'</h3>
<h3>appicationParam : '${appicationParam}'</h3>
<h3>request : '${request}'</h3>
<h3>model : '${model}'</h3> 运行结果

session : session223


appicationAttr : 'applicationAttr'


appicationParam : ''


request : 'request'


model : 'model123'


第二,变量名字相同时

<h3>session : ${test}</h3>
<h3>appicationAttr : '${test}'</h3>
<h3>appicationParam : '${test}'</h3>
<h3>request : '${test}'</h3>
<h3>model : '${test}'</h3> 运行结果

session : model123


appicationAttr : 'model123'


appicationParam : 'model123'


request : 'model123'


model : 'model123'


第三,当model为null时

<h3>session : ${test}</h3>
<h3>appicationAttr : '${test}'</h3>
<h3>appicationParam : '${test}'</h3>
<h3>request : '${test}'</h3>
<h3>model : '${test}'</h3>
运行结果

session : session223


appicationAttr : 'session223'


appicationParam : 'session223'


request : 'session223'


model : 'session223'


第四,当session也为null时

<h3>session : ${test}</h3>
<h3>appicationAttr : '${test}'</h3>
<h3>appicationParam : '${test}'</h3>
<h3>request : '${test}'</h3>
<h3>model : '${test}'</h3> 运行结果
session : applicationAttr appicationAttr : 'applicationAttr' appicationParam : 'applicationAttr' request : 'applicationAttr' model : 'applicationAttr'

结论:1.model > session >application>requset的,其他的就不测试了,这几个是最长用的.

2.慎重使用session变量,这个范围太大了,如果因为一个模块把变量存在session中实现起来更容易,就这样做了,那么这就很容易为后面埋下bug.

如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。

所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个

请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被

称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。

如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。

整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务

器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。

application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。

与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application

中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,

参考blog:JSP九大内置对象及四个作用域

3.熟悉jsp基础,已经常用的变量.

JSP隐含变量和Spring中Model在EL表达式中的读取顺序的更多相关文章

  1. JS中如何使用EL表达式中的对象

    JS中如何使用EL表达式中的对象 2017年09月25日 15:33:09 lhpnba 阅读数:4859   1.js中使用el表达式要加双引号或单引号:'${list}' 2.js变量获取el表达 ...

  2. jsp中如何判断el表达式中的BigDecimal==0

    比较蠢一点的做法: <c:if test="${not ((someBigDecimal < 0) or (someBigDecimal > 0))}"> ...

  3. IT兄弟连 JavaWeb教程 EL表达式中的内置对象

    EL语言定义了11个隐含对象,它们都是java.util.Map类型,网页制作者可通过它们来便捷地访问Web应用中的特定数据.表1对这11个隐含对象做了说明. 1  EL表达式中的内置对象 这11个隐 ...

  4. EL表达式中引用隐式变量

    除了在jsp中9大隐式变量(在前面文章也叫预定义变量)在转化成为servlet后_jspService中可以看到: public void _jspService(final javax.servle ...

  5. 在jsp中怎么使用Cookie?el表达式中获取cookie的问题

    初学jsp,不清楚cookie的使用方法,希望高手指点一下!   一般来说有两种办法,在JSP中使用Java的嵌入脚本. 例如: 写入Cookie <html> <head>. ...

  6. EL表达式中fn函数 (转载)

    JSTL 使用表达式来简化页面的代码,这对一些标准的方法,例如bean的getter/setter方法,请求参数或者context以及 session中的数据的访问非常方便,但是我们在实际应用中经常需 ...

  7. java、el表达式中保留小数的方法

    Java中: import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; p ...

  8. EL表达式中如何截取字符串

    EL表达式中如何截取字符串 可以截取,用fn函数:<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/ ...

  9. 关于EL表达式中requestScope和param区别

    今天演示EL表达式的时候发现自己jsp的基础实在是薄弱,在这个很简单的问题上迷惑了很久. 首先在看遇到的问题: 在浏览器地址输入,表示传入一个参数test,值为123 http://localhost ...

随机推荐

  1. Java:对象的强、软、弱和虚引用

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

  2. Java核心技术点之集合框架

    1. 概述     Java集合框架由Java类库的一系列接口.抽象类以及具体实现类组成.我们这里所说的集合就是把一组对象组织到一起,然后再根据不同的需求操纵这些数据.集合类型就是容纳这些对象的一个容 ...

  3. JS给文本框赋值后,在页面后台取不到文本框值的解决方法

    转自:http://www.cnblogs.com/qiaohd/archive/2012/03/23/2413660.html (ReadOnly.disabled 都有可能造成取值取不到) 开发一 ...

  4. 背包dp整理

    01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...

  5. 转:用WCAT进行IIS压力测试

    Microsoft的Web容量分析工具(WCAT) 是测试你的客户-服务器网络配置的必备工具.这个工具在你的网络上对多种工作量的场景进行仿真,允许你确定你的网络和服务器的最佳配置.WCAT是专门为 评 ...

  6. 由于 ASP.NET 进程标识对全局程序集缓存没有读权限,因此未能执行请求。错误: 0x80131902

    由于 ASP.NET 进程标识对全局程序集缓存没有读权限,因此未能执行请求.错误: 0x80131902 分类: c#2013-06-17 10:22 89人阅读 评论(0) 收藏 举报 ASP.NE ...

  7. windows命令行下简单使用javac、java、javap详细演示

    最近重新复习了一下java基础,在使用javap的过程中遇到了一些问题,这里便讲讲对于一个类文件如何编译.运行.反编译的.也让自己加深一下印象. 如题,首先我们在桌面,开始->运行->键入 ...

  8. java:利用xpath删除xml中的空节点

    原始xml内容: <data> <a> </a> <b>b1</b> <awb> <awbpre>123</a ...

  9. 大学回顾和C与PHP之路

    我去年毕业,从事PHP学习和开发一年多. background:medical muti-media electric web; 先讲一下我的背景吧,我大学的学校是一个医科学校,然而专业是计算机动漫设 ...

  10. SQLServer(MSSQL)、MySQL、SQLite、Access相互迁移转换工具 DB2DB v1.1

    最近公司有一个项目,需要把原来的系统从 MSSQL 升迁到阿里云RDS(MySQL)上面.为便于测试,所以需要把原来系统的所有数据表以及测试数据转换到 MySQL 上面.在百度上找了很多方法,有通过微 ...