In-depth analysis of JavaWeb Item23 -- Introduction to jsp custom tag Development

Source: Internet
Author: User
Tags return tag tld

In-depth analysis of JavaWeb Item23 -- Introduction to jsp custom tag Development
I. Role of custom tags

Custom tags are mainly used to remove java code from Jsp pages.

Ii. Development and Use of custom tags 2.1 custom tag development steps

   1. Compile a Java class (Tag Processor class) that implements the Tag interface)

To write a custom Tag, you must first implement a Tag interface class. However, Jsp already has a class that implements this interface. We need to implement one by ourselves.

Package me. gacl. web. tag; import java. io. IOException; import javax. servlet. http. httpServletRequest; import javax. servlet. jsp. jspException; import javax. servlet. jsp. jspWriter; import javax. servlet. jsp. pageContext; import javax. servlet. jsp. tagext. tag; public class ViewIPTag implements Tag {// receives the passed PageContext object private PageContext pageContext; @ Override public int doEndTag () throws JspException {System. out. println ("Call doEndTag () method"); return 0 ;}@ Override public int doStartTag () throws JspException {System. out. println ("Call doStartTag () method"); HttpServletRequest request = (HttpServletRequest) pageContext. getRequest (); JspWriter out = pageContext. getOut (); String ip = request. getRemoteAddr (); try {// The IOException out is thrown during output. write (ip);} catch (IOException e) {// catch IOException and throw new RuntimeException (e);} return 0 ;}@ Override public Tag getParent () {return null ;}@ Override public void release () {System. out. println ("Call the release () method") ;}@ Override public void setPageContext (PageContext pageContext) {System. out. println ("setPageContext (PageContext pageContext)"); this. pageContext = pageContext;} @ Override public void setParent (Tag arg0 ){}}

  2. Create a tld file in the WEB-INF/directory and describe the tag processor class in the tld File

  

Here, the label description can be copied to the example in the tomcat server example, and you can just copy the header and copy the ass. The code for the gacl. tld file is as follows:

 
           
   
    
Custom tag library developed by lone wolf
            
   
    
1.0
       
   
    
GaclTagLibrary
            
   
    
/Gacl
                  
           
    
     
This label is used to output the IP address of the client.
                     
    
     
ViewIP
                     
    
     
Me. gacl. web. tag. ViewIPTag
            
    
     
Empty
        
   
  
2.2 use custom tags on the Jsp page

  1. Use the "<% @ taglib uri =" uri of the tag library "prefix =" prefix "%>" command to introduce the tag library to be used.

For example, reference the gacl tag library in jspTag_Test1.jsp.

<%@ page language="java" pageEncoding="UTF-8"%> <%@taglib uri="/gacl"  prefix="xdp"%>
Your ip address is (get the output using java code): <% // use java code on the jsp page to obtain the Client ip address String ip = request. getRemoteAddr (); out. write (ip); %> Your IP address is (use custom tag to get output): <% -- use custom tag viewIP -- %>

The Running Effect of the tag is as follows:

  

You can see from the running effect that the java code on the jsp page can be removed by using the custom tag. If you need to output the Client IP address on the jsp page, use Tags can replace the code on the jsp page:

<% // Use java code on the jsp page to obtain the Client ip address String ip = request. getRemoteAddr (); out. write (ip); %>

This is the benefit of developing and using custom tags, so that java code is not nested on our Jsp page.

3. Execution Process of custom tags

When the JSP Engine encounters a custom tag, it first creates the Instance Object of the tag processor class, and then calls its method according to the communication rules defined in the JSP specification.
  
1,public void setPageContext(PageContext pc)After the JSP Engine instantiate the tag processor, it will call the setPageContext method to pass the pageContext object of the JSP page to the tag processor. The tag processor can then communicate with the JSP page through this pageContext object.

2、public void setParent(Tag t)After the setPageContext method is executed, the setParent method called by the WEB Container then passes the parent tag of the current tag to the current tag processor. If there is no parent tag for the current tag, the parameter value passed to the setParent method is null.

3、public int doStartTag()After the setPageContext method and setParent method are called, The doStartTag method of the tag processor is called when the WEB Container runs the start tag of the custom tag.

4、public int doEndTag()After the WEB Container executes the TAG body of the custom tag, it then executes the end tag of the custom tag. At this time, the WEB Container will call the doEndTag method of the tag processor.

5、public void release()Generally, after a WEB Container executes a custom tag, the tag processor will reside in the memory and be another request server until the web application is stopped, the web Container will call the release method.

The call diagram is as follows:


On the tomcat server"work\Catalina\localhost\JavaWeb_JspTag_study_20140816\org\apache\jsp"You can findjspTag_Test1.jspThe source code of the java after the Servlet is translated, as shown in:

OpenjspTag_005fTest1_jsp.javaFile, you can see the call sequence and process of the setPageContext (PageContext pc), setParent (Tag t), doStartTag (), doEndTag (), and release () methods.

The jspTag_005fTest1_jsp.java code is as follows:

Out. write ("your IP address is (get the output using java code): \ r \ n"); out. write (""); // use the java code on the jsp page to obtain the Client ip address String ip = request. getRemoteAddr (); out. write (ip); out. write ("\ r \ n"); out. write ("
\ R \ n "); out. write ("your IP address is (use custom tags to get output):"); if (_ jspx_meth_xdp_005fviewIP_005f0 (_ jspx_page_context) return; out. write ("\ r \ n"); out. write ("\ r \ n"); out. write ("\ r \ n");} catch (Throwable t) {if (! (T instanceof SkipPageException) {out = _ jspx_out; if (out! = Null & out. getBufferSize ()! = 0) try {out. clearBuffer ();} catch (java. io. IOException e) {} if (_ jspx_page_context! = Null) _ jspx_page_context.handlePageException (t) ;}} finally {_ jspxFactory. releasePageContext (_ jspx_page_context);} private boolean _ aggregate (PageContext _ jspx_page_context) throws Throwable {PageContext pageContext = _ jspx_page_context; JspWriter out = _ aggregate (); // xdp: viewIP me. gacl. web. tag. viewIPTag _ jspx_th_xdp_005fviewIP_005f0 = (me. gacl. web. tag. viewIPTag) _ 005fjspx_005ftagPool_005fxdp_005fviewIP_005fnobody.get (me. gacl. web. tag. viewIPTag. class); _ aggregate (_ jspx_page_context); _ aggregate (null); int _ jspx_eval_xdp_005fviewIP_005f0 = _ aggregate (); if (_ aggregate () = javax. servlet. jsp. tagext. tag. SKIP_PAGE) {_ partition (_ jspx_th_xdp_005fviewIP_005f0); return true ;}_ partition (_ jspx_th_xdp_005fviewIP_005f0); return false ;}}

The following focuses on the analysisprivate boolean _jspx_meth_xdp_005fviewIP_005f0(PageContext _jspx_page_context)Code in the Method

① Here is an object for instantiating a viewIP tag Processor class me. gacl. web. tag. ViewIPTag

//  xdp:viewIP     me.gacl.web.tag.ViewIPTag _jspx_th_xdp_005fviewIP_005f0 = (me.gacl.web.tag.ViewIPTag) _005fjspx_005ftagPool_005fxdp_005fviewIP_005fnobody.get(me.gacl.web.tag.ViewIPTag.class);

② After the tag processor is instantiated, call the setPageContext method to pass the pageContext object of the JSP page to the tag processor.

_jspx_th_xdp_005fviewIP_005f0.setPageContext(_jspx_page_context);

③ After the setPageContext method is executed, the setParent method is called to pass the parent tag of the current tag to the current tag processor. If there is no parent tag for the current tag, the parameter value passed to the setParent method is null.

 _jspx_th_xdp_005fviewIP_005f0.setParent(null);

④ After the setPageContext method and setParent method are called, The doStartTag method of the tag processor will be called when the WEB Container runs the start tag of the custom tag.

 int _jspx_eval_xdp_005fviewIP_005f0 = _jspx_th_xdp_005fviewIP_005f0.doStartTag();

⑤ After the WEB Container executes the TAG body of the custom tag, it then executes the end tag of the custom tag. At this time, the WEB Container will call the doEndTag method of the tag processor.

 if (_jspx_th_xdp_005fviewIP_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)

This is the execution process of custom labels.

Here is an entry-level case to explain the development of custom tags for javaweb.

Iv. API of custom tag Technology 4.1. API class inheritance relationship of tag Technology

  

V. Introduction to tag APIs 5.1 JspTag Interface

The JspTag interface is the parent interface of all custom tags. It is a newly defined tag interface in JSP2.0 and does not have any attributes or methods. The JspTag interface has two direct sub-interfaces: Tag and SimpleTag. In versions earlier than JSP2.0, only Tag interfaces are available. Therefore, custom tags that implement Tag interfaces are also called traditional tags, the custom tag that implements the SimpleTag interface is called a simple tag.

5.2 Tag Interface

The Tag interface is the parent interface of all traditional labels. It defines two important methods (doStartTag and doEndTag) and four constants (EVAL_BODY_INCLUDE,SKIP_BODY,EVAL_PAGE,SKIP_PAGE), The two methods and the four constants are used as follows:

(1) In the process of interpreting and executing JSP pages, WEB containers call the doStartTag method of the tag processor when starting a custom tag, after the doStartTag method is executed, a constant can be returned to the WEB container.EVAL_BODY_INCLUDEOrSKIP_BODY. If the doStartTag method returnsEVAL_BODY_INCLUDEThe WEB Container then executes the label body of the custom tag. If the doStartTag method returnsSKIP_BODYThe WEB Container will ignore the TAG body of the custom tag and directly explain the end tag of the custom tag.

(2) When the WEB Container interprets and runs the end tag of the custom tag, the doEndTag method of the tag processor is called. After the doEndTag method is executed, a constant can be returned to the WEB container.EVAL_PAGEOrSKIP_PAGE. If the doEndTag method returns a constantEVAL_PAGEThe WEB Container then executes the JSP code behind the end tag on the JSP page. If the doEndTag method returnsSKIP_PAGE, The WEB Container will ignore all content behind the ending mark in the JSP page.

The functions of doStartTag and doEndTag methods and return values show that when developing custom tags, You can compile appropriate Java program code in the doStartTag and doEndTag methods to implement specific functions, by controlling the return values of the doStartTag method and the doEndTag method, you can also tell the WEB Container whether to execute the label body in the custom tag and the content behind the end tag of the custom tag in the JSP page.

5.3 IterationTag Interface

  The IterationTag interface inherits the Tag interface, and adds a doAfterBody method andEVAL_BODY_AGAINConstant.The labels that implement the IterationTag interface can not only complete the functions that the Tag interface can accomplish, but also notify the WEB Container whether to repeatedly execute the Tag body content. For custom tags that implement the IterationTag interface, after the WEB Container executes the label body of the custom tag, it will call the doAfterBody method of the tag processor. The doAfterBody method can return constants to the WEB container.EVAL_BODY_AGAINOrSKIP_BODY. If the doAfterBody method returnsEVAL_BODY_AGAIN, The WEB Container will re-execute the label body content again, and then call the doAfterBody method after the execution, so that the constant is returned until the doAfterBody MethodSKIP_BODYThe WEB Container starts to process the end tag of the tag and calls the doEndTag method.

It can be seen that when developing custom tags, you can control the return value of the doAfterBody method to tell the WEB Container whether to repeatedly execute the TAG body content, so as to achieve the effect of loop processing of the TAG body content. For example, you can use a label that implements the IterationTag interface to iteratively output all elements in a set and specify the output format of the elements in the label body.

The jsp api also provides the default implementation class of the IterationTag interface.TagSupportWhen writing a tag processor class for a custom tag, We can inherit and extend the TagSupport class, which simplifies development compared to implementing the IterationTag interface.

5.4 BodyTag Interface

  The BodyTag interface inherits the IterationTag interface, and adds two methods (setBodyContent, doInitBody) and oneEVAL_BODY_BUFFEREDConstant.In addition to the IterationTag interface, the label that implements the BodyTag interface can also modify the content of the label body. For custom tags that implement the BodyTag interface, the doStartTag method of the tag processor can return not only the constants described aboveEVAL_BODY_INCLUDE orSKIP_BODYAnd can return constants.EVAL_BODY_BUFFERED. If the doStartTag method returnsEVAL_BODY_BUFFEREDThe WEB Container will create a BodyContent object dedicated to capturing the running results of the TAG body, and then call the setBodyContent method of the tag processor to pass the reference of the BodyContent object to the tag processor, the WEB Container then writes the execution result of the label body to the BodyContent object. In the subsequent event methods of the tag processor, you can obtain the execution result of the TAG body by referencing the previously saved BodyContent object, then, the BodyContent object's unique method is called to modify and control the content (that is, the execution result of the label body) in the BodyContent object.

The BodyTag interface implementation class is also provided in the jsp api.BodyTagSupportWhen writing a custom tag processor class that can modify the content of a TAG body, we can inherit and expand the BodyTagSupport class, which simplifies development compared to implementing the BodyTag interface.

5.5 SimpleTag Interface

SimpleTag interface is a new label interface in JSP2.0. Because traditional tags use three tag interfaces to accomplish different functions, they are too cumbersome and are not conducive to the promotion of tag technology. Therefore, SUN wants to reduce the difficulty of learning tag technology, JSP 2.0 defines a simpler and easier SimpleTag interface for writing and calling. The biggest difference between the SimpleTag interface and the traditional tag interface is that the SimpleTag interface only defines a doTag method used to process the tag logic. This method is called when a WEB Container executes a custom tag, it is called only once. Functions completed by using the traditional tag interface, such as whether to execute the TAG body, iterate the TAG body, and modify the TAG body content can be completed in the doTag method.

The SimpleTag interface implementation class is also provided in the jsp api.SimpleTagSupportWhen writing simple labels, We can inherit and extend the SimpleTagSupport class, which simplifies the development work compared to implementing the SimpleTag interface.

5.6 descriptions of the returned values of methods in the traditional tag Interface

Lists the main methods in the Tag interface, IterationTag interface, and BodyTag interface, as well as descriptions of the returned values.

  

6. Develop Traditional labels to implement page logic

When writing Jsp pages, developers often need to introduce some logic in the pages, such:

Controls whether to execute a part of the content on the jsp page. Determines whether the entire jsp page is executed. Control repeated execution of jsp page content.

Modify jsp page content output.

In addition to java code removed from the jsp page, the custom tag can also implement the preceding functions.

6.1 control whether a part of the jsp page is executed  

Write a class to implement the tag interface and control the return value of the doStartTag () method. If this method returnsEVAL_BODY_INCLUDE, The TAG body is executed. IfSKIP_BODY, The label body is not executed.

SUN provides a default implementation class for the tag interface.TagSupportThe TagSupport class implements all the tag interface methods, so we can write a class that inherits the TagSupport class and then override the doStartTag method.

The sample code is as follows:

TagDemo1.java

Package me. gacl. web. tag; import javax. servlet. jsp. jspException; import javax. servlet. jsp. tagext. tag; import javax. servlet. jsp. tagext. tagSupport;/*** @ author gacl * TagSupport class implements the Tag interface. TagDemo1 inherits the TagSupport class **/public class TagDemo1 extends TagSupport {/* override the doStartTag method, control whether the label body is executed * @ see javax. servlet. jsp. tagext. tagSupport # doStartTag () */@ Override public int doStartTag () throws JspException {// If EVAL_BODY_INCLUDE is returned for this method, the TAG body is executed. If SKIP_BODY is returned, the Tag body // return Tag is not executed. EVAL_BODY_INCLUDE; return Tag. SKIP_BODY ;}}

Add a description of the tag processing class to the tld file under the WEB-INF directory, as shown below:

 
           
   
    demo1
            
   
    me.gacl.web.tag.TagDemo1
                      
   
    JSP
    
  

Import and use custom tags on the jsp page as follows:

<% @ Page language = "java" pageEncoding = "UTF-8" %> <% -- import the custom tag library on the jsp page -- %> <% @ taglib uri = "/gacl "prefix =" gacl "%>
<% -- In the jsp page, the demo1 tag with the TAG body contains the strings "lone wolf" -- %> Lone Wolf

The running effect is as follows:

6.2. control whether the entire jsp page is executed

Write a class to implement the tag interface and control the return value of the doEndTag () method. If this method returnsEVAL_PAGETo execute the remaining jsp page of the tag.SKIP_PAGE, The remaining jsp is not executed.

The sample code is as follows:

TagDemo2.java

Package me. gacl. web. tag; import javax. servlet. jsp. jspException; import javax. servlet. jsp. tagext. tag; import javax. servlet. jsp. tagext. tagSupport;/*** @ author gacl * TagSupport class implements the Tag interface. TagDemo2 inherits the TagSupport class */public class TagDemo2 extends TagSupport {/* override the doEndTag method, control whether the jsp page is executed * @ see javax. servlet. jsp. tagext. tagSupport # doEndTag () */@ Override public int doEndTag () throws JspException {// if this method returns EVAL_PAGE, execute the remaining jsp page of the tag. If SKIP_PAGE is returned, the remaining jsp return Tag is not executed. SKIP_PAGE; // return Tag. EVAL_PAGE ;}}

Add a description of the tag processing class to the tld file under the WEB-INF directory, as shown below:

 
           
   
    demo2
            
   
    me.gacl.web.tag.TagDemo2
                      
   
    empty
    
  

Import and use custom tags on the jsp page as follows:

<% @ Page language = "java" pageEncoding = "UTF-8" %> <% -- import the custom tag library on the jsp page -- %> <% @ taglib uri = "/gacl "prefix =" gacl "%>
Jsp page content 1 <% -- Use the custom tag demo2 on the jsp page without the TAG body -- %> Jsp page content 2

The running effect is as follows:

 

6.3 Control repeated execution of jsp page content

Write a class to implement the Iterationtag interface to control the return value of the doAfterBody () method. If this method returnsEVAL_BODY_AGAINThe web server executes the TAG body again, and so on, until the doAfterBody method returnsSKIP_BODY.

The sample code is as follows:

TagDemo3.java

Package me. gacl. web. tag; import javax. servlet. jsp. jspException; import javax. servlet. jsp. tagext. iterationTag; import javax. servlet. jsp. tagext. tag; import javax. servlet. jsp. tagext. tagSupport; public class TagDemo3 extends TagSupport {int x = 5; @ Override public int doStartTag () throws JspException {return Tag. EVAL_BODY_INCLUDE;}/* controls the return value of the doAfterBody () method. * If this method returns EVAL_BODY_AGAIN, the web server executes the label body again, * According Wait until the doAfterBody method returns the SKIP_BODY, And the TAG body will not be repeated. * @ See javax. servlet. jsp. tagext. tagSupport # doAfterBody () */@ Override public int doAfterBody () throws JspException {x --; if (x> 0) {return IterationTag. EVAL_BODY_AGAIN;} else {return IterationTag. SKIP_BODY ;}}}

Add a description of the tag processing class to the tld file under the WEB-INF directory, as shown below:

 
           
   
    demo3
            
   
    me.gacl.web.tag.TagDemo3
                      
   
    JSP
    
  

Import and use custom tags on the jsp page as follows:

<% @ Page language = "java" pageEncoding = "UTF-8" %> <% -- import the custom tag library on the jsp page -- %> <% @ taglib uri = "/gacl "prefix =" gacl "%>
<% -- Use the custom tag demo3 tag on the jsp page -- %> Jsp page content

The running effect is as follows:

  

6.4 modify jsp page content output

Compile a class to implement the BodyTag interface and control the doStartTag () method to returnEVAL_BODY_BUFFEREDThe web server will create a BodyContent object to capture the label body, and then obtain the bodyContent object representing the label body in the doEndTag () method body, so that you can modify the label body.

SUN provides a default implementation class for the BodyTag interface.BodyTagSupportThe BodyTagSupport class implements all methods of the BodyTag interface. Therefore, we can write a class that inherits the BodyTagSupport class, and then rewrite the doStartTag and doEndTag () methods as needed.

The sample code is as follows:

TagDemo4.java

Package me. gacl. web. tag; import java. io. IOException; import javax. servlet. jsp. jspException; import javax. servlet. jsp. tagext. bodyContent; import javax. servlet. jsp. tagext. bodyTag; import javax. servlet. jsp. tagext. bodyTagSupport; import javax. servlet. jsp. tagext. tag;/*** @ author gacl * BodyTagSupport class implements the BodyTag interface. TagDemo4 inherits the BodyTagSupport class */public class TagDemo4 extends BodyTagSupport {/* controls doStartTag () method returns EVAL_BODY_BUFFERED * @ see javax. servlet. jsp. tagext. bodyTagSupport # doStartTag () */@ Override public int doStartTag () throws JspException {return BodyTag. EVAL_BODY_BUFFERED;} @ Override public int doEndTag () throws JspException {// this. getBodyContent () gets the bodyContent object BodyContent bodyContent = this. getBodyContent (); // get the TAG body String content = bodyContent. getString (); // modify the content in the TAG body and convert the content of the TAG body into a String result = content. toUpperCase (); try {// output the modified content this. pageContext. getOut (). write (result);} catch (IOException e) {throw new RuntimeException (e);} return Tag. EVAL_PAGE ;}}

Add a description of the tag processing class to the tld file under the WEB-INF directory, as shown below:

 
           
   
    demo4
            
   
    me.gacl.web.tag.TagDemo4
                      
   
    JSP
    
  

Import and use custom tags on the jsp page as follows:

<% @ Page language = "java" pageEncoding = "UTF-8" %> <% -- import the custom tag library on the jsp page -- %> <% @ taglib uri = "/gacl "prefix =" gacl "%>
<% -- Use the custom tag demo4 tag on the jsp page -- %> Xdp_gacl

The running effect is as follows:

  

VII. Summary of jsp traditional tag Development

In the current jsp tag development, traditional tags are rarely directly used for development. Currently, most of them are simple tags, so you can understand the traditional Jsp tag development!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.