Home  >  Article  >  Web Front-end  >  JSP template inheritance function implementation_html/css_WEB-ITnose

JSP template inheritance function implementation_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:42:271126browse

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":

  • If we need to globally introduce or delete some public scripts (such as online customer service icons, GA analysis scripts, etc.) in the future development process, change the jQuery version and change DocType type is Html5 type and so on. To complete similar requirements, we must modify JSP files one by one, and the workload will be proportional to the number of JSP files in the project.
  • The more troublesome problem is that for the above global operations, we cannot guarantee whether the code is effective on all pages. Manual inspection? Haha...
  • Solution

    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:

    1. Implement the template function of JSP files and introduce a common template to all pages.
    2. The public part information is maintained directly in the template, and the variable part defines placeholders in the template, and is then rewritten by the page to maintain the diversity of different pages.

    After you have the template, you can write the page like this:

    The benefits of this writing method are obvious:

  • First of all, the page structure is clear at a glance. When writing a page, you no longer need to pay attention to the public parts other than the content, which reduces the workload of copying a lot of codes and also reduces the error rate
  • Secondly, public styles, scripts, etc. are introduced in the template, which facilitates unified adjustment
  • 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)

    BlockTag

    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;    }}

    OverwriteTag

    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
    1. After all pages use templates, you can easily control the global styles and scripts of the project. Due to blocking It also captures a lot of page public information, making daily page development more efficient and reducing error rates.
    2. JSP natively does not support the template mechanism, but the template function can be realized by using two custom tags with just a few tricks, reducing a lot of repetitive work. Therefore, pain points in the work process are often also opportunities for personal growth.
    3. In the demo above, I simply defined a base_template.jsp template. However, in actual scenarios, a website may have many pages with different layout styles, so one template obviously cannot meet the diverse layout requirements. , then we can grade the template and define the template as three levels: base, common, and channel. The abstraction level is from high to low to realize the inheritance relationship of channel->common->base. Pages of different styles only need Just introduce the corresponding channel template. The specific abstraction needs to be treated differently according to the actual scenario.

    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn