您的位置:首页 > Web前端 > CSS

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

2016-03-03 17:41 579 查看
网站中大部分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>


五、效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: