Springmvc JSP静态化处理 | 不需要第三方Jar 不需要任何模板化技术
2017-10-23 00:00
501 查看
最近想接了一个活,需求是采集多方网站,然后导入到自己库中。
CMS+爬虫。考虑到CMS期初打算用 织梦做一个前台,java做数据来着,结果想了想还是自己写一个吧。
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 。然后建立一个过滤器即可。
过滤器:
重写的Response
重写的ServletOutputStream
CMS+爬虫。考虑到CMS期初打算用 织梦做一个前台,java做数据来着,结果想了想还是自己写一个吧。
尝试了下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 。然后建立一个过滤器即可。
过滤器:
@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要走过滤器,大家也可以自行改进,然后做成调用的方法来用就比较好使。
重写的Response
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(); } }
相关文章推荐
- 关于大型网站技术演进的思考(二十)--网站静态化处理—web前端优化—中(12)
- 关于大型网站技术演进的思考(十一)--网站静态化处理—动静分离策略(3)
- 关于大型网站技术演进的思考(九)--网站静态化处理--总述(1)
- 关于大型网站技术演进的思考(九)--网站静态化处理--总述(1)
- 关于大型网站技术演进的思考(十五)--网站静态化处理―前后端分离―中(7)
- 关于大型网站技术演进的思考(十七)--网站静态化处理—满足静态化的前后端分离(9)
- 关于大型网站技术演进的思考(十)--网站静态化处理—动静整合方案(2)
- 关于大型网站技术演进的思考(十六)--网站静态化处理—前后端分离—下(8)
- 关于大型网站技术演进的思考(九)--网站静态化处理--总述(1)
- 关于大型网站技术演进的思考(九)--网站静态化处理--总述(1)
- 关于大型网站技术演进的思考(二十一)--网站静态化处理—web前端优化—下【终篇】(13)
- 关于大型网站技术演进的思考(十)--网站静态化处理—动静整合方案(2)
- 关于大型网站技术演进的思考(十一)--网站静态化处理—动静分离策略(3)
- 关于大型网站技术演进的思考(十六)--网站静态化处理―前后端分离―下(8)
- 关于大型网站技术演进的思考(十二)--网站静态化处理—缓存
- 关于大型网站技术演进的思考(二十一)--网站静态化处理—web前端优化—下【终篇】(13)
- ORACLE/JSP技术涉及日期、时间问题的处理
- 关于大型网站技术演进的思考(十五)--网站静态化处理—前后端分离—中(7)
- 关于大型网站技术演进的思考(十)--网站静态化处理—动静整合方案(2)
- 关于大型网站技术演进的思考(十五)--网站静态化处理—前后端分离—中(7)