标签:
最近刚入职新公司,浏览一下新公司项目,发现项目中大多数JSP页面都是独立的、完整的页面,因此许多页面都会有如下重复的代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.Calendar" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="/common-tags" prefix="m"%>
<c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>${webModule.module.name} ---xxxx</title>
<meta name="keywords" content="xxxx"/>
<meta name="description" content="xxxx"/>
<link rel="stylesheet" href="${ctx}/css/web-bbs.css"/>
<link rel="stylesheet" href="${ctx}/css/page.css"/>
<script type="text/javascript" src="${ctx}/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="${ctx}/js/bbs.js"></script>
<script type="text/javascript" src="${ctx}/js/webUtil.js"></script>
<script type="text/javascript" src="${ctx}/js/index.js"></script>
<script type="text/javascript" src="${ctx}/js/faces.js"></script>
小伙伴们每新添加一个页面,就需要copy一份上面这坨代码,还需要在各自页面重复引入公共的头尾文件(如header.jsp,footer.jsp等)。。。
对于这种开发方式,重复的工作量就不多描述了,更重要的问题是这种架构方式未来会导致更多的维护工作量、甚至是bug隐患。
举两个“栗子”:
上面扯了那么多,其实核心问题就是所有的jsp页面都是各自为战,没有一个统一的公共的模板来维护一些全局的信息,所以这里就介绍一下我们以前的实现方案:
有了模板以后就可以这样写页面了:
这样的写法好处显而易见:
模板内容大概是这个样子的:
实现原理其实很简单,模板功能的实现主要是两个自定义标签(自定义标签的开发步骤这里就不讲了)
该标签主要用于在模板文件中定义相应的模块(可以看做一个占位符),在渲染JSP页面时会将标签定义的位置替换为页面重写的内容,替换时根据标签的name属性加上特定的前缀作为key值从request的attribute中读取内容。
/**
* 自定义标签,用于在Jsp模板中占位
*
* @author 逆风之羽
*
*/
public class BlockTag extends BodyTagSupport {
/**
* 占位模块名称
*/
private String name;
private static final long serialVersionUID = 1425068108614007667L;
@Override
public int doStartTag() throws JspException{
return super.doStartTag();
}
@Override
public int doEndTag() throws JspException {
ServletRequest request = pageContext.getRequest();
//block标签中的默认值
String defaultContent = (getBodyContent() == null)?"":getBodyContent().getString();
String bodyContent = (String) request.getAttribute(OverwriteTag.PREFIX+ name);
//如果页面没有重写该模块则显示默认内容
bodyContent = StringUtils.isEmpty(bodyContent)?defaultContent:bodyContent;
try {
pageContext.getOut().write(bodyContent);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
return super.doEndTag();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
该标签主要用于在最终的页面上重写模板中的相应模块,在页面渲染时将标签内部的内容写入到当前request的attribute中,该标签有一个必填参数name属性作为该内容的key值,这个name属性必须要和模板中对应要重写的block的name值相同。
/**
* 自定义标签,用于在jsp模板中重写指定的占位内容
*
* 基本原理:
* 将overwrite标签内容部分添加到ServletRequest的attribute属性中
* 在后续block标签中再通过属性名读取出来,将其渲染到最终的页面上即可
*
* @author 逆风之羽
*
*/
public class OverwriteTag extends BodyTagSupport {
private static final long serialVersionUID = 5901780136314677968L;
//模块名的前缀
public static final String PREFIX = "JspTemplateBlockName_";
//模块名
private String name;
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return super.doStartTag();
}
@Override
public int doEndTag() throws JspException {
ServletRequest request = pageContext.getRequest();
//标签内容
BodyContent bodyContent = getBodyContent();
request.setAttribute(PREFIX+name, StringUtils.trim(bodyContent.getString()));
// TODO Auto-generated method stub
return super.doEndTag();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
标签:
原文地址:http://www.cnblogs.com/firstdream/p/5475184.html