将java.time.LocalDate与JSTL一起使用<;fmt:形成日期>;行动

将java.time.LocalDate与JSTL一起使用<;fmt:形成日期>;行动,java,jsp,java-8,jstl,jsp-tags,Java,Jsp,Java 8,Jstl,Jsp Tags,我还没有弄清楚如何在JSP中显示java.time.LocalDate值 在我的JSP中,我有以下内容: std.datum类型为。呈现JSP时,我会遇到以下异常: javax.el.ELException: 无法转换类型为class的2015-02-14 将java.time.LocalDate转换为类java.util.Date 我想是转换吧 那么,是否可以使用操作格式化LocalDate类的实例 我想是转换吧 是的,这是一个与转换相关的异常 解决方案 您可以首先使用JSTL的“支持

我还没有弄清楚如何在JSP中显示
java.time.LocalDate

在我的JSP中,我有以下内容:



std.datum
类型为。呈现JSP时,我会遇到以下异常:

javax.el.ELException:
无法转换类型为class的2015-02-14 将java.time.LocalDate转换为类java.util.Date

我想是转换吧

那么,是否可以使用
操作格式化LocalDate类的实例

我想是转换吧

是的,这是一个与转换相关的异常


解决方案 您可以首先使用JSTL的“支持I18n的格式化标记库”中的操作进行转换,然后使用该操作进行格式化

以下是一个例子:

<fmt:parseDate  value="${std.datum}"  type="date" pattern="yyyy-MM-dd" var="parsedDate" />
<fmt:formatDate value="${parsedDate}" type="date" pattern="dd.MM.yyyy" var="stdDatum" />



规范版本1.2(见第109页)中也介绍了该解决方案

这是一个老问题,但我发现在这种情况下最好使用自定义tld:不需要对字符串进行任何双重转换

创建自己的tld文件,然后重写FormatDate类。最后,声明您自己的自定义前缀并使用custom:formatDate而不是fmt:formatDate

这是一个简化的版本

JSP中的用法:

<%@ taglib uri="/WEB-INF/custom" prefix="custom" %>
...
<custom:formatDate value="${std.datum}" pattern="dd/MM/yyyy" />

我希望避免更改所有使用的位置,因此我创建了以下两个类:

首先是一个转换器,用于转换(部分)java.time类。它检查java.util.Date是否为目标类型,如果不是,则不执行任何操作。它支持源时间为java.util.Date(包括java.sql.Timestamp和java.sql.Date)、LocalDate、LocalDateTime、ZonedDateTime、Instant或Long(时间单位为毫秒)

最后,web.xml中的一个条目(如果您没有使用注释或其他方式):


com.example.web.JspElResolverInitListener

根据消息
无法将类java.time.LocalDate的2015-02-14转换为类java.util.Date
,JSTL标记
不支持java 8中引入的
java.time.LocalDate
<?xml version="1.0" encoding="UTF-8"?>
<tag ib version="2.0" 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">

<tag>
    <description>
        FormatDate with java8 type
    </description>
    <name>formatDate</name>
    <tag-class>com.custom.tag.FormatDateTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <description>
            Date and/or time to be formatted.
        </description>
        <name>value</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>

    <attribute>
        <description>
            Custom formatting style for dates and times.
        </description>
        <name>pattern</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>
</taglib>
public class FormatDateTag extends TagSupport  {

    protected Temporal value;
    protected String pattern; 
    private String var; 
    private int scope; 


    public FormatDateTag()
    {
        super ();
        init ();
    }

    private void init()
    {

        this.pattern = this.var = null;
        this.value = null;
        this.scope = PageContext.PAGE_SCOPE;
    }


    public void setVar(final String var)
    {
        this.var = var;
    }

    public void setScope(final String scope)
    {
        this.scope = Util.getScope (scope);
    }


    public void setValue(final Temporal value)
    {
        this.value = value;
    }


    public void setPattern(final String pattern)
    {
        this.pattern = pattern;
    }


    @Override
    public int doEndTag() throws JspException
    {

        String formatted = null;

        if (this.value == null)
        {
            if (this.var != null)
            {
                this.pageContext.removeAttribute (this.var, this.scope);
            }
            return EVAL_PAGE;
        }

        // Create formatter
        if (this.pattern != null)
        {
            final DateTimeFormatter formatter = DateTimeFormatter.ofPattern (this.pattern);
            formatted = formatter.format (this.value);
        }
        else
        {
            // no formatting locale available, use Date.toString()
            formatted = this.value.toString ();
        }

        if (this.var != null)
        {
            this.pageContext.setAttribute (this.var, formatted, this.scope);
        }
        else
        {
            try
            {
                this.pageContext.getOut ().print (formatted);
            }
            catch (final IOException ioe)
            {
                throw new JspTagException (ioe.toString (), ioe);
            }
        }

        return EVAL_PAGE;
    }


    @Override
    public void release()
    {
        init ();
    }

}
package com.example.elresolvers;

import javax.el.ELContext;
import javax.el.TypeConverter;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

@SuppressWarnings("UseOfObsoleteDateTimeApi")
public class DateFromJavaTimeResolver extends TypeConverter {
    @Override
    public Object convertToType(ELContext context, Object obj, Class<?> type) {
        Date date = null;
        if (Date.class.isAssignableFrom(type)) {
            if (obj instanceof Date) {
                date = (Date) obj;
            } else {
                ZonedDateTime zdt = null;
                if (obj instanceof LocalDate) {
                    zdt = ((LocalDate) obj).atStartOfDay(ZoneId.systemDefault());
                } else if (obj instanceof LocalDateTime) {
                    zdt = ((LocalDateTime) obj).atZone(ZoneId.systemDefault());
                } else if (obj instanceof ZonedDateTime) {
                    zdt = (ZonedDateTime) obj;
                } else if (obj instanceof Instant) {
                    date = Date.from((Instant) obj);
                } else if (obj instanceof Long) {
                    date = new Date((Long) obj);
                }
                if (zdt != null) {
                    date = Date.from(zdt.toInstant());
                }
            }
            context.setPropertyResolved(date != null);
        }
        return date;
    }
}
package com.example.web;

import com.example.elresolvers.DateFromJavaTimeResolver;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspFactory;

public class JspElResolverInitListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        JspApplicationContext context = JspFactory.getDefaultFactory().getJspApplicationContext(servletContext);
        context.addELResolver(new DateFromJavaTimeResolver());
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}
<listener>
    <listener-class>com.example.web.JspElResolverInitListener</listener-class>
</listener>