【问题标题】:Adding a servlet filter that wraps the request into a HttpServletRequestWrapper seem to break page forwading添加将请求包装到 HttpServletRequestWrapper 中的 servlet 过滤器似乎会破坏页面转发
【发布时间】:2011-06-15 13:48:23
【问题描述】:

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

这是一个服务器端 Equinox 应用程序,在 Eclipse 中运行,使用嵌入式 Jetty Web 服务器提供 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 实现中的一个错误,但我可能遗漏了一些东西。

我做错了吗?

谢谢!!

爱德华多出生

【问题讨论】:

    标签: servlets osgi servlet-filters forwarding equinox


    【解决方案1】:

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

    找到ProxyServlet的来源:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2013-02-22
        • 2015-09-12
        • 2012-08-07
        • 2018-05-25
        • 2012-03-04
        • 2015-04-13
        • 2013-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多