2011-02-14 125 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);