java EE js css 加载及版本集中管理器

网站中大部分js css有重复的引用代码,生产环境中需要对新的js css版本做更新,此管理器实现了

1. js css 引用统一配置

2. 可方便地更新版本号

3. 引用路径支持相对路径、单一绝对路径、多域名绝对路径、是否使用.min格式


一、自定义控件

 
 
public class JavascriptLoader extends BodyTagSupport {

	private static final long serialVersionUID = 1L;

	/**
	 * 控件参数1:用于匹配xxxLoader.xml中的定义
	 */
	private String pageName;
	/**
	 * 控件参数2:用于指定处理类型:js css
	 */
	private String fileType = "js";

	// 以下变量会有变化,用于适用css js不同的处理类型 begin
	private  String loaderXmlPathDef = "/WEB-INF/JavascriptLoader.xml";// xxxLoader.xml具体文件名
	private String urlAttr = "src";
	private String fullUrl1 = "<script type='text/javascript' src=\"{1}/{0}\"></script>";
	private String fullUrl2 = "<script type='text/javascript' src=\"{0}{1}\"></script>";
	private String fullUrl3 = "<script type='text/javascript' src=\"{1}/{0}\"></script>";
	private String fullUrl4 = "<script type='text/javascript' src=\"{0}\"></script>";
	private String jsRoot = "/" + fileType;// js文件所属目录,开头加/
	private String minFileRoot = fileType + "/min";// js压缩后文件所属目录,开头不加/
	private String minFileName = "{0}_min_{1}." + fileType;// outputType=3时生成压缩文件名
	private String minFileString = "{0}/{1}/{2}_min_{3}." + fileType;// outputType=3时生成压缩文件完整路径,存放在minFileRoot对应目录下
	private String tempFileString = "{0}/{1}/{2}_temp_{3}." + fileType;// outputType=3时生成临时合并文件文件格式,存放在minFileRoot对应目录下
	private String deletedFilePattern = "{0}_min_\\d+." + fileType;// 需清除的旧的合并压缩文件的匹配正则表达式
	private String commonEle = "script";

	// end

	public JavascriptLoader() {
	}

	/**
	 * 当前是否JS处理模式
	 * 
	 * @return
	 */
	private boolean forJS() {

		return (fileType == null || fileType.length() == 0 || fileType .equals( "js"));
	}

	@Override
	public int doEndTag() throws JspException {

		return super.doEndTag();
	}

	@Override
	public int doStartTag() throws JspException {

		// 如果fileType为空,则默认当前为JS输出模式,否则为CSS输出模式
		if (!forJS()) {

			loaderXmlPathDef = "/WEB-INF/CSSLoader.xml";
			urlAttr = "href";
			fullUrl1 = "<link href=\"{1}/{0}\" rel='stylesheet' type='text/css' />";
			fullUrl2 = "<link href=\"{0}{1}\" rel='stylesheet' type='text/css' />";
			fullUrl3 = "<link href=\"{1}/{0}\" rel='stylesheet' type='text/css' />";
			fullUrl4 = "<link href=\"{0}\" rel='stylesheet' type='text/css' />";
			jsRoot = "/" + fileType;
			minFileRoot = fileType + "/min";
			minFileName = "{0}_min_{1}." + fileType;
			minFileString = "{0}/{1}/{2}_min_{3}." + fileType;
			tempFileString = "{0}/{1}/{2}_temp_{3}." + fileType;
			deletedFilePattern = "{0}_min_\\d+." + fileType;
			commonEle = "link";
		}

		// web根目录的资源管理器路径
		String dirPath = this.pageContext.getServletContext().getRealPath("/");
		// web根目录的站点根路径
		String urlPath = this.pageContext.getServletContext().getContextPath();
		// 配置文件位置
		String loaderXmlPath = dirPath + loaderXmlPathDef;// getClass().getClassLoader().getResource("JavascriptLoader.xml").getPath();

		// 读取web.xml中的MergeAndCompress,判断是否所有资源按outputType=1的形式输出
		String mergeAndCompress = this.pageContext.getServletContext()
				.getInitParameter("MergeAndCompress");
		String useMinJsCss = this.pageContext.getServletContext()
				.getInitParameter("UseMinJsCss");
		// 配置文件读取,所有CSS JS各一个文件
		 
		Document doc = LoaderTagSupport.getMessage(loaderXmlPath, fileType);
		Element root = XmlParser.getRootNode(doc);
		// 读取common节点 
		java.util.List<Element> commonList = XmlParser.getChildElements(root,
				"common/" + commonEle);
		 
		Map<String, CommonScript> commonMap = new HashMap<String, CommonScript>();
		if (commonList != null) {
			for (Element common : commonList) {
				Attribute outputTypeAttr = XmlParser.getAttribute(common,
						"outputType");
				String name = XmlParser.getAttribute(common, "name").getText();
				commonMap.put(
						name,
						new CommonScript(name, XmlParser.getAttribute(common,
								urlAttr).getText(),
								outputTypeAttr == null ? null : outputTypeAttr
										.getText()));

			}
		}

		// 读取server节点
		java.util.List<Element> serverEleList = XmlParser.getChildElements(
				root, "servers/server");
		List<String> serverList = new ArrayList<String>();
		if (serverEleList != null) {
			for (Element server : serverEleList) {
				serverList.add(server.getText());
			}
		}  
		// 读配置文件对应page节点
		Element page =(Element)  XmlParser.getSingleNode(root, "page[@name='"
				+ pageName + "']");
		// page节点的所有子集,对于JS对于script节点,对于css对于link节点
		List<Element> srcriptList  =null;
		if(page!=null)
			srcriptList = XmlParser.getChildList(page);
		else {
			srcriptList=new ArrayList<Element>();
		}
		// 判断outputType,根据outputType存入不同集合
		List<String> outTypeList1 = new ArrayList<String>();
		List<String> outTypeList2 = new ArrayList<String>();
		List<String> outTypeList3 = new ArrayList<String>();
		 
		
     	//加入group公共组,开始
		//由于group功能是后期加入的,不想对javascriptloader.xml做大修改,所以暂时只对cssloader.xml有效
		if(!forJS()){
			Element groups = XmlParser.getChild(root,"groups");
			List<Element> groupList = XmlParser.getChildList(groups);
			@SuppressWarnings("unchecked")
			
			//取出page的groupid
			org.dom4j.Attribute groupid = XmlParser.getAttribute(page, "groupid");
			 if(groups!=null  && groupList.size() >0  ){
				 //未配置groupid,使用默认group或第一个group 
				 if(groupid==null   ){
					 Element defaultEle  = (Element) XmlParser.getSingleNode(groups,"group[@default='true']"); 
					 if(defaultEle==null  )
						 defaultEle =  groupList.get(0);
					 srcriptList.addAll(0,XmlParser.getChildList(defaultEle));
				 }
				 else{
					 //已配置groupid,则找到对应group加入到scriptlist
					 Element groupEle  = (Element) XmlParser.getSingleNode(groups,"group[@id='"+ groupid.getText() +"']");
					 if(groupEle!=null)
						 srcriptList.addAll(0,XmlParser.getChildList(groupEle));
				 }
			}
		}
		//加入group公共组,结束
		
 	  
		// 当前page的所有script
		for (Element script : srcriptList) {
			
		  
			org.dom4j.Attribute outputType = XmlParser.getAttribute(script,
					"outputType");
			String curOutputType = outputType==null?null:outputType.getText();
			// 判断script是否存在ref
			org.dom4j.Attribute ref = XmlParser.getAttribute(script, "ref");
			// 存在ref
			String src;
			if (ref != null) {
				CommonScript commonScript = commonMap.get(ref.getText());
				src = commonScript.getSrc();
				if(curOutputType==null && commonScript.getOutputType()!=null)
					curOutputType = commonScript.getOutputType();
			} else {
				src = XmlParser.getAttribute(script, urlAttr).getText();
			}
			if(!StringHelp.IsNullOrEmpty(useMinJsCss) &&  useMinJsCss.equals("true") &&  !StringHelp.IsNullOrEmpty(src) && !src.startsWith("http") && !src.contains(".min")){
				src = src.replace("."+fileType, ".min."+fileType );
			}
			// 按照xml的outputtype指定输出,用于生产环境
			if (mergeAndCompress.equals("true")) {
				// 如果未指定outputtype,则默认outputtype=2
				if (curOutputType == null) {
					outTypeList2.add(src);
				} else {
					switch (curOutputType) {
					case "1":
						outTypeList1.add(src);
						break;
					case "2":
						outTypeList2.add(src);
						break;
					case "3":
						outTypeList3.add(src);
						break;
					}
				}

			} else {
				// 不按照xml指定的outputtype输出,而是全部原样输出,用于测试环境
				outTypeList1.add(src);
			}
		}
		 
		// outputType=1的处理,原样输出
		for (String src : outTypeList1) {
			// Long lastModified = LoaderTagSupport.getLastModified(src);
			if (src == null)
				continue;
			String scriptString = src.startsWith("http") ? MessageFormat
					.format(fullUrl4, src) : MessageFormat.format(fullUrl1,
					src, urlPath);
			try {
				this.pageContext.getOut().println(scriptString);
			} catch (IOException e) {

				e.printStackTrace();
			}
		}
		// outputType=2的处理,每个js随机服务器地址输出
		for (String src : outTypeList2) {
			// Long lastModified = LoaderTagSupport.getLastModified(src);
			String scriptString = MessageFormat.format(fullUrl2,
					LoaderTagSupport.RandomJSAbsoluteUrl(serverList), src);
			try {
				this.pageContext.getOut().println(scriptString);
			} catch (IOException e) {

				e.printStackTrace();
			}
		}
		// outputType=3的处理  基本没用过,略
		 

		return super.doStartTag();
	}

	/**
	 * 指定页面代号以获取相关配置
	 * 
	 * @return
	 */
	public String getPageName() {
		return pageName;
	}

	public void setPageName(String pageName) {
		this.pageName = pageName;
	}

	public String getFileType() {
		return fileType;
	}

	public void setFileType(String fileType) {
		this.fileType = fileType;
	}

}

二、jsp引用js配置文件

<?xml version="1.0" encoding="UTF-8"?>
<root>

	 

	<!-- 定义随机地址列表,也可删除,只有 MergeAndCompress=true 且 outputType=2时才会起作用 -->
	<servers>
		<server>http://js1.domain.com/</server>
		<server>http://js2.domain.com/</server>
		<server>http://js3.domain.com/</server>
	</servers>

 
	<common>
		 
		<script src="js/JsRender.js" name="jsrender"></script>
		<script src="js/jquery-1.10.2.min.js" name="jquery"></script>
		<script src="js/jquery.validate.1.14.001.js" name="jqvalidate"></script>
		<script src="js/selectArea.js?v=0004" name="selectArea"></script>
		<script src="js/mobileBUGFix.mini.js" name="mobilebf"></script>
		<script src="js/jquery.blockUI.js" name="blockui"></script>
	</common>
 

	<!-- 注意, 不指定 outputType,则等效于 outputType=2,所以一般都不需指定 -->

	<page name="demo_beginform">

		<script ref="jquery"></script>
		<script ref="jqvalidate"></script>
		<script ref="jsrender"></script>
		<script src="js/selectArea.js?v=0003"></script>
		<script ref="mobilebf"></script>
		<script src="js/qst.js"></script>
		<script src="js/uploadImg.js"></script>
		<script ref="blockui"></script>
		 
	</page>
 

	<page name="test">
		<script ref="jquery"></script>
		<script ref="jsrender"></script>
		<script src="js/selectArea.js?v=20160105"></script>
		<script ref="jweixin"></script>
		<script ref="wxsdk"></script>
	</page>
	<!-- 测试 end -->

	 

</root>


三、 jsp引用css配置文件

<?xml version="1.0" encoding="UTF-8"?>
<root>

	 

	<servers>


		<server>http://css1.domain.com/</server>
		<server>http://css2.domain.com/</server>
		<server>http://css3.domain.com/</server>

	</servers>

	<common>
		<link href="css/citycss.css?v=0015" name="citycss" />
		<link href="css/base.css?v=0015" type="text/css" name="mt_base" />
	</common>
	
	
	<!-- 会默认为每个jsp添加的css引用,默认为page加载第一个或default="true"的group 。可以在 page 节点指定 groupid="1"匹配对应group,或指定 
	groupid="none"不加载group,未匹配page节点的jsp页,也会加载 group[@default="true"]
	 -->
	<groups>
		<group default="true" id="1">
			<link ref="mt_base" />
			<link ref="citycss" />
		</group>
	  
	</groups>
 

	<page name="test">
		<link href="css/wap_indexokwei.css?v=20160105" />
	</page>
	 
	 
	
</root>


四、jsp中加入相关代码

<custom:JsLoaderTag pageName="beginform"></custom:JsLoaderTag>
<custom:JsLoaderTag pageName="beginform" fileType="css"></custom:JsLoaderTag>

五、效果




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值