Home > Article > Web Front-end > JSP template inheritance function implementation_html/css_WEB-ITnose
Background
I just joined a new company recently. I browsed the new company’s projects and found that most of the JSP pages in the project are independent and complete pages, so many pages will have the following repeated code:
<%@ 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>
Every time you add a new page, you need to copy the above code, and you also need to repeatedly introduce public header and tail files (such as header.jsp, footer.jsp, etc.). . .
For this development method, the repetitive workload will not be described in detail. The more important issue is that this architectural method will lead to more maintenance workload and even bug risks in the future.
Cite two "chestnuts":
There is so much mentioned above, but the core problem is that all jsp pages work independently, and there is no unified common template to maintain some global information, so I will introduce it here. Let’s take a look at our previous implementation plan:
After you have the template, you can write the page like this:
The benefits of this writing method are obvious:
The template content probably looks like this:
Implementation principle
The implementation principle is actually very simple. The implementation of the template function is mainly two custom tags (custom tag development steps I won’t go into it here)
This tag is mainly used to define the corresponding module in the template file (can be regarded as a placeholder). When rendering the JSP page, the tag will be The defined position is replaced with the rewritten content of the page. When replacing, the content is read from the attribute of the request based on the name attribute of the tag plus a specific prefix as the key value.
/** * 自定义标签,用于在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; }}
This tag is mainly used to rewrite the corresponding module in the template on the final page when the page is rendered. Write the content inside the tag to the attribute of the current request. The tag has a required parameter name attribute as the key value of the content. This name attribute must be the same as the name value of the corresponding block to be rewritten in the template.
/** * 自定义标签,用于在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; } }Summary and Expansion