Custom Tags trong JSP



Một custom tag là một phần tử JSP được định nghĩa bởi người sử dụng. Khi một JSP page chứa một custom tag được phiên dịch thành một Servlet, thẻ này được biến đổi để hoạt động trên một đối tượng đã gọi một Tag Handler. Sau đó, Web container triệu hồi các hoạt động này khi Servlet của JSP page được thực thi.

Sự kế thừa của các JSP tag giúp bạn tạo các thẻ mới mà bạn có thể chèn một cách trực tiếp vào trong một JSP page, như khi bạn thực hiện với các thẻ có sẵn (built-in) trong các chương trước đã giới thiệu. JSP 2.0 Specification giới thiệu Simple Tag Handler để viết các Custom Tag này.

Để viết một custom tag, đơn giản bạn có thể kế thừa lớp SimpleTagSupport và ghi đè phương thức doTag(), tại đây bạn có thể đặt code của bạn để tạo content cho thẻ đó.

Tạo thẻ "Hello" trong JSP

Giả sử bạn muốn định nghĩa một custom tag tên là và bạn muốn sử dụng nó trong kiểu mà không có phần thân như sau:


Để tạo một Custom Tag trong JSP, đầu tiên bạn phải tạo một lớp Java mà hoạt động như là một Tag Handler. Vì thế, chúng ta tạo HelloTag class như sau:

package com.tutorialspoint;import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;public class HelloTag extends SimpleTagSupport {  public void doTag() throws JspException, IOException {
    JspWriter out = getJspContext().getOut();
    out.println("Hello Custom Tag!");
  }
}

Code trên có mã hóa đơn giản, với phương thức doTag() nhận đối tượng JspContext hiện tại bởi sử dụng phương thức getJspContext() và sử dụng nó để gửi "Hello Custom Tag!" tới đối tượng JspWriter hiện tại.

Biên dịch lớp trên và copy nó trong một thư mục có sẵn trong biến môi trường CLASSPATH. Cuối cùng, tạo file thư viện thẻ sau: webapps\ROOT\WEB-INF\custom.tld.


  1.0
  2.0
  Example TLD
  
    Hello
    com.tutorialspoint.HelloTag
    empty
  

Bây giờ là lúc sử dụng custom tag là Hello đã định nghĩa trên trong chương trình JSP như sau:

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>

  
    A sample custom tag
  
  
    
  

Thử gọi JSP trên và nó sẽ cho kết quả sau:

Hello Custom Tag!

Truy cập phần thân thẻ trong JSP

Bạn có thể bao một message trong phần thân của Custom Tags như khi bạn đã thấy với các thẻ chuẩn. Giả sử bạn muốn định nghĩa một custom tag với tên và bạn muốn sử dụng nó trong kiểu có một phần thân thẻ:


   This is message body

Chúng ta sửa đổi code trên một chút để xử lý phần thân cho thẻ:

package com.tutorialspoint;import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;public class HelloTag extends SimpleTagSupport {   StringWriter sw = new StringWriter();
   public void doTag()
      throws JspException, IOException
    {
       getJspBody().invoke(sw);
       getJspContext().getOut().println(sw.toString());
    }}

Trong trường hợp này, kết quả từ sự triệu hồi, đầu tiên được bắt vào trong một StringWriter trước khi được ghi tới JspWriter mà liên kết với thẻ đó. Bây giờ, theo đó, chúng ta cần thay đổi TLD file như sau:


  1.0
  2.0
  Example TLD with Body
  
    Hello
    com.tutorialspoint.HelloTag
    scriptless
  

Chúng ta gọi thẻ trên với phần thân chính xác như sau:

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>

  
    A sample custom tag
  
  
    
        This is message body
    
  

Nó sẽ cho kết quả:

This is message body

Thuộc tính của Custom Tag trong JSP

Bạn có thể sử dụng các thuộc tính đa dạng cùng với các thẻ custom tag của bạn. Để chấp nhận một giá trị thuộc tính, một lớp custom tag cần triển khai các phương thức setter, như phương thức setter trong JavaBeans như sau:

package com.tutorialspoint;import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;public class HelloTag extends SimpleTagSupport {   private String message;   public void setMessage(String msg) {
      this.message = msg;
   }   StringWriter sw = new StringWriter();   public void doTag()
      throws JspException, IOException
    {
       if (message != null) {
          /* Use message from attribute */
          JspWriter out = getJspContext().getOut();
          out.println( message );
       }
       else {
          /* use message from the body */
          getJspBody().invoke(sw);
          getJspContext().getOut().println(sw.toString());
       }
   }}

Tên của thuộc tính là "message", vì thể phương thức setter là setMessage(). Bây giờ chúng ta thêm thuộc tính này trong TLD file bởi sử dụng phần tử như sau:


  1.0
  2.0
  Example TLD with Body
  
    Hello
    com.tutorialspoint.HelloTag
    scriptless
    
       message
    
  

Thử JSP trên với thuộc tính message như sau:

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>

  
    A sample custom tag
  
  
    
  

Nó sẽ cho kết quả sau:

This is custom tag

Hy vọng ví dụ trên sẽ giúp ích cho bạn. Bạn nên ghi nhớ rằng bạn có thể bao các Property cho một thuộc tính:

Property Mục đích
namePhần tử name định nghĩa tên của một thuộc tính. Mỗi tên thuộc tính phải là duy nhất cho một thẻ cụ thể
requiredXác định nếu thuộc tính này được yêu cầu hoặc là tùy ý. Nó sẽ là false cho tùy ý
rtexprvalueKhai báo nếu một giá trị runtime expression cho một thuộc tính thẻ là hợp lệ
typeĐịnh nghĩa kiểu lớp Java cho thuộc tính này. Theo mặc định, nó được xem như là String
Miêu tảSự miêu tả có tính thông tin này có thể được cung cấp
fragmentKhai báo nếu giá trị thuộc tính này nên được đối xử như là một JspFragment.

Ví dụ sau xác định các Property liên quan tới một thuộc tính trong:

.....
    
      attribute_name
      false
      java.util.Date
      false
    
.....

Nếu bạn đang sử dụng hai thuộc tính, thì bạn có thể sửa đổi TLD như sau:

.....
    
      attribute_name1
      false
      java.util.Boolean
      false
    
    
      attribute_name2
      true
      java.util.Date
    
.....

Các bài học JSP khác tại VietJack: