[JAVA] Sample to create custom tag for JSP

Since I sometimes created a custom tag for jsp, it is a sample rather than a memo. Please accept (´ ・ ω ・ `)

Let's start with the requirement definition! It's easy because it's a sample, but I've summarized it as follows.

--Display database search results as a pull-down --However, since it is a sample, the database is implemented as a mock. --The tag name is sample: select. It has group as a required attribute and uses this as a key to search the database.

Preparation: Create DB access layer and Servlet.

Since we want to create a custom tag that displays the DB search results, we will create a class that shows the access to the DB and the search results. We also need a Servlet to display jsp, so create this as well. The following is the sample code, but the __package declaration, import declaration, getter and setter are omitted because they are redundant. __ However, I would appreciate it if you could judge the package structure based on the image shown at the beginning (´ ・ ω ・ `).

image

DB.java


/**
 *Database access class. However, since it is a sample, it will be implemented as a mock.
 */
public class DB implements Serializable {    
    private List<Row> rows;
    
    /**
     *constructor. Create an instance and input initial data to the mock DB.
     */
    public DB() {
        this.rows = new ArrayList<>();
        
        this.rows.add(new Row("group1", "A", "AAA"));
        this.rows.add(new Row("group1", "B", "BBB"));
        this.rows.add(new Row("group1", "C", "CCC"));
        this.rows.add(new Row("group1", "D", "DDD"));
        this.rows.add(new Row("group1", "E", "EEE"));
        
        this.rows.add(new Row("group2", "a", "Ah ah"));
        this.rows.add(new Row("group2", "b", "Good"));
        this.rows.add(new Row("group2", "c", "Uuu"));
        this.rows.add(new Row("group2", "d", "Yeah yeah"));
        this.rows.add(new Row("group2", "e", "Oh oh"));
    }
    
    /**
     *Search the DB using group as a key.
     * @param group group column value
     * @return search results
     */
    public List<Row> select(String group) {
        return rows.stream()
                .filter(row -> row.getGroup().equals(group))
                .collect(Collectors.toList());
    }
}

Row.java


/**
 * com.sample.db.A bean class that indicates a row in the database indicated by the DB class.
 */
final public class Row implements Serializable {
    private String group;
    private String id;
    private String name;

    public Row(String group, String id, String name) {
        this.group = group;
        this.id = id;
        this.name = name;
    }
}

SampleServlet.java


/**
 * sample.Servlet for displaying jsp.
 */
@WebServlet("/sample")
public class SampleServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/sample.jsp");
        dispatcher.forward(request, response);
    }
}

Implement a tag handler.

Now that the prerequisites are in place, implement a tag handler, a Java class that corresponds to your custom tag. The tag handler is realized by implementing the interface javax.servlet.jsp.tagext.Tag, and the sample code is as follows.

Select.java


public class Select implements Tag {
    
    private Tag parent;
    private PageContext pageContext;
    private String group;
    
    @Override
    public int doStartTag() throws JspException {
        return Tag.SKIP_BODY; //This tag has no Body element.
    }
    
    @Override
    public int doEndTag() throws JspException {
        //Search DB based on group.
        DB db = new DB();
        List<Row> rows = db.select(this.group);
        
        //Dynamically generate select tag based on the search result to DB.
        String select = rows.stream().map(row -> {
            String id = row.getId();
            String name = row.getName();
            
            return String.format("<option value=\"%s\">%s</option>", id, name);
        }).collect(Collectors.joining("", "<select>", "</select>"));
        
        //Dynamically generate the generated select tag.
        try {
            JspWriter out = this.pageContext.getOut();
            out.print(select);
        } catch (IOException e) {
            throw new JspException(e);
        }
        
       return Tag.EVAL_PAGE; 
    }
    
    @Override
    public void release() {
    }
    
    @Override
    public Tag getParent() {
        return this.parent;
    }
    
    @Override
    public void setParent(Tag parent) {
        this.parent = parent;
    }
   
    @Override
    public void setPageContext(PageContext pageContext) {
        this.pageContext = pageContext;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }
}

In addition, there were the following two "fitting points" here.

--It is necessary to implement the fields corresponding to the attributes and Getter and Setter. --In the above sample, it will not work unless private String group; getGroup`` setGroup exists. --JSPWriter does not explicitly close.

Prepare the tld file.

Now that we have a tag handler that is a resident of the Java world, we need to connect the tag handler with a tag that is a resident of the jsp world. It is the tld file that sets this, and a sample is shown below. The extension is tld, but in reality it is in xml format.

sample.tld


<?xml version="1.0" encoding="UTF-8"?>

<taglib 
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
    version="2.0">

  <tlib-version>1.0</tlib-version>
  <short-name>sample</short-name>

  <tag>
    <name>select</name>
    <tag-class>com.sample.tag.Select</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <name>group</name>
        <required>true</required>
    </attribute>
  </tag>
</taglib>

Create and deploy a jsp file.

After that, create a jsp file using your own tag and deploy the application on the server.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="sample.tld" prefix="sample" %>

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Sample</title>
    </head>
    <body>
        <h1>JSP Sample</h1>
        <p><sample:select group="group1" /></p>
        <p><sample:select group="group2" /></p>
    </body>
</html>

Finally, when you access / jsp / sample with a web browser etc. to check the result, the web page represented by the following source code should be displayed.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Sample</title>
    </head>
    <body>
        <h1>JSP Sample</h1>
        <p>
            <select>
                <option value="A">AAA</option>
                <option value="B">BBB</option>
                <option value="C">CCC</option>
                <option value="D">DDD</option>
                <option value="E">EEE</option>
            </select>
        </p>
        <p>
            <select>
                <option value="a">Ah ah</option>
                <option value="b">Good</option>
                <option value="c">Uuu</option>
                <option value="d">Yeah yeah</option>
                <option value="e">Oh oh</option>
            </select>
        </p>
    </body>
</html>

End (`・ ω ・ ´) Shakin

Recommended Posts

Sample to create custom tag for JSP
Easy way to create JSP custom tags
Sample to create PDF from Excel with Ruby
How to create a database for H2 Database anywhere
How to create pagination for a "kaminari" array
[Rails] How to create a signed URL for CloudFront
[Spring Boot] How to create a project (for beginners)
[For beginners] Minimum sample to display RecyclerView in Java
[For those who create portfolios] How to use font-awesome-rails
How to execute WebCamCapture sample of NyARToolkit for Java
I want to create a generic annotation for a type
How to create docker-compose
Tutorial to create a blog with Rails for beginners Part 1
How to create a lightweight container image for Java apps
Sample to create GUI application with JavaFX + IntelliJ + Scene Builder
[For those who create portfolios] How to use chart kick
Sample to create one-time password on server side and client side
[For those who create portfolios] How to omit character strings
Tutorial to create a blog with Rails for beginners Part 2
How to create and launch a Dockerfile for Payara Micro
Tutorial to create a blog with Rails for beginners Part 0