【问题标题】:Making Servlet 2.5 code Servlet 3.0 compatible and vice versa使 Servlet 2.5 代码与 Servlet 3.0 兼容,反之亦然
【发布时间】:2014-04-14 23:05:36
【问题描述】:

我有一个实现 javax.servlet.Filter 的类,在该过滤器中,我正在实例化 InterceptHttpRequestFilter 和 InterceptHttpResponseFilter 的实例(用于修改传入和传出的请求和响应)

例子:

public class InterceptHttpRequestFilter implements HttpServletRequest {

    private HttpServletRequest httpReq;
    final StringBuffer sb = new StringBuffer();

    public InterceptHttpRequestFilter(ServletRequest request) {
        this.httpReq = (HttpServletRequest) request;
        try {
            StringWriter sw = new StringWriter();
            IOUtils.copy(request.getInputStream(), sw);
            sb.append(sw.getBuffer().toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    ....

使用 Servlet 2.5 在 Tomcat6 上部署此项目时,一切正常。 在 Tomcat 7 上部署它,我得到一个 AbstractMethodError:

SEVERE: Servlet.service() for servlet [_______] in context with path [/__________-1.0.0] threw exception [Filter execution threw an exception] with root cause
java.lang.AbstractMethodError
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:225)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at com.mycee.project.filter.MyFilter.doFilter(MyFilter.java:182)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

显而易见的解决方案是实现 Servlet 版本 3 的 HttpRequest / Response 接口所需的所有缺失方法。

对 mvnrepository 的 maven 依赖仍处于 alpha 阶段:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>3.0-alpha-1</version>
</dependency>

所以我的问题是,是否存在允许我在 Tomcat6 (Servlet 2.5) 和 Tomcat7 (Servlet 3.0) 上运行该项目而无需修改我的 InterceptHttpRequestFilter 和 InterceptHttpResponseFilter 的中间立场?

【问题讨论】:

  • 除了限制自己使用 2.5 不使用 3.0 的方法之外,我看不出...
  • 我不太明白这个。哪个抽象方法给你带来麻烦,在什么类上? MyFilter 是你的InterceptHttpRequestFilter 吗? AFAIK 你应该可以在 3.0 容器中使用 2.5 Filter 就好了。
  • @Anders,问题不在于过滤器,而在于实现 HttpServletRequest / Response 的拦截器,并且容器使用不同版本的 servlet 规范。 axtavt 使用 HttpServletRequestWrapper 的解决方案就是通过填充缺失的方法来解决这个问题。

标签: java maven tomcat servlets


【解决方案1】:

这就是为什么建议扩展HttpServletRequestWrapper 而不是直接实现HttpServletRequest

HttpServletRequestWrapper 实现了所有必需的方法,因此应该可以解决问题。

【讨论】:

  • 从来不知道 HttpServletRequestWrapper 和 HttpServletResponseWrapper - 一个非常简洁的解决方案,让我摆脱了大部分 @Overrides :-)
  • 今天学到了新东西! +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 2013-11-16
  • 2011-12-28
  • 2021-12-09
相关资源
最近更新 更多