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à <ex:Hello> và bạn muốn sử dụng nó trong kiểu mà không có phần thân như sau:

<ex:Hello />

Để 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: <Tomcat-Installation-Directory>webapps\ROOT\WEB-INF\custom.tld.

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD</short-name>
  <tag>
    <name>Hello</name>
    <tag-class>com.tutorialspoint.HelloTag</tag-class>
    <body-content>empty</body-content>
  </tag>
</taglib>
Quảng cáo

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"%>
<html>
  <head>
    <title>A sample custom tag</title>
  </head>
  <body>
    <ex:Hello/>
  </body>
</html>

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 <ex:Hello> và bạn muốn sử dụng nó trong kiểu có một phần thân thẻ:

<ex:Hello>
   This is message body
</ex:Hello>

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

}
Quảng cáo

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:

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD with Body</short-name>
  <tag>
    <name>Hello</name>
    <tag-class>com.tutorialspoint.HelloTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>
</taglib>

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"%>
<html>
  <head>
    <title>A sample custom tag</title>
  </head>
  <body>
    <ex:Hello>
        This is message body
    </ex:Hello>
  </body>
</html>

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ử <attribute> như sau:

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD with Body</short-name>
  <tag>
    <name>Hello</name>
    <tag-class>com.tutorialspoint.HelloTag</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
       <name>message</name>
    </attribute>
  </tag>
</taglib>

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

<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
  <head>
    <title>A sample custom tag</title>
  </head>
  <body>
    <ex:Hello message="This is custom tag" />
  </body>
</html>

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>attribute_name</name>
      <required>false</required>
      <type>java.util.Date</type>
      <fragment>false</fragment>
    </attribute>
.....

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>
      <name>attribute_name1</name>
      <required>false</required>
      <type>java.util.Boolean</type>
      <fragment>false</fragment>
    </attribute>
    <attribute>
      <name>attribute_name2</name>
      <required>true</required>
      <type>java.util.Date</type>
    </attribute>
.....

Đã có app VietJack trên điện thoại, giải bài tập SGK, SBT Soạn văn, Văn mẫu, Thi online, Bài giảng....miễn phí. Tải ngay ứng dụng trên Android và iOS.

Theo dõi chúng tôi miễn phí trên mạng xã hội facebook và youtube:

Các bạn có thể mua thêm khóa học JAVA CORE ONLINE VÀ ỨNG DỤNG cực hay, giúp các bạn vượt qua các dự án trên trường và đi thực tập Java. Khóa học có giá chỉ 300K, nhằm ưu đãi, tạo điều kiện cho sinh viên cho thể mua khóa học.

Nội dung khóa học gồm 16 chuơng và 100 video cực hay, học trực tiếp tại https://www.udemy.com/tu-tin-di-lam-voi-kien-thuc-ve-java-core-toan-tap/ Bạn nào có nhu cầu mua, inbox trực tiếp a Tuyền, cựu sinh viên Bách Khoa K53, fb: https://www.facebook.com/tuyen.vietjack

Follow facebook cá nhân Nguyễn Thanh Tuyền https://www.facebook.com/tuyen.vietjack để tiếp tục theo dõi các loạt bài mới nhất về Java,C,C++,Javascript,HTML,Python,Database,Mobile.... mới nhất của chúng tôi.

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




Tài liệu giáo viên