`
lph279430114
  • 浏览: 7751 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

关于输出mini版HTML代码的方法

阅读更多

在实际开发中,我们不可避免需要优化输出的内容,使得用户体验优化的效果。

其中,在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等情况不需要考虑
分享到:
评论

相关推荐

    Python库 | py_mini_racer-0.1.9-cp36-cp36m-macosx_10_6_intel.whl

    `py_mini_racer`就是这样一个库,它专注于提供JavaScript引擎的接口,使得Python代码能够执行JavaScript代码,从而实现跨语言交互。 `py_mini_racer`是基于Google的V8 JavaScript引擎的一个小型封装,它在Python中...

    通过Web远程浏览并控制Mini6410上的摄像头-

    “Mini6410”和“Web远程浏览”则是关键的技术点,说明我们是在Mini6410上运行代码,通过Web接口实现远程访问。 压缩包中的文件名列表提供了一些线索: 1. LICENSE:通常包含软件的授权信息,可能涉及使用、修改和...

    Python库 | py_mini_racer-0.1.17-cp34-cp34-manylinux1_x86_64.whl

    - **安全隔离**: 通过在沙箱环境中运行JavaScript,`py_mini_racer`可以在一定程度上保护Python应用免受恶意JavaScript代码的影响。 **4. 兼容性与依赖** `py_mini_racer-0.1.17-cp34-cp34-manylinux1_x86_64.whl`...

    vue框架下的webpack包的使用,里面涉及html, css, JavaScript代码.zip

    在这个“vue框架下的webpack包的使用,里面涉及html,css,JavaScript代码”的压缩包中,我们将会探讨如何在Vue项目中整合Webpack,以及HTML、CSS和JavaScript代码的处理。 1. **Vue与Webpack简介** - Vue.js 提供...

    移植Android_到mini2440

    3. **添加与mini2440硬件平台相关的代码**:这部分是移植工作的核心,需要根据mini2440的具体特性来编写或修改代码。 #### 3. Android内核与主线Linux内核的区别 接下来,我们具体分析一下Android内核与主线Linux...

    微信小程序专用的二维码组件支持base64输出和canvas绘制两种方式

    在提供的压缩包文件“wx-mini-qrcode-master”中,包含了这个组件的源代码、示例和使用说明。你可以通过阅读文档,了解如何在项目中集成这个组件,并进行实际操作。通常,这会涉及到在项目的json配置文件中声明依赖...

    由 Voron 设计组设计的 很酷的硬件_HTML_代码_下载

    Klipper_Expander 独立 MCU,可与具有各种输入和输出的 Klipper 一起使用 微动开关_Endstop 用于机械限位开关的 PCB 微动开关_Z_Endstop 用于机械 Z 限位开关的 PCB Nano_Display 使 Arduino Nano 适应 RepRap 标准 ...

    pdf.js mini包

    "pdf.js mini 包" 是这个项目的精简版,专为快速集成到工程中设计,尤其是对体积有严格要求的场景。 这个压缩包包含两个主要目录: 1. **web**: 这个目录包含了 PDF.js 应用的核心资源,如 JavaScript 文件、CSS...

    需求分析1.0——端茶倒水小组1

    项目的主要目标是构建一个能够解析 mini-C 语言的解释器,它需具备处理输入、词法分析、语法解析、执行中间代码和输出解释信息的功能。 首先,需求分析文档的引言部分明确了报告的目的,确定了软件的范围,并提供了...

    DataGrid导出EXCEL的几个方法(WebControl).rar

    首先,通过遍历DataGrid的Item对象,生成HTML表格的代码,并将其写入到HttpResponse的输出流中。然后,设置Content-Type为"application/vnd.ms-excel",并重定向到一个临时文件名,使得浏览器下载一个Excel文件。...

    mjpg-streamer-mini6410-bin.tar.gz_Mjpg_mjeg-streamer 6410

    描述"mjpg streamer code base for Mini6410"表明这个压缩包包含了mjpg-streamer在Mini6410开发板上的代码基础,这通常意味着它已经过优化,以适应该硬件平台的性能和资源限制。 从标签"mjpg mjeg-streamer_6410...

    手写迷你版的webpack

    在我们的迷你版中,我们需要设置一个或多个入口点,解析对应的源代码文件。 2. 输出配置(Output):定义了编译后的文件如何输出。这包括输出文件的路径、命名规则等。我们需要编写逻辑来处理这个过程,确保打包后...

    php minixml详解

    这里你可以找到关于类、方法以及如何使用它们的具体信息。 ### 总结 MiniXML库为PHP开发者提供了一个简洁的工具,用于处理XML数据。尽管它的功能可能没有DOM或SimpleXML那样全面,但对于处理小型XML文件或对性能有...

    Node_miniProject

    【Node.js mini项目详解】 Node.js 是一个基于Chrome V8引擎的JavaScript运行环境,它让JavaScript可以在服务器端执行,极大地拓宽了JavaScript的应用领域。在这个名为"Node_miniProject"的项目中,我们将深入探讨...

    快速K-均值(kmeans)聚类图像分割算法源代码

    `kmeans.m`很可能是实现这个算法的MATLAB代码,它会读取图像数据,执行k-means算法,并可能将结果输出为新的分割图像。 `loadFile.do.htm`可能是一个HTML文件,用于说明如何加载图像数据。在MATLAB中,通常使用函数...

    概要设计说明书1.0——端茶倒水小组1

    3. 输出模块:解释中间代码,输出结果和错误信息。 这种模块化设计提高了内聚性和降低了耦合度。 **四、UI 设计** UI 设计关注用户体验,包括: 1. 样式原型:采用 HTML + CSS + Bootstrap + JavaScript 进行前端...

    基于PHP的disk 网盘源码 Mini GBK.zip

    【标题】"基于PHP的disk 网盘源码 Mini GBK.zip" 是一个使用PHP编程语言开发的轻量级网盘系统源代码,专为GBK编码环境设计。这个源码可能适合那些需要构建简单、小巧且易于部署的个人或企业云存储解决方案的开发者。...

    MiniProject_Verzeo

    - 代码单元格:可以执行Python代码,实时查看输出结果。 - 绘图与可视化:使用matplotlib、seaborn等库进行数据可视化,增强结果解释。 - 组织结构:利用ToC(Table of Contents)扩展实现Notebook的目录结构,...

    《动手学深度学习》安装GPU版Pytorch

    ### 《动手学深度学习》安装GPU版Pytorch #### 一、准备工作 在开始安装GPU版Pytorch...以上就是关于《动手学深度学习》中GPU版Pytorch的安装指南,希望能帮助大家顺利完成安装。如有疑问或遇到问题,欢迎留言反馈。

    WebpackCleanInitCode

    WebpackCleanInitCode是一个关于使用Webpack进行项目初始化并优化代码清理的实践。Webpack 是一个流行的模块打包工具,它能够将JavaScript、CSS、图片等资源转换、打包,并生成优化过的静态资源。在这个项目中,我们...

Global site tag (gtag.js) - Google Analytics