0

当请求被 HttpServletRequestWrapper 包装时,我在让 servlet 转发工作时遇到问题。

这是一个服务器端 Equinox 应用程序,使用嵌入式 Jetty Web 服务器在 Eclipse 中运行,以提供 HttpService 实现。

为了隔离问题,我的字段唯一要做的就是包装请求并将其转发:

public class TestFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest)request), response);
    }
    ...
}

...而我的 servlet 除了尝试转发到 JSP 之外什么都不做:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    RequestDispatcher dispatcher = request.getRequestDispatcher("/account.jsp");
    try {
        dispatcher.forward(request, response);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

根据 servlet 2.3 规范,传递给 forward 方法的请求和响应对象可以是原始对象,也可以是提供的包装器的实例。我需要传递一个自定义包装器,但是当我这样做时,转发失败了以下异常:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(Unknown Source)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:64)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:318)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:327)
    at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126)
    at org.eclipse.equinox.http.servlet.internal.RequestDispatcherAdaptor.forward(RequestDispatcherAdaptor.java:30)
    at mypackage.internal.signup.PlatformSetupServlet.doPost(PlatformSetupServlet.java:53)
...

如果我拿走包装器并转发原始请求,则 servlet 转发成功。

这看起来像是 org.eclipse.equinox.http.servlet 实现中的一个错误,但我可能遗漏了一些东西。

难道我做错了什么?

谢谢!!

爱德华多·博恩

4

2 回答 2

0

解析请求信息时,ProxyServlet 似乎遇到了问题。

找到ProxyServlet的来源:

http://kickjava.com/src/org/eclipse/equinox/http/servlet/internal/ProxyServlet.java.htm

虽然它不完全匹配,但您可以从代码中看到它正在尝试从您的请求中提取路径信息——它没有找到它所期望的“/”。您可以尝试调整 servlet 的路径,只是为了测试它?

于 2011-02-23T05:34:55.190 回答
0

这应该是 ProxyServlet.service 方法中的代码将 -1 传递给子字符串引起的。但是“转发”破坏您的代码的原因是“转发”不会创建一个全新的包装层次结构。相反,它会找到并用新转发的请求替换最里面的请求。

所以外包装不会改变,如果你要求它返回查询字符串,如果它有一个缓存的查询字符串,它将返回相同的,而不是转发的。

我遇到了这个问题,我正在努力解决。如果我成功了,我会再次在这里发帖。

请参阅我刚刚发布的这个问题,以更好地描述我的意思: How to know when the request is forwarded in a RequestWrapper object

于 2011-04-11T13:52:07.887 回答