Springmvc JSP靜態化處理 | 不須要第三方Jar 不須要任何模板化技術

最近想接了一個活,需求是採集多方網站,而後導入到本身庫中。 CMS+爬蟲。考慮到CMS期初打算用 織夢作一個前臺,java作數據來着,結果想了想仍是本身寫一個吧。html

嘗試了下Freemarker,可是都有點缺點就是 標籤庫不夠我用,不能定義全局變量。我的習慣想找一個不須要任何框架,我就一個modelandview對象你就生成html就行。找了不少 ぜんぜん 很差使。因此考慮本身寫一個吧,參考了國外大神的回答:https://stackoverflow.com/questions/8933054/how-to-read-and-copy-the-http-servlet-response-output-stream-content-for-logging

    首先,Springmvc 它本身是不給咱們返回響應的,這一點搞得人很糾結,因此要重寫方法。

You need to create a Filter wherein you wrap the ServletResponse argument with a custom HttpServletResponseWrapper implementation wherein you override the getOutputStream() and getWriter() to return a custom ServletOutputStream implementation wherein you copy the written byte(s) in the base abstract OutputStream#write(int b) method. Then, you pass the wrapped custom HttpServletResponseWrapper to the FilterChain#doFilter() call instead and finally you should be able to get the copied response after the the call. 上面是原話。就是重寫 response 和 ServletOutputStream 。而後創建一個過濾器便可。java

過濾器:mvc

@WebFilter("/*")
public class ResponseLogger implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        // NOOP.
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (response.getCharacterEncoding() == null) {
            response.setCharacterEncoding("UTF-8"); // Or whatever default. UTF-8 is good for World Domination.
        }

        HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);

        try {
            chain.doFilter(request, responseCopier);
            responseCopier.flushBuffer();
        } finally {
            byte[] copy = responseCopier.getCopy();
        }
    }

    @Override
    public void destroy() {
        // NOOP.
    }

}
在過濾器中使用「new String(copy, response.getCharacterEncoding())」 獲取返回的響應內容。而後寫一個寫入到文件的方法,就能夠生成html咯。不過速度挺通常的。
你們能夠在後臺單獨寫一個方法,而後定義爲生成html的方法,而後首頁列表頁直接修改成靜態頁面的地址便可。由於這個生成html要走過濾器,你們也能夠自行改進,而後作成調用的方法來用就比較好使。

重寫的Responseapp

public class HttpServletResponseCopier extends HttpServletResponseWrapper {

    private ServletOutputStream outputStream;
    private PrintWriter writer;
    private ServletOutputStreamCopier copier;

    public HttpServletResponseCopier(HttpServletResponse response) throws IOException {
        super(response);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (writer != null) {
            throw new IllegalStateException("getWriter() has already been called on this response.");
        }

        if (outputStream == null) {
            outputStream = getResponse().getOutputStream();
            copier = new ServletOutputStreamCopier(outputStream);
        }

        return copier;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        if (outputStream != null) {
            throw new IllegalStateException("getOutputStream() has already been called on this response.");
        }

        if (writer == null) {
            copier = new ServletOutputStreamCopier(getResponse().getOutputStream());
            writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()), true);
        }

        return writer;
    }

    @Override
    public void flushBuffer() throws IOException {
        if (writer != null) {
            writer.flush();
        } else if (outputStream != null) {
            copier.flush();
        }
    }

    public byte[] getCopy() {
        if (copier != null) {
            return copier.getCopy();
        } else {
            return new byte[0];
        }
    }

}

重寫的ServletOutputStream框架

public class ServletOutputStreamCopier extends ServletOutputStream {

    private OutputStream outputStream;
    private ByteArrayOutputStream copy;

    public ServletOutputStreamCopier(OutputStream outputStream) {
        this.outputStream = outputStream;
        this.copy = new ByteArrayOutputStream(1024);
    }

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

    public byte[] getCopy() {
        return copy.toByteArray();
    }

}
相關文章
相關標籤/搜索