作者zanyking (最後的六年级生)
看板java
标题Re: [问题] jsp间session物件引用cast例外
时间Thu Aug 29 02:03:10 2013
※ 引述《JeremyJoung (J.J.)》之铭言:
: 状况描述
: 於JSP中 以<%! %> 宣告CLASS Cart
: 相同页面内运作正常也可以删改
: 但是 当我以session+HashMap 保存Cart并於其他页面载入Cart时发生
: java.lang.ClassCastException:
: org.apache.jsp.login_jsp$Cart cannot be cast to org.apache.jsp.index_jsp$Cart
: 问题码是
: Cart c=cartL2.get(pdt);
: 从map中叫出来时就出错了
: cartL2 是LinkedHashMap<String, Cart>();
: 状况看起来是 login_jsp$Cart 不可以在index中使用
: 就算是使用(Cart)强转也无效
: 请问 为什麽会有这样的状况?
我尽量长话短说。
1. 可以的话,请不要在JSP里宣告class。
2. 如果你在JSP里宣告class,请记得这个class(注意,是class,不是instance)只能在
该JSP当中使用。
3. 更正确的讲法,甚至下一次request进到同一页,你从session里把东西取出来,是
不是还能用都不保证。
4. 以上,最保险的in JSP class用法,就是只在那个request的当下,在那页里面用,
或是不要用。
原因:
JSP会被JSP Compiler(如果你用Tomcat,那个Jasper Engine就是了。) compile 成
Servlet,然後跑在Container上,你在<% %>里宣告的class会成为一个inner class。
好,现在有几个问题:
1. 请问JSP是什麽时间点被Compile 成Servlet?
答案是:
看设定、看Container,有时是启动时会Compile,有时是request来才Compile
2. 请问Container如果突然觉得JSP应该重新Compile 一次,我们能保证他Compile 出
来的『新的』JspServlet,仍然跟旧的名称一样、记忆体结构一样吗?
答案是:
不能保证,JSP Engine高兴做啥就做啥,有些高级Java Web Server,为了支援线上
动态编辑JSP,然後直接动态挂载执行,会把改过的JSP Compile 成不同的servlet
Name但是吃同样的servlet path,这是因为在多绪执行环境里,可能某些User
已经在存取使用该JSP前一版的servlet class instance了,所以不可以直接下线
,得要先把新版的准备好,把流量导过去後才把旧的版本从classLoader里卸载。
那如果你在前一版的时候create 了一个Cart存Session,然後好死不死,user前脚
刚刚结束一个request,Container就把第二版给上了,结果user再发一个request
的时候连到的是第二版JSP,className都不一样了。
而你的程式码这时想从session里把Cart拿出来,想要cast成Cart...糗了。
my_JspServlet.Cart跟my_JspServlet2.Cart可是不同的class。
事实上,你Session里的cart物件,很有可能再也找不到正确的class可以处理了。
(如果session是被Serialize到disc再被load回来,那此时会喷error,甚至根本就
serialize 不出去)
: 是JSP间禁止引用不同页面间所宣告的物件吗?
: 这问题该如何回避?
: 感谢解答.
...好,我的废话还是太多了,Anyway,如果上面的有任何地方你看不懂,你就没有资格
在JSP里宣告class,你用了会动,很可能只是运气好没碰上而已。
你不懂却用了但没事,只是沙滩上的城堡碰上退潮而已,该来的还是会来的。
请乖乖的宣告一个Cart.java在你的project src里,compile它,然後用它。
--
生命起源於简单的化学反应,灵魂是脑神经上头的火花。
掌纹没有含意,不过是具有止滑功用的纹路。
而神不存在,死去的人们只是等待细菌分解的腐肉而已。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 123.193.164.59
1F:推 PsMonkey:长话短说是违反版规的 [指] [完全误] 08/29 12:08