2011-02-14 21 views
5

我需要編寫一個Servlet或Filter類,它可以訪問org.apache.catalina.connector.Request對象,該對象包裝在給予我的servlet的RequestFacade對象中。 Casting不起作用,因爲RequestFacade不是Request的子類。如何獲取Tomcat中的org.apache.catalina.connector.Request對象?

我需要這個的原因是因爲我試圖調用Request的setRequestedSessionId()方法,而這顯然不是Http servlet規範的一部分。我需要這樣做的原因是因爲會話ID被包含在一個名稱不同於JSESSIONID的URL中。我無法更改URL或參數的名稱,所以我試圖通過提取會話ID並調用Request.setRequestedSessionId()將請求與正確的會話相關聯。

我已經使用Valve子類實際解決了這個問題,但我不喜歡使用Valve,因爲據我所知,我需要將我的Valve子類安裝在Tomcat/server/classes目錄中而不是打包它與我的其他web應用程序。如果有一種可移植的方法可以跨越不同的Servlet容器來做到這一點,那就太好了,但是現在我已經放棄了製作這個Tomcat的特定版本。

這裏是工作的閥門代碼:

public class SessionSetter extends ValveBase { 
public void invoke(Request request, Response response) throws IOException, ServletException { 
    String sessionId = request.getParameter("whatever"); 
    request.setRequestedSessionId(sessionId); 
} 

}

是否有某種方式做同樣的事情在Servlet或篩選?或者有沒有辦法在我的應用程序.war文件中打包Valve類?

+0

爲什麼你需要一個? – Bozho 2011-02-14 21:15:16

+1

爲什麼我需要做什麼?我想我在第二段中說明了原因,請告訴我哪一部分我沒有解釋清楚。 – 2011-02-14 21:41:53

回答

5

(這是我的評論升級到一個答案)

如果你使用的是Tomcat 5.5或6那麼這可能是一種替代你可以看看:http://tomcat.apache.org/tomcat-6.0-doc/config/systemprops.html#Sessions。您可以使用系統屬性更改用於會話ID參數的名稱。儘管我可以告訴它,但它不適用於Tomcat 7(我認爲tc7實現的servlet規範更嚴格地關於更改名稱)。

至於從您的webapp(servlet或過濾器)訪問Tomcat內部請求對象,我不認爲你能夠。我似乎回想起在某處讀取RequestFacade類明確存在以防止這種情況,以便webapp不能混淆Tomcat內部。

3

的Tomcat存儲在受保護的變量要求RequestFacade的,這樣你就可以得到它(在servlet或JSP)真正請求對象與reflection

import java.lang.reflect.Field; 
import org.apache.catalina.connector.Request; 

... 

Field f = request.getClass().getDeclaredField("request"); 
f.setAccessible(true); // grant access to (protected) field 
Request realRequest = (Request)f.get(request);