JSP自定义标签(三)自定义日期选择标签

这篇博客,我想利用前面两篇JSP标签的内容实现一个可以选择日期的自定义标签。这篇博客会用到WdatePicker.js插件,这是一个日期选择器。本篇博客主要是想利用前面两篇博客的内容实现一些能用上的自定义标签。关于WdatePicker.js的使用不会多说,重点还是自定义标签。
首先看一下最终的结果是个什么样子:
这里写图片描述
通过自定义标签生成一个输入框,单击这个输入框则会调用WdatePicker.js让用户选择日期。
这个实现还是很简单,直接给代码,在代码中说明一下,需要注意的事项。
标签处理器:

package myTag;

import java.io.IOException;

import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTagSupport;


/** 继承了SimpleTagSupport的全部方法 */
public class DateTag extends SimpleTagSupport {

    private String dateValue;  //值
    private String format;     //日期
    private String id;         //输入框的ID



    public String getDateValue() {
        return dateValue;
    }
    public void setDateValue(String dateValue) {
        System.out.println("得到的值:" + dateValue);
        this.dateValue = dateValue;
    }


    public String getFormat() {
        return format;
    }
    public void setFormat(String format) {
        System.out.println("得到的格式:" + format);
        this.format = format;
    }


    public String getId() {
        return id;
    }
    public void setId(String id) {
        System.out.println("得到的ID:" + id);
        this.id = id;
    }

    /** 主要的方法,绘制标签会调用 */
    @Override
    public void doTag() throws JspException, IOException {
        /* 输出JspWriter */
        JspWriter out = getJspContext().getOut();
        try {
            String html = "<input type='text' id='" + getId()  + "' class='css' onclick=\"showWdatePicker(\'" + getId() + "','" + getFormat() + "')\" ";
            if(getDateValue() != null && !"".equals(getDateValue())) {
                html += " value='" + getDateValue() + "' />";
            } else {
                html += "' />";
            }
            System.out.println(html);
            out.println(html);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    /** JspContext的setter,getter方法,
     * 容器在处理JSP页面的中自定义标签时会调用标签处理器(本类),
     * 这个时候容器会把页面的JspContext传递个标签处理器,就是通过这个方法
     * 得到JspContext最主要的是要得到JspWriter
     * 一般会把容器传递进来的JspContext保存在一个变量中,(本类没有显示这个变量,因为在定义在SimpleTagSupport类中,直接使用就可以了)
     *  */
    @Override
    protected JspContext getJspContext() {
        return super.getJspContext();
    }
    @Override
    public void setJspContext(JspContext pc) {
        super.setJspContext(pc);
    }

    /** JspFragment的setter, getter方法
     * 如果标签存在主体,则容器在调用这个标签处理器的时候,会调用setJspBody()方法,将主体传递给标签处理器
     * 同样建议使用变量保存起来,SimpleTagSupport类中存在这个变量:jspBody
     * */
    @Override
    protected JspFragment getJspBody() {
        return super.getJspBody();
    }
    @Override
    public void setJspBody(JspFragment jspBody) {
        super.setJspBody(jspBody);
    }

    /** Parent的setter,getter方法,如果当前标签在另一个标签之中
     * 则容器在处理该标签的时候会把父标签传递及哪里,SimpleTagSupport的:parentTag会保存这个变量
     *  */
    @Override
    public JspTag getParent() {
        return super.getParent();
    }
    @Override
    public void setParent(JspTag parent) {
        super.setParent(parent);
    }


}


tld文件:

    <tag>
        <name>dateTag</name>
        <tag-class>myTag.DateTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>id</name>
            <required>true</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>format</name>
            <required>true</required>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>dateValue</name>
            <rtexprvalue>true</rtexprvalue>
            <type>java.lang.Date</type>
        </attribute>
    </tag>

jsp:

<%@ taglib uri="/WEB-INF/mytags.tld" prefix="easy" %>
<%@ page isELIgnored="false" %> 
<%@ page contentType="text/html;charset=UTF-8" language="java"  pageEncoding="UTF-8"  %>

<%
    String ctx = request.getContextPath();
    request.getSession().setAttribute("dateValue", "2017-9-9");
    /* 不写后台方法直接将值存在session中 */
%>

<html>
    <head>
        <script src="<%=ctx %>/resources/js/datepicker/WdatePicker.js" ></script> 
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>时间标签</h1>
        <easy:dateTag id="id" format="yyyy-MM-dd" dateValue="${dateValue}"/>
    </body>
    <script>
        /** 显示日历控件 */
        function showWdatePicker(objId,df){
            WdatePicker({
                el:objId,
                isShowClear:false,
                readOnly:true,
                highLineWeekDay:true,
                dateFmt:df
            });
        }
    </script>
</html>

被容器处理过后的页面:


<html>
    <head>
        <script src="/WebTest/resources/js/datepicker/WdatePicker.js" ></script> 
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>时间标签</h1>
        <input type='text' id='id' class='css' onclick="showWdatePicker('id','yyyy-MM-dd')"  value='2017-9-9' />

    </body>
    <script>
        /** 显示日历控件 */
        function showWdatePicker(objId,df){
            WdatePicker({
                el:objId,
                isShowClear:false,
                readOnly:true,
                highLineWeekDay:true,
                dateFmt:df
            });
        }
    </script>
</html>

对于上面的代码没有什么特殊的,不过有一点需要提一下:如果在标签处理器中使用Date作为日期的值类型,那么在页面上使用EL表达式取值的时候,EL会强转,这时候就会报错:
这里写图片描述
上网百度过,网友也说跟环境有关的,我的环境是JDK1.7, Tomcat7.x的,出现这个问题,错误代码就不贴了,如果是自己的标签出现这个错误就改一下标签,如果是第三方库出现这个问题,就想办法改一改实现方式。


版权声明:本文为zhonglin_li原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。