移植问题及解决
移植問題及解決
By CFR(mudboy)
摘要:本文檔包括將現在系統:從tomcat5移植至WAS5.1,以及從WAS5.1移植到WAS6.0的一些問題的解決過程。
?
1、概述
應用架構:
WebStart/jsp + struts1.1 + spring115 + hibernate2.1
?
2、問題及解決
2.1 癥狀:用了JSTL標簽的JSP頁面運行出錯。
解決:由于was512不支持jstl2.0(標準的寫法將自動使用該版本的標簽而不用配置),因此,使用它時,需要web.xml中顯式的增加配置,或直接寫明使用:
<%@ taglib uri="/WEB-INF/tld/c-1_0.tld" prefix="c" %>
而不是2.0
在web.xml中增加如下即可
<taglib>
??? <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
??? <taglib-location>/WEB-INF/tld/c-1_0.tld</taglib-location>
</taglib>
如果支持,則可以直接用而不需要配置!
注意:jstl并不是WEB容器必須支持的東東!
?
2.2 癥狀:URLConnection調用Servlet,有兩種方法設置我當前的SESSION(后端傳過來的):
設置Cookie的:JSESSIONID,或重寫URL,這在tomcat完全沒有問題,但在WebSphere5.1下卻不行,到服務器又創建了一個新的SESSION,不知道為什么?
解決:一般而言,有兩種最常用的會話跟蹤機制,一種就是URL重寫。在客戶端不接受cookie的情況下可以使用URL重寫進行會話跟蹤。URL重寫包括向URL路徑添加一些容器可以解釋的數據。規范要求會話ID必須編碼在URL路徑中,參數名稱必須是jsessionid,
例如: http://www.myserver.com/catalog/index.html;jsessionid=1234
一種就是現在最常用的cookie了,規范要求所有的servlet都必須支持cookie。容器向客戶端發送一個cookie,客戶端在后續的處于同一個會話的請求中向服務器返回該cookie。會話跟蹤cookie的名字必須是JSESSIONID。
httpUrl=http://localhost:9080/Agile/getFlightList.do;jsessionid=-JW0T70Esp9QZlyfUKOsO7o?currentCity=PEK
上面的方式在WAS下也不行,也不知道還需要做什么設置?
原來,在WAS中,SESSIONID不止這些,而應該是:<your_session>:<websphere_clone_id>,而返回的只有:前的部分,當然沒有呀!!
看下面的日志:
swt process,sessionID is :uEVqj3UC4yYmIAZvmyZzuPw
2005-06-21 13:24:06 [com.ibatis.struts.SwtAction]-[DEBUG] other:0000uEVqj3UC4yYmIAZvmyZzuPw:-1,JSESSIONID=0000uEVqj3UC4yYmIAZvmyZzuPw:-1
2005-06-21 13:24:06 [com.ibatis.struts.SwtAction]-[DEBUG] cookie:JSESSIONID=0000uEVqj3UC4yYmIAZvmyZzuPw:-1
即SESSIONID還包括冒號后的部分。
在鏈接頁面中,將代代碼做如下修改:
<%
String sessionid = "";
Cookie[] cookie = request.getCookies();
for(int i = 0; i < cookie.length; i++)
{
?????? if(cookie[i].getName().trim().equalsIgnoreCase("JSESSIONID"))
?????? {
?????? ?????? sessionid = cookie[i].getValue().trim();
????????????? break;
?????? ?????? //logger.debug("cookie:"+cookie[i].getName() + "=" +cookie[i].getValue());
?????? }
??????
}
?
%>
?
<a href="/Agile/swt/index.jnlp?sessionid=<%=sessionid%>">lanuch agile client here</a>
?
實際上,解決此方法唯一要改的地方就是鏈接處(見上):
但為了以后其它的兼容性,也可將URL重寫也加上,這在HTTPUTIL文件中。
即不能通過調用getSession().getId()得到,而應該自己從Cookie中找
?
?
2.3 癥狀:ORB得不到,通過JNDI無法得到,也無法得到SUN的ORB。
解決:由于WAS用的是IBM自己改造過的JRE,因此,通過實驗,無法更換到SUN的JRE,而且也無法讓相關的SUN的ORB組件介入。最終還應通過JNDI獲取。
將通過JNDI得到ORB的代碼改成如下:
orb = (org.omg.CORBA.ORB) ctx.lookup("java:comp/ORB");
orb =(org.omg.CORBA.ORB)javax.rmi.PortableRemoteObject.narrow(
???????????????????? ?????? ?????? ctx.lookup("java:comp/ORB"),
???????????????????? ?????? ?????? org.omg.CORBA.ORB.class);
運行正常。
?
?
?
2.4 癥狀:從WAS5.1到WAS6.X 出現的問題,即URL重寫導致STRUTS相關的請求均無法正常完成。
解決:主要原因是:getPathInfo,getServletPath的實現有變動,這會影響到struts,acegi等獲得路徑的行為。
?
解決方法:
?????? 將SWT中的URL重寫部分去掉
?????? 創建新的RequestProcess,可以只在WAS6.X上才配置用該RequestProcess,在該process中,取得路徑后,如果有URL重寫部分則將其去掉
?????? 配置上新的processor后,工作正常。
?
?
附錄1:
得到ORB異常信息:
org.omg.CORBA.INTERNAL:?? vmcid: 0x4f422000? minor code: 77? completed: No
[05-6-21 13:50:59:656 CST] 2dbf5794 SystemErr???? R ?? at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[05-6-21 13:50:59:656 CST] 2dbf5794 SystemErr???? R ?? at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:79)
[05-6-21 13:50:59:656 CST] 2dbf5794 SystemErr???? R ?? at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java(Compiled Code))
[05-6-21 13:50:59:656 CST] 2dbf5794 SystemErr???? R ?? at java.lang.reflect.Constructor.newInstance(Constructor.java(Compiled Code))
?
附錄2:
有關InitServlet晚于listener執行的問題,解決無非兩種:
1)讓Spring在需要時才生成對象
2)自己寫listener載入配置(不在InitServlet中進行),且必須在Spring的listener之前執行。
3)規定不要在SPRING管理的類構造函數中調用配置。
目前已按方法2進行。
?
?
?
附錄3:
以下是IBM BBS上的一些問答,供參考:
?
附錄:
http://www-128.ibm.com/developerworks/forums/dw_thread.jsp?message=4023650&cat=9&thread=54497&treeDisplayType=threadmode1&forum=266#4023650
?
JSESSIONID cookie - Help!
Originally posted: 2004 July 15 05:39 AM
? Nau????? Post new reply?
?
Hi, All
?
I have a need to call a servlet from another one withing the same session:
?
URL url = new URL( someURL );
URLConnection connection = url.openConnection();
connection.setDoInput( true );
connection.setRequestProperty( "Cookie", "JSESSIONID=" + request.getSession().getId() );
?
This piece of code works fine for Tomcat but on Webspere I'm getting a new session.
?
Any help please!
Thanks a million
?
Re: JSESSIONID cookie - Help!
Originally posted: 2004 July 19 07:15 AM
? Ben_????? Post new reply?
?
WebSphere generates a cookie named JSESSIONID with value
<your_session>:<websphere_clone_id>.
?
It can be JSESSIONID=000024N1ZDMZZH022EANUW2ZO5I:u7078j8m, for example.
?
You can see this if you look at the cookies the browser received or dump the
HTTP request headers.
?
You built an HTTP request containing the JSESSIONID cookie with
"JSESSIONID=" + request.getSession().getId(), but this code is broken
because getSession().getId() only return the value before the ':' sign in
the cookie value.
?
Since only the *name* of the cookie is standardized in J2EE (JSESSIONID),
it's a bad idea to assume the format of the cookie is simply the session id,
because the way the *value* of the session cookie is computed is not J2EE
standardized.
?
You'd better read the actual value from the HTTP request header instead.
?
?
?
Re: JSESSIONID gets overwritten
Originally posted: 2005 Feb 28 05:01 PM
? sjostrand2@hotmail.com????? Post new reply?
?
?
Lukasz Szelag wrote:
> JSESSIONID gets overwritten in the following scenario:
>
> 1. HTTP Request is sent to "A" URL.
>
> 2. HTTP session is created for "A" and session ID is stored in
> JSESSIONID cookie.
>
> 3. "A" stores an object in the session.
>
> 4. "A" calls "B" ("B" provides a menu)
>
> 5. HTTP session is created for "B" and session ID is stored in
> JSESSIONID cookie overwriting the previous value ("A" session ID).
>
> 6. Second HTTP request is sent to "A" URL.
>
> 7. "A" fails to lookup the object in the session stored in step 3.
> request.getSession(false) returns null.
>
> Is there a way to cure this problem? Thanks.
>
> PS. Not sure if that matters but "A" and "B" are deployed on two
> different servers. Specifying a different names for cookies seems to
> help, i.e. JSESSIONID_A and JSESSIONID_B but this is WebSphere
specific
> extension (Servlet specification requires that the cookie name is
> JSESSIONID).
>
> Lukasz
?
I assume that A and B are in two different WAR files and therefore have
different context roots, right?
?
In that case you could use WebSphere's admin console and change the
cookie path from the default (which is /, meaning the cookie is sent as
long as the URL starts with a /, which is always) to the context root
for each application.
So for application A, set the cookie path to /appA_contextRoot and for
application B, set the cookie path to /appB_contextRoot.
?
In WebSphere's admin console, go to Enterprise Applications ->
Application A -> Session Management -> {click the Enable Cookies link}
and change the Cookie path.
Good luck
/Henrik Sjostrand
總結