Recently new company, browse the new company project, found that most of the JSP pages in the project are separate, complete pages, so many pages will have the following duplicate 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:setVar= "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 "><Htmlxmlns= "Http://www.w3.org/1999/xhtml"><Head><MetaHttp-equiv= "Content-type"Content= "text/html; Charset=utf-8 "/><Title>${webmodule.module.name}---xxxx</Title><MetaName= "keywords"Content= "XXXX"/><MetaName= "description"Content= "XXXX"/><LinkRel= "stylesheet"Href= "${ctx}/css/web-bbs.css"/><LinkRel= "stylesheet"Href= "${ctx}/css/page.css"/><ScriptType= "Text/javascript"Src= "${ctx}/js/jquery-1.7.2.min.js"></Script><ScriptType= "Text/javascript"Src= "${ctx}/js/bbs.js"></Script><ScriptType= "Text/javascript"Src= "${ctx}/js/webutil.js"></script>< Span style= "color: #0000ff;" ><script type= " Text/javascript " Src=" ${ctx}/js/index.js "></script> <script type= "text /javascript " Src=" ${ctx}/js/faces.js "></script>
Small partners Each new page, you need to copy a copy of the above code, but also in their respective pages to introduce the common Kinsoku files (such as header.jsp,footer.jsp) ...
For this kind of development, the duplication of work is not much described, the more important problem is that the future of this architecture will lead to more maintenance work, or even a bug.
Two "chestnuts":
- If we need to introduce and delete some common scripts (such as online customer service icons, GA analysis scripts, etc.) in the future development process, change the version of jquery, change the DOCTYPE type to HTML5 type, and so on. To accomplish a similar requirement we have to modify the JSP file one by one, and the workload is proportional to the number of JSP files in the project.
- The more troubling question is, for these global operations we can't guarantee that the code is in effect on all pages, Manual Check? Oh...
Solution Solutions
The above pull so much, in fact, the core problem is that all JSP pages are fighting each other, there is no unified public template to maintain some of the global information, so here is the introduction of our previous implementation scenario:
- Implement the JSP file template functionality, and let all pages introduce a common template.
- The public part information is maintained directly in the template, and the variable section defines placeholders in the template, which are then rewritten by the page to maintain the diversity of the different pages.
With the template will be able to write this page:
The benefits of this writing are obvious:
- First, the page structure at a glance, write the page no longer focus on the public part of the content, reduce the workload of many copy code, but also reduce the error rate
- Secondly, public styles, scripts and so on are introduced in the template, so as to facilitate uniform adjustment
The template content is probably like this:
Implementation principle
The implementation of the principle is very simple, the implementation of the template function is mainly two custom tags (custom label development steps are not spoken here)
Blocktag
This label is primarily used to define the appropriate module in the template file (which can be considered a placeholder), and the location of the label definition is replaced with the content of the page rewrite when the JSP page is rendered. The replacement reads content from the attribute of the request based on the label's Name property plus a specific prefix as the key value.
/*** Custom tags for placeholders in JSP templates * *@authorThe feather of the wind **/PublicClass BlocktagExtendsBodytagsupport {/*** Placeholder Module name*/PrivateString name;PrivateStaticFinalLong Serialversionuid = 1425068108614007667L; @OverridePublicint doStartTag ()Throwsjspexception{ReturnSuper. doStartTag (); } @OverridePublicint Doendtag ()Throwsjspexception {ServletRequest request =Pagecontext.getrequest ();//Default value in the block tag String defaultcontent = (getbodycontent () = =NULL)? "": Getbodycontent (). getString (); String bodycontent = (string) request.getattribute (overwritetag.prefix+name);//If the page does not override the module, the default content bodycontent = Stringutils.isempty (bodycontent) is displayed.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;}} Blocktag CodeOverwritetag
This label is primarily used to rewrite the corresponding module in the template on the final page, and the contents of the label are written to the attribute of the current request when the page is rendered, and the label has a required parameter Name property as the key value for the content. This name property must be the same as the name value of the block in the template that corresponds to the override.
/*** Custom tags for overriding specified placeholder content in a JSP template * * Rationale: * Add the Overwrite label content section to the attribute attribute of ServletRequest * in subsequent block tags through the property name Read it and render it to the final page * *@authorThe feather of the wind **/PublicClass OverwritetagExtendsBodytagsupport {PrivateStaticFinalLong Serialversionuid = 5901780136314677968L;//Prefix of module namePublicStaticFinal String PREFIX = "Jsptemplateblockname_";//Module namePrivateString name; @OverridePublicint doStartTag ()Throwsjspexception {//TODO auto-generated Method StubReturnSuper. doStartTag (); } @OverridePublicint Doendtag ()Throwsjspexception {ServletRequest request =Pagecontext.getrequest ();// tag content bodycontent bodycontent = Getbodycontent (); Request.setattribute (Prefix+name, Stringutils.trim (bodycontent.getstring ())); Span style= "color: #008000;" >// TODO auto-generated method stub return super.doendtag ();} public String GetName () { return name; public void SetName ( String name {this.name = name;}} Overwritetag CodeSummary and Development
- After all the pages are used templates, it is easy to control the project global style, script, because the blocking of many pages of public information, but also make daily page development more efficient and reduce error rate.
- JSP native does not support the template mechanism, but only a little bit of the use of two custom tags can be implemented template functionality, reducing a lot of duplication of effort. As a result, the pain points in the work process are often an opportunity for individuals to grow.
- I've only simply defined a base_ in the demo above template.jsp this template, but the actual scenario in which a site may have many layout styles of different types of pages, then a template obviously does not meet the diversity of layout requirements, then we can be graded template to define the template as a Base,common,channel three levels , the degree of abstraction from high to low, to achieve the inheritance of channel->common->base, different styles of the page only need to introduce the corresponding channel template can be, how to abstract also need to be treated according to the actual scene.
JSP Template inheritance function implementation