不是抽象的,不会覆盖抽象方法错误

时间:2013-05-21 08:27:34

标签: java servlets http-headers

我完全陷入了我的一个显示错误的课程中:

ResettableHttpServletResponse is not abstract and does not override abstract method getHeaderNames() in HttpServletResponse

这是我的整个班级:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.NestableRuntimeException;


@SuppressWarnings("deprecation")
public class ResettableHttpServletResponse implements HttpServletResponse, Resettable {

    private interface ResponseOperation {

        void apply();
    }
    private HttpServletResponse wrapped;
    private List<ResponseOperation> operations;
    private Locale locale;
    private int bufferSize;
    private String contentType;
    private String charset;
    private PrintWriter writer;
    private OutputStream outputStream;
    private ServletOutputStream servletOutputStream;
    private File contents;
    private Set<String> headerNames;
    private int status;
    private boolean stateApplied;

    public ResettableHttpServletResponse(final HttpServletResponse response) {
        wrapped = response;
        operations = new ArrayList<ResponseOperation>();
        headerNames = new HashSet<String>();
        resetState();
    }

    @Override
    public void addCookie(final Cookie cookie) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.addCookie(cookie);
            }
        });
    }

    @Override
    public void addDateHeader(final String name, final long date) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.addDateHeader(name, date);
            }
        });
    }

    @Override
    public void addHeader(final String name, final String value) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.addHeader(name, value);
            }
        });
    }

    @Override
    public void addIntHeader(final String name, final int value) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.addIntHeader(name, value);
            }
        });
    }

    @Override
    public void applyState() {
        try {
            // Apply all operations
            for (final ResponseOperation operation : operations) {
                operation.apply();
            }
            // Copy the response contents, if any
            if (outputStream != null) {
                try {
                    outputStream.flush();
                    IOUtils.copy(new FileInputStream(contents), wrapped.getOutputStream());
                } catch (final Exception e) {
                    throw new NestableRuntimeException(e);
                }
            } else if (writer != null) {
                try {
                    writer.flush();
                    IOUtils.copy(new FileReader(contents), wrapped.getWriter());
                } catch (final Exception e) {
                    throw new NestableRuntimeException(e);
                }
            }
            stateApplied = true;
        } finally {
            reset();
        }
    }

    @Override
    public boolean containsHeader(final String name) {
        return headerNames.contains(name);
    }

    @Override
    public String encodeRedirectUrl(final String url) {
        return wrapped.encodeRedirectUrl(url);
    }

    @Override
    public String encodeRedirectURL(final String url) {
        return wrapped.encodeRedirectURL(url);
    }

    @Override
    public String encodeUrl(final String url) {
        return wrapped.encodeUrl(url);
    }

    @Override
    public String encodeURL(final String url) {
        return wrapped.encodeURL(url);
    }

    @Override
    public void flushBuffer() throws IOException {
        // No-op, as nothing has been done in the real response
    }

    @Override
    public int getBufferSize() {
        return bufferSize;
    }

    @Override
    public String getCharacterEncoding() {
        return charset;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public Locale getLocale() {
        return locale;
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (writer != null) {
            throw new IllegalStateException("getWriter() was already invoked in this response");
        }
        if (servletOutputStream == null) {
            contents = File.createTempFile("cyclos_", "_response");
            outputStream = new FileOutputStream(contents);
            servletOutputStream = new ServletOutputStream() {
                @Override
                public void close() throws IOException {
                    outputStream.close();
                }

                @Override
                public void flush() throws IOException {
                    outputStream.flush();
                }

                @Override
                public void write(final byte[] b) throws IOException {
                    outputStream.write(b);
                }

                @Override
                public void write(final byte[] b, final int off, final int len) throws IOException {
                    outputStream.write(b, off, len);
                }

                @Override
                public void write(final int b) throws IOException {
                    outputStream.write(b);
                }
            };
        }
        return servletOutputStream;
    }

    public int getStatus() {
        return status;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        if (outputStream != null) {
            throw new IllegalStateException("getOutputStream() was already invoked");
        }
        if (writer == null) {
            contents = File.createTempFile("cyclos_", "_response");
            writer = new PrintWriter(contents);
        }
        return writer;
    }

    @Override
    public boolean isCommitted() {
        if (!stateApplied) {
            return false;
        }
        return wrapped.isCommitted();
    }

    @Override
    public void reset() {
        resetState();
    }

    @Override
    public void resetBuffer() {
        IOUtils.closeQuietly(outputStream);
        IOUtils.closeQuietly(writer);
        outputStream = null;
        servletOutputStream = null;
        writer = null;
        if (contents != null) {
            contents.delete();
            contents = null;
        }
    }

    @Override
    public void resetState() {
        status = 0;
        operations.clear();
        headerNames.clear();
        charset = wrapped.getCharacterEncoding();
        bufferSize = wrapped.getBufferSize();
        contentType = wrapped.getContentType();
        locale = wrapped.getLocale();
        resetBuffer();
    }

    @Override
    public void sendError(final int sc) {
        status = sc;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                try {
                    wrapped.sendError(sc);
                } catch (final IOException e) {
                    throw new NestableRuntimeException(e);
                }
            }
        });
    }

    @Override
    public void sendError(final int sc, final String msg) throws IOException {
        status = sc;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                try {
                    wrapped.sendError(sc, msg);
                } catch (final IOException e) {
                    throw new NestableRuntimeException(e);
                }
            }
        });
    }

    @Override
    public void sendRedirect(final String location) throws IOException {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                try {
                    wrapped.sendRedirect(location);
                } catch (final IOException e) {
                    throw new NestableRuntimeException(e);
                }
            }
        });
    }

    @Override
    public void setBufferSize(final int bufferSize) {
        this.bufferSize = bufferSize;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setBufferSize(bufferSize);
            }
        });
    }

    @Override
    public void setCharacterEncoding(final String charset) {
        this.charset = charset;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setCharacterEncoding(charset);
            }
        });
    }

    @Override
    public void setContentLength(final int len) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setContentLength(len);
            }
        });
    }

    @Override
    public void setContentType(final String contentType) {
        this.contentType = contentType;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setContentType(contentType);
            }
        });
    }

    @Override
    public void setDateHeader(final String name, final long date) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setDateHeader(name, date);
            }
        });
    }

    @Override
    public void setHeader(final String name, final String value) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setHeader(name, value);
            }
        });
    }

    @Override
    public void setIntHeader(final String name, final int value) {
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setIntHeader(name, value);
            }
        });
    }

    @Override
    public void setLocale(final Locale locale) {
        this.locale = locale;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setLocale(locale);
            }
        });
    }

    @Override
    public void setStatus(final int sc) {
        status = sc;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setStatus(sc);
            }
        });
    }

    @Override
    public void setStatus(final int sc, final String sm) {
        status = sc;
        operations.add(new ResponseOperation() {
            @Override
            public void apply() {
                wrapped.setStatus(sc, sm);
            }
        });
    }
}

任何人告诉我我应该做些什么来摆脱这个错误?

编辑:我在类中添加了以下方法声明,但它似乎没有影响我的错误。我该怎么办?

@Override
public Collection<String> getHeaderNames() {
    operations.add(new ResponseOperation() {
        @Override
        public void apply() {
            wrapped.getHeaderNames();
        }
    });
    return headerNames;
}

2 个答案:

答案 0 :(得分:7)

当您实现非抽象类的接口时,您必须重新定义接口中声明的所有方法。在这里,您没有重新定义接口getHeaderNames()中声明的方法HttpServletResponse

您需要在班级ResettableHttpServletResponse

中覆盖此方法

编辑:

您得到的错误是明确的。它清楚地表示您忘记覆盖接口HttpServletResponse的方法getHeaderNames

您应该阅读有关接口和继承的lesson

答案 1 :(得分:0)

抽象类或接口(本例)HttpServletResponse定义了一个你没有实现的抽象方法getHeaderNames()。由于你的课程也不是抽象的,这是一个错误。通常,IDE可以为所有抽象方法生成虚拟实现。

您可以考虑改用HttpServletResponseWrapper