在实际开发中,我们不可避免需要优化输出的内容,使得用户体验优化的效果。
其中,在Web开发当中就有tomcat的gzip来压缩输出流,使得网络带宽压力下降,从而提升浏览器的文件下载速度。这个办法的好处是配置简单,资源较多的情况下效果明显。
但是也有缺点:
1、增加CPU的负担。故此方法不适合CPU资源紧张的服务器。
2、压缩得还不算彻底。
3、需要相应支持的浏览器。
哪怕有上面这些问题,总体上来讲,这个技术还是利大于弊。毕竟CPU便宜过带宽。
为了压缩得更加彻底,我们可以尝试在gzip的基础上,实现一个进一步的代码压缩,把所有jsp、HTML、css、js这些资源文件自动输出成mini版。这样就可以到达进一步压缩的目的。但是会加深CPU、RAM的消耗以及,这个方法是通过自行写代码实现,所以有一定的难度以及可能不够灵活。
具体实现方式是:
1、继承javax.servlet.http.HttpServletResponseWrapper来编写一个Java类。
2、创建一个专门处理资源文件输出的Filter。
3、实现一段处理字符串的逻辑。
4、Filter过滤全部的请求,并且里面要分开各种资源请求的类型来进行不同处理。
5、字符串输出。
继承HttpServletResponseWrapper的Java代码:
import java.io.CharArrayWriter; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class ResponseWrapper extends HttpServletResponseWrapper { private CharArrayWriter out; public ResponseWrapper(HttpServletResponse response) { super(response); out = new CharArrayWriter(); } public PrintWriter getWriter() { return new PrintWriter(out); } public String toString() { return getCharArrayWriter().toString(); } public CharArrayWriter getCharArrayWriter() { return out; } }
负责过滤请求并返回处理后的信息的Filter以及内部写的一些处理方法:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import com.winsun.warpper.ResponseWrapper; /** * 专门用于对输出的内容进行格式化 * 可以起到一定的保密作用,以及优化服务器的流量带宽,但是对服务器CPU、RAM有一定的消耗 * @author Lph * @date 2015年11月27日 */ public class HTMLFilter implements Filter { //用于控制本FIlter的功能是否启动 private static boolean FILTER_SWITCH = true; public void destroy() { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { if(FILTER_SWITCH) { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; String servletPath = request.getServletPath(); String url = request.getContextPath() + servletPath; if(url.endsWith(".jsp") || url.endsWith(".action")) { ServletOutputStream outStream = servletResponse.getOutputStream(); ResponseWrapper wrapper = new ResponseWrapper(response); chain.doFilter(request, wrapper); String code = wrapper.toString(); String[] rows = code.split("\n"); StringBuffer codeBuffer = new StringBuffer(); String row = null; for(int i = 0 ; i < rows.length; i++) { row = rows[i]; row = clearTabcharacter(row); row = clearRowTheNodes(row); if(StringUtils.isBlank(row) || row.equals("\n")) { //清除空行 continue; } codeBuffer.append(row); } String result = codeBuffer.toString(); /*if(url.endsWith("css") || url.endsWith("js") || url.endsWith("map")) { System.out.println("Output Content:"); System.out.println(result); }*/ //result = clearRowsTheNodes(result); outStream.write(result.getBytes("UTF-8")); outStream.flush(); outStream.close(); } else { chain.doFilter(request, response); } } else { chain.doFilter(servletRequest, servletResponse); } } public void init(FilterConfig config) throws ServletException { String filterSwitch = config.getInitParameter("FilterSwitch"); FILTER_SWITCH = StringUtils.isBlank(filterSwitch) || filterSwitch.equals("on"); } /** * 清除字符串对象的其实制表符和结束的制表符 * @param row * @return */ public String clearTabcharacter(String row) { char[] chars = row.toCharArray(); int startIndex = -1, endIndex = -1; int i = 0; for(i = 0; i < chars.length; i++) { if(chars[i] == "\t".charAt(0) || chars[i] == " ".charAt(0)) { startIndex = i; } else { break; } } for(i = chars.length - 1; i >= 0; i--) { if(chars[i] == "\t".charAt(0) || chars[i] == " ".charAt(0)) { endIndex = i; } else { break; } } if(startIndex < 0) { return row; } else { if(endIndex < 1) { endIndex = row.length(); } return row.substring(startIndex + 1, endIndex); } } /** * 清除行注释,仅仅是判断"//" * 满足则返回空字符串。否则原样返回 * @param row 一行的内容 * @return */ public String clearRowTheNodes(String row) { if(row.startsWith("//")) { row = ""; } return row; } public String clearRowsTheNodes(String content) { StringBuffer code = new StringBuffer(); char[] chars = content.toCharArray(); boolean captureStart = false, captrueEnd = false; for(int i = 0; i < chars.length; i++) { if(i + 1 < chars.length) { if(chars[i] == "/".charAt(0) && chars[i + 1] == "*".charAt(0)) { captureStart = true; } if(chars[i] == "*".charAt(0) && chars[i + 1] == "/".charAt(0)) { captrueEnd = true; } if(captureStart == false && captrueEnd == false) { code.append(chars[i]); captureStart = false; captrueEnd = false; } } } return code.toString(); } }
- 这里仅仅是举例,没有彻底完成所以并不能完成的mini输出。
- 目前贴出来的代码仅仅支持jsp。其他资源文件还没处理。
- 支持JSP内“//”这种行注释的去除。
- 具体可以达到什么样的效果要看代码的实现。
- 自动输出迷你版在自动去除注释的情况下可以起到一定的保密作用。
- 方便更新版本,不需要每次修改文件都生成一次迷你版。
- 此方法是在jsp编译完毕之后才会进行处理,故jstl\el等情况不需要考虑
相关推荐
`py_mini_racer`就是这样一个库,它专注于提供JavaScript引擎的接口,使得Python代码能够执行JavaScript代码,从而实现跨语言交互。 `py_mini_racer`是基于Google的V8 JavaScript引擎的一个小型封装,它在Python中...
“Mini6410”和“Web远程浏览”则是关键的技术点,说明我们是在Mini6410上运行代码,通过Web接口实现远程访问。 压缩包中的文件名列表提供了一些线索: 1. LICENSE:通常包含软件的授权信息,可能涉及使用、修改和...
- **安全隔离**: 通过在沙箱环境中运行JavaScript,`py_mini_racer`可以在一定程度上保护Python应用免受恶意JavaScript代码的影响。 **4. 兼容性与依赖** `py_mini_racer-0.1.17-cp34-cp34-manylinux1_x86_64.whl`...
在这个“vue框架下的webpack包的使用,里面涉及html,css,JavaScript代码”的压缩包中,我们将会探讨如何在Vue项目中整合Webpack,以及HTML、CSS和JavaScript代码的处理。 1. **Vue与Webpack简介** - Vue.js 提供...
3. **添加与mini2440硬件平台相关的代码**:这部分是移植工作的核心,需要根据mini2440的具体特性来编写或修改代码。 #### 3. Android内核与主线Linux内核的区别 接下来,我们具体分析一下Android内核与主线Linux...
在提供的压缩包文件“wx-mini-qrcode-master”中,包含了这个组件的源代码、示例和使用说明。你可以通过阅读文档,了解如何在项目中集成这个组件,并进行实际操作。通常,这会涉及到在项目的json配置文件中声明依赖...
Klipper_Expander 独立 MCU,可与具有各种输入和输出的 Klipper 一起使用 微动开关_Endstop 用于机械限位开关的 PCB 微动开关_Z_Endstop 用于机械 Z 限位开关的 PCB Nano_Display 使 Arduino Nano 适应 RepRap 标准 ...
"pdf.js mini 包" 是这个项目的精简版,专为快速集成到工程中设计,尤其是对体积有严格要求的场景。 这个压缩包包含两个主要目录: 1. **web**: 这个目录包含了 PDF.js 应用的核心资源,如 JavaScript 文件、CSS...
项目的主要目标是构建一个能够解析 mini-C 语言的解释器,它需具备处理输入、词法分析、语法解析、执行中间代码和输出解释信息的功能。 首先,需求分析文档的引言部分明确了报告的目的,确定了软件的范围,并提供了...
首先,通过遍历DataGrid的Item对象,生成HTML表格的代码,并将其写入到HttpResponse的输出流中。然后,设置Content-Type为"application/vnd.ms-excel",并重定向到一个临时文件名,使得浏览器下载一个Excel文件。...
描述"mjpg streamer code base for Mini6410"表明这个压缩包包含了mjpg-streamer在Mini6410开发板上的代码基础,这通常意味着它已经过优化,以适应该硬件平台的性能和资源限制。 从标签"mjpg mjeg-streamer_6410...
在我们的迷你版中,我们需要设置一个或多个入口点,解析对应的源代码文件。 2. 输出配置(Output):定义了编译后的文件如何输出。这包括输出文件的路径、命名规则等。我们需要编写逻辑来处理这个过程,确保打包后...
这里你可以找到关于类、方法以及如何使用它们的具体信息。 ### 总结 MiniXML库为PHP开发者提供了一个简洁的工具,用于处理XML数据。尽管它的功能可能没有DOM或SimpleXML那样全面,但对于处理小型XML文件或对性能有...
【Node.js mini项目详解】 Node.js 是一个基于Chrome V8引擎的JavaScript运行环境,它让JavaScript可以在服务器端执行,极大地拓宽了JavaScript的应用领域。在这个名为"Node_miniProject"的项目中,我们将深入探讨...
`kmeans.m`很可能是实现这个算法的MATLAB代码,它会读取图像数据,执行k-means算法,并可能将结果输出为新的分割图像。 `loadFile.do.htm`可能是一个HTML文件,用于说明如何加载图像数据。在MATLAB中,通常使用函数...
3. 输出模块:解释中间代码,输出结果和错误信息。 这种模块化设计提高了内聚性和降低了耦合度。 **四、UI 设计** UI 设计关注用户体验,包括: 1. 样式原型:采用 HTML + CSS + Bootstrap + JavaScript 进行前端...
【标题】"基于PHP的disk 网盘源码 Mini GBK.zip" 是一个使用PHP编程语言开发的轻量级网盘系统源代码,专为GBK编码环境设计。这个源码可能适合那些需要构建简单、小巧且易于部署的个人或企业云存储解决方案的开发者。...
- 代码单元格:可以执行Python代码,实时查看输出结果。 - 绘图与可视化:使用matplotlib、seaborn等库进行数据可视化,增强结果解释。 - 组织结构:利用ToC(Table of Contents)扩展实现Notebook的目录结构,...
### 《动手学深度学习》安装GPU版Pytorch #### 一、准备工作 在开始安装GPU版Pytorch...以上就是关于《动手学深度学习》中GPU版Pytorch的安装指南,希望能帮助大家顺利完成安装。如有疑问或遇到问题,欢迎留言反馈。
WebpackCleanInitCode是一个关于使用Webpack进行项目初始化并优化代码清理的实践。Webpack 是一个流行的模块打包工具,它能够将JavaScript、CSS、图片等资源转换、打包,并生成优化过的静态资源。在这个项目中,我们...