很简单的调用JavaBean的问题:一、俩文件,一个Bean,一个JSP文件。(环境Tomcat4.1和jdk1.4)1.JavaBean代码如下:(文件名为CounterBean.java)
----------------------
package mypack;
public class CounterBean{
private int count=0;
public CounterBean(){} public int getCount(){
return count;
}
public void setCount(int count){
this.count=count;
}
}
-----------------------
2.JSP文件代码如下:(文件名为Counter.jsp)
-----------------------
<%@ page import="mypack.CounterBean" %>
<html>
<head>
<title>
Counter
</title>
</head>
<jsp:useBean id="myBean" scope="session" class="mypack.CounterBean" />
<body>
<jsp:getProperty name="myBean" property="count" />
<br>
<%
out.println(myBean.getCount());
%>
<jsp:setProperty name="myBean" property="count" value="<%=myBean.getCount()+1%>"/>
</body>
</html>
--------------------------------二、问题描述:
URL=http://localhost/文件夹路径/Counter.jsp
我通过浏览器访问以上路径,开始输出结果没问题,每次刷新都能自加一。
但是当我把JSP文件中的scope从scope="session"改成scope="application",保存了,再刷新以后,结果竟然不变了,而且一直停留在
1
0
上了,很奇怪,不仅不自加一,而且竟然俩数字不一样!!当我打开一个新的浏览器访问该地址的时候,结果没问题,每次刷新可以自加一。但是原先的浏览器依然不行。请高手给解释一下,100分送给第一个说明白的人。

解决方案 »

  1.   

    session级的,当你开浏览器,他初始化一个对象,你关了他就消亡了application级服务器不重启就只有一个。而且你需要将页面缓存清除
    response.setHeader("Pragma","No-cache");
    response.setHeader("Cache-Control","no-cache");
    response.setDateHeader("Expires", 0);
      

  2.   

    To hellwindy:
    首先感谢下。不过好像没有解决问题。
    你说的两个的有效范围,我是知道的。
    而且我将你的清除缓存的代码加入jsp中以后,问题依然存在。
    而且为啥后一次访问的结果是1和0,而不是0和0或1和1呢?简单说下问题吧:就是先访问scope为session的jsp没问题;把scope改成application以后,在同一个浏览器中再次访问,就有问题了。
      

  3.   

    session是会话级的,关了浏览器就没了,重新打开浏览器又有的!aplication是与服务器有关,关了服务器就没了!
    session正常就不多说了,而用application不正常,你要改了之后重新部署一下,重新开一个浏览器!
      

  4.   

    To fuyou001:书上说application的信息是在服务器上保留的。既然是跟服务器有关的,为啥只需要重新开浏览器,而不是reboot服务器?
    当然reboot服务器和重开浏览器都是可以解决此问题的了,呵呵。但是你没有说明白为何在当前浏览器出现的这个问题,而且还没有解释0和1不同的问题。顺便顶下贴,别沉了。
      

  5.   

    每次刷新每次 初始化所以肯定每次都没边了CounterBean把这个类放到request.getSession().setAt.....中去,就好了每次取的时候从 request.getSession()中去取
      

  6.   

    每次加1后,再放进request.getSession()中
      

  7.   

    kokobox,你啥意思?
    请把修改后的代码贴出来吧。谢谢。(不过能解释下原来为啥不行么?)
      

  8.   

    他们的的生存期作用域不同,session的变量存放在Session里,application的变量存放在ServletContext里session:会话作用域,当用户首次访问时,产生一个新的会话,以后服务器就可以记住这个会话状态。生命周期:会话超时,或者服务器端强制使会话失效。application:全局作用范围,整个应用程序共享,就是在部署文件中的同一个webApp共享,生命周期为:应用程序启动到停止。page,就是这个bean只在这个页面中有效,比如你换了一个页面或者刷新了一下,这个bean就被重新实例化了     
    session,bean在一个会话中有效   
    application,只要你的web server没有停止,就一直有效
      

  9.   

    谢谢。
    不过,heisetoufa,你说的都是textbook,并没有解释我的问题哦。
      

  10.   

    四个作用域的区别,可以参考我们教程中的讨论:http://www.family168.com/tutorial/jsp/html/jsp-ch-04.html
      

  11.   

    以上已经说的很明白了,我觉得LZ你自己要好好思考下,当appliaction时候,你第一次访问JSP的时候,输出肯定是0了,但是你已经setproperty了,也就是加了1,刷新一次后,自然显示的是1了,然后application中的东西,只有在重起服务器的时候,才。。哎。。
      

  12.   

    现像:打开浏览器1输入URL, 不停刷新,正确.修改为application.
    再刷新几次浏览器,发现只剩下1,0;
    打开浏览器2输入URL,不停刷新,正确(从零开始增加)刷新一次浏览器1,浏览器是前面数字不变,后边的在浏览器2上+1.
    再刷新浏览器1,浏览前面数字变成刷新上的+1.后边的没边.
    不停刷新浏览器1数字不变.
      

  13.   

    导致这种现象的原因是在session和application中都存在有myBean
    <jsp:useBean id="myBean" scope="session" class="mypack.CounterBean" /> 输出的是session中的
    而<% 
    out.println(myBean.getCount()); 
    %> 
    输出的是application中的了
      

  14.   

    application 没有问题,呵呵!我自己都测试了! 可以一直增加下去!package net.java2000.html;public class CounterBean {
      private int count = 0;  public CounterBean() {
      }  public int getCount() {
        return count;
      }  public void setCount(int count) {
        this.count = count;
      }
    }<html>
    <head>
    <title>Counter</title>
    </head>
    <jsp:useBean id="myBean" scope="application" class="net.java2000.html.CounterBean" />
    <body>
    <jsp:getProperty name="myBean" property="count" />
    <br>
    <%
      out.println(myBean.getCount());
    %>
    <jsp:setProperty name="myBean" property="count" value="<%=myBean.getCount()+1%>" />
    </body>
    </html>
      

  15.   

    而且一直相同的! 你重新启动你的 tomcat 吧!呵呵!
      

  16.   

    用<bean:write name="myBean" scope="application">和<bean:write name="myBean" scope="session">可以发现输出结果不同
      

  17.   

    To java2000_net:怎么可能没有问题?AWUSOFT也试过了,而且现象描述的和我得到的结果一样。
      

  18.   

    to:  kingssq 问题是浏览两次访问 的都同一个JSP呀.虽然说有可能是取值范围不一样(一个是session一个是application),但再刷新后应该是一样的啊.刚开始的时候我也是在考虑session与application都存在对像的问题.后来发生了那些现像才感觉说不下去.
      

  19.   

    我觉得遇到这种问题的时候应该重新编译,部署一下程序,如果你是用jbulider那么先clean然后再make重新编译一下
    eclipse也是一样,重新部署到服务器里去
    问题依旧可以选择删除tomcat目录下work目录里的所有内容
      

  20.   

    struts标签,你不会也可以用jstl测试
      

  21.   


    个人认为正解。
    lz 的有误:
    <%@ page import="mypack.CounterBean" %> 
    <html> 
    <head> 
    <title> 
    Counter 
    </title> 
    </head> 
    <jsp:useBean id="myBean" scope="session" class="mypack.CounterBean" /> <body> 
    <jsp:getProperty name="myBean" property="count" /> 
      

  22.   

    说明一下吧,我用的是文本编辑器,没有用其他任何高级的集成IDE。
    这个跟cookie有啥关系??从头到尾没碰cookie一下。
      

  23.   

    想了想,觉得可能有是浏览器缓存的问题。要不为什么有的人运行的时候是正确的呢?
    建议你修改一下internet选项,设置为每次访问此页时检查,再看看是不是还有这样的问题?
      

  24.   

    当楼主 (当然,大家使用的时候都一样,嘿嘿) 使用
    <jsp:useBean id="myBean" scope="session" class="mypack.CounterBean" /> 
    的时候,实际上是进行了和下面相同的工作:
     mypack.CounterBean myBean = null;
    然后呢,servlet就从 session里面找名字为 myBean的对象,如果找到了,皆大欢喜:
      myBean = (mypack.CounterBean) pageContextObj.getAttribute("myBean", pageContext.SESSION_SCOPE); 
    如果没有找到的话,没关系,咱们就"牛"一个,然后把它放到马甲里面去:
      myBean =  new mypack.CounterBean();
      pageContextObj.setAttribute("myBean", myBean, PageContext.SESSION_SCOPE);
      (其实啊,这句话可以这样理解: session.setAttribute("myBean", myBean) )
      然后呢,楼主进行了下列动作,<jsp:getProperty name="myBean" property="count" /> 
    这句话等同与:
        <%=(mypack.CounterBean)(pageContextObj.findAttribute("myBean")).getCount()%>  在这里问题来了,findAttribute("myBean") 是啥玩意?
       (插播:楼主你有100分不?嘿嘿,感觉我好贪财,猥琐。[email protected])
       findAttribute("myBean") 是JspContext(pageContext是JspContext的一个子类)的一个方法(这不废话嘛),
       他的作用是按顺序从  page, request, session ,application 作用域取得有属性名为myBean的所关联的对象。
       就是说,如果之前有page.setAttribute("myBean","1"),session.setAttribute("myBean","2"),那么,findAttribute("myBean")返回的值是1。
       因为我们就有有一句 pageContextObj.setAttribute("myBean", myBean, PageContext.SESSION_SCOPE);所以在这里呢<jsp:getProperty name="myBean" property="count" /> 将会输出保存在在session里面的名为myBean的值,(就是楼主刷新N遍的值)。如果是第一次呢,就是0咯。  接着,楼主不甘心,有输出out.println(myBean.getCount()); 这个时候,这个myBean是我们刚开始声明的那个myBean,就是 mypack.CounterBean myBean = null;啦,如果是第一次的话,他肯定也是0咯,因为我们是"牛"的嘛,如果是楼主刷新N次的,那他已经是myBean = (mypack.CounterBean) pageContextObj.getAttribute("myBean"), pageContext.SESSION_SCOPE); 里的了,所以结果会和 刷新N遍的值一致。
      最后楼主还是没有满足好奇心让他加一,注意这里面<jsp:setProperty name="myBean" property="count" value=" <%=myBean.getCount()+1%>"/> 有个myBean.getCount()+1,这个myBean是和out.println(myBean.getCount());同一个引用。setProperty和getProperty一样,都使用了findAttribute("myBean"),同样因为我们只有一个session里面有属性名为"myBean"的东东,所以大家会看到,刷新后输出的值都是一样。
    最后,楼主的求知欲加强;把 scope="session" 改成了scope="application",那么问题就来了,当楼主不停刷新这个改动后的页面后困惑的发现,值永远是 1,0 ,然后楼主就来散分就解了。  这个问题其实主要是findAttribute("myBean")是引起的。
      
      同样,楼主使用 
        <jsp:useBean id="myBean" scope="application" class="mypack.CounterBean" /> 后,系统知趣的执行为:
          mypack.CounterBean myBean = null;
          myBean = (mypack.CounterBean) pageContextObj.getAttribute("myBean", pageContext.APPLICATION_SCOPE);
          if(myBean == null) {
    myBean = new yugu.com.Bean(); 
            然后放到APPLICATION里面去
          }
      到这里是没有问题滴,继续:
         <jsp:getProperty name="myBean" property="count" /> 
        在这里呢,还记得楼主在最开始的时候
         <jsp:useBean id="myBean" scope="session" class="mypack.CounterBean" /> ,如果session这个时候没有过期,那么session里面的值就还在咯。系统照例使用findAttribute("myBean"),因为这个方法会按照顺序搜索page, request, session ,application,在session的时候就发现了有这么个值,所以返回session里名为"myBean"的值。所以这里输出的是session里的值.
         然后呢,out.println(myBean.getCount()); 这里的myBean正是我们声明的mypack.CounterBean myBean = null;的那个引用,所以输出的是我们在页面声明的那个myBean里面的值。
         在楼主使用 setProperty 把application里的count值加一然后赋给了session里面的那个myBean。
         所以在修改了之后jsp之后,application里面的count值一直没有变化(count一直保持为0,比人民币坚挺),而每次刷新页面的时候,都用application里的count值加一赋给session里的,所以在刷新页面后session里的count值是0+1=1.    模拟输出:
          未改之前的页面,假如楼主刷新N+1次,那么此时的输出是 N  N
          现在楼主改了jsp,开始执行新jsp:
                第一次的输出  N  0 
                以后的输出:1,0楼主,送分啦,我写了好久啊,做论文的时候都没这么认真过,本人从小语文不好,措辞见谅哈!转帖注明:[email protected] (尊重他人劳动成果,谢谢)
      

  25.   

    我解释的清楚不?楼主不清楚加我QQ,我可惦记着100分呢,呵呵,要分哄MM
      

  26.   

    之前看这个问题的时候也感觉不需要运行,基本就这样,后来看见那么多朋友都有同样的问题,我自加试了试,也发现同样的问题,看来真是实践出真知,我自己是用下面代码来理解的,但是不如huangwen9兄弟说的那么清楚明白
    我的理解也只是认为getProperty和setProperty的工作原理并不像大家想的那样,但是具体的工作原理我真是不知道,看了huangwen9的解释,终于恍然大悟<%@ page import="adfa.CounterBean" %> 
    <html> 
    <head> 
    <title> 
    Counter 
    </title> 
    </head> 
    <jsp:useBean id="myBean" scope="session" class="adfa.CounterBean" /> <!--第一行-->
    <body> 
    getProperty:<jsp:getProperty name="myBean" property="count" /> <!--第二行-->
    <br>
    session EL:${sessionScope["myBean"]["count"]}<br /> <!--第三行-->
    <% 
    out.println(myBean.getCount());//第四行
    %> 
    <br />
    application EL:${applicationScope["myBean"]["count"]}<br /><!--第五行-->
    <jsp:setProperty name="myBean" property="count" value="<%=myBean.getCount()+1%>"/> <!--第六行-->
    </body>
    </html> huangwen9兄弟说的太详细了,佩服佩服,不过貌似有点需要纠正的地方...输出结果那里
    模拟输出: 
          未改之前的页面,假如楼主刷新N+1次,那么此时的输出是 N  N 
          现在楼主改了jsp,开始执行新jsp: 
                第一次的输出  N+1  0  
                以后的输出:1,0 
    因为这个时候之前刷新出的数字N实际上已经在页面里被setProperty标签加了1..所以修改完
    第一次刷新的以后这里应该是N+1
    哈哈,有点鸡蛋里挑骨头了,不过有不小的收获,以往用标签的时候很少会考虑标签到底是用了那个类的什么方法来实现的,所以今天才会出现这样的问题,很多人找不到原因PS:大家如果不相信的话可以先用application再用session来看看结果,很有意思
      

  27.   

    37楼正解,下面是 findAttribute的API说明
        /**
         * Searches for the named attribute in page, request, session (if valid),
         * and application scope(s) in order and returns the value associated or
         * null.
         *
         * @param name the name of the attribute to search for
         * @return the value associated or null
         * @throws NullPointerException if the name is null
         */    abstract public Object findAttribute(String name);以及JSP编译后的部分代码      net.java2000.html.CounterBean myBean = null;
          synchronized (application) {
            myBean = (net.java2000.html.CounterBean) _jspx_page_context.getAttribute("myBean", PageContext.APPLICATION_SCOPE);
            if (myBean == null){
              myBean = new net.java2000.html.CounterBean();
              _jspx_page_context.setAttribute("myBean", myBean, PageContext.APPLICATION_SCOPE);
            }
          }
          out.write("\r\n");
          out.write("<body>\r\n");
          out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString((((net.java2000.html.CounterBean)_jspx_page_context.findAttribute("myBean")).getCount())));
          out.write("\r\n");
          out.write("<br>\r\n");  out.println(myBean.getCount());      out.write('\r');
          out.write('\n');
          org.apache.jasper.runtime.JspRuntimeLibrary.handleSetProperty(_jspx_page_context.findAttribute("myBean"), "count",
    myBean.getCount()+1);
      

  28.   

    针对本问题,我整理的文档可以看这里,再次感谢35楼和37楼的朋友。
    其中16楼虽然给出了答案,但没有解释清楚。呵呵!
    http://blog.csdn.net/java2000_net/archive/2008/04/11/2280615.aspx或者到我的网站http://www.java2000.net/viewthread.jsp?tid=2742
      

  29.   

    哈,一直在想这些JSP标签的原理,忘记了像版主一样看编译后的.
      

  30.   

    今天早上一来上班,突然发现变成精华贴了,对我来说这可是“大姑娘上轿——头一回”啊,高兴!感谢铁岭TV,感谢辽宁TV,讲来还有可能感谢CCTV哈哈,不说那么多废话了,整点有用的吧:感谢大家热心关注和分析,尤其是java2000_net(你贴的findAttribute的API说明,让我豁然开朗),AWUSOFT,还有huangwen9同学的幽默详尽的解释(这100分是非你莫属啦,嘎嘎)最后再问一个小问题,希望能找到书面的依据,大家别笑我:
    为啥你说的,<jsp:getProperty name="myBean" property="count" />等同于<%=(mypack.CounterBean)(pageContextObj.findAttribute("myBean")).getCount()%>呢??
      

  31.   

    简单说,就是为啥getProperty和findAttribute一样?
      

  32.   

    35楼牛人啊,看来还是需要servlet的基础,jsp才能学好。
      

  33.   

    哦,这么多人了呀,呵呵
    getProperty和findAttribute不是一样的。
    我之所以说<jsp:getProperty name="myBean" property="count" />等同于 <%=(mypack.CounterBean)(pageContextObj.findAttribute("myBean")).getCount()%>是就事论事。
    是因为,你在使用 <jsp:getProperty 的时候,系统会寻找属性名为myBean的关联,然后强制转换成mypack.CounterBean类型,因为你的property是count,所以它会去找一个getCount()的方法。  例如在一个bean里,如果你有一个属性为 apple,那么为了使用 g(s)etProperty标签你就必须提供setApple()和getApple()方法。
      

  34.   

    OK,懂了,谢谢。
    这个问题真迷惑人,周围问了一圈没人能说清楚,到这里弄懂了,看来还是CSDN藏龙卧虎啊。
    再次感谢huangwen9,100分送上。
      

  35.   

    原以为JSP写出来能用就行.
    今天才发现里面有趣的东西,难怪总听别人用什么东西都说玩~
      

  36.   

    还是实践出真知啊!!要多多学习了!
    不过我有点不明白,这里:
    myBean = (mypack.CounterBean) pageContextObj.getAttribute("myBean", pageContext.APPLICATION_SCOPE); 
    设计时为什么(mypack.CounterBean)(pageContextObj.findAttribute("myBean")).getCount();这个findAttribute()
    不根据jsp页面上给出的scope去查找,而是从page,request,session,application这样的顺序来查找呢?
    各位能说说吗?对jsp不是很清楚,希望学习下。
      

  37.   

    呵呵都说那么多,我说一种简单的办法,楼主可以试试把session改成request就行了<jsp:useBean id="myBean" scope="request" class="adfa.CounterBean" /> <!--第一行-->
      

  38.   


    哇————这个办法不错,100分应该给你啊!哈哈,lever0066,你实在太逗了...... ^_^