Java 如何在Tomcat中获取org.apache.catalina.connector.Request对象?

Java 如何在Tomcat中获取org.apache.catalina.connector.Request对象?,java,tomcat,servlets,Java,Tomcat,Servlets,我需要编写一个Servlet或过滤器类,该类可以访问org.apache.catalina.connector.Request对象,该对象封装在提供给我的Servlet的RequestFacade对象中。强制转换不起作用,因为RequestFacade不是Request的子类 我之所以需要这样做,是因为我试图调用Request的setRequestedSessionId()方法,而这显然不是Http servlet规范的一部分。我之所以需要这样做,是因为会话ID包含在URL中的名称与JSSess

我需要编写一个Servlet或过滤器类,该类可以访问org.apache.catalina.connector.Request对象,该对象封装在提供给我的Servlet的RequestFacade对象中。强制转换不起作用,因为RequestFacade不是Request的子类

我之所以需要这样做,是因为我试图调用Request的setRequestedSessionId()方法,而这显然不是Http servlet规范的一部分。我之所以需要这样做,是因为会话ID包含在URL中的名称与JSSessionID不同。我无法更改URL或参数的名称,因此我试图通过提取会话ID和调用request.setRequestedSessionId()将请求与正确的会话关联

实际上,我已经用一个Valve子类解决了这个问题,但我不喜欢使用Valve,因为据我所知,我需要在Tomcat/server/classes目录中安装我的Valve子类,而不是将它与我的webapp的其余部分打包在一起。如果有一种可移植的方法可以跨不同的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或过滤器中是否有一些方法可以做同样的事情?或者是否有某种方法可以将Valve类打包到我的application.war文件中?

(这是我升级为答案的评论)

如果您使用的是Tomcat 5.5或6,那么这可能是您可以考虑的一种替代方法:。您可以使用系统属性更改用于会话id参数的名称。但据我所知,它不适用于Tomcat7(我认为tc7实现的servlet规范在更改名称方面更为严格)


至于从您的webapp(servlet或过滤器)访问Tomcat内部请求对象,我认为您不能。我似乎记得在某个地方读到过,RequestFacade类明确地存在是为了防止这种情况,这样Web应用程序就不会弄乱Tomcat的内部结构。

Tomcat将真正的请求对象存储在RequestFacade的受保护变量Request中,这样您就可以得到它(在Servlet或JSP中)与:


为什么我需要做什么?我想我在第二段说明了原因,请告诉我我没有解释清楚的部分。如果您使用的是Tomcat 6,那么这可能是您可以考虑的另一种选择:。您可以使用系统属性更改用于会话id参数的名称。但据我所知,Tomcat7不支持它(我认为tc7实现的servlet规范在更改名称方面更为严格)。嗨,Matt,我们使用的是Tomcat5.5,所以我不知道我们是否可以依赖这个调整,但这真的很巧妙!比我想做的更好的解决方案。我将调查Tomcat5.5是否支持它;它在5.5中也是可配置的,因此这对我们来说非常适合。如果你想转载作为一个答案,我会标记为接受的答案,这样你就可以得到学分。我仍然很好奇,如果我需要直接调用请求对象上的方法,是否有某种方法可以访问请求对象。请注意,如果Java安全管理器限制setAccessible,这将不起作用。
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);