You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:JSF中无法将用户输入的日期时间转换为Timestamp

解决JSF中java.util.Date到java.sql.Timestamp的转换错误

这个报错的核心原因很明确:<f:convertDateTime> 默认会将用户输入的日期字符串转换为 java.util.Date 类型,但你的实体类属性 datum 是 java.sql.Timestamp 类型,JSF容器无法自动完成这两种类型的直接转换,因此抛出类型不匹配的异常。

下面给你几种可行的解决方案,按推荐程度排序:

方案1:将实体类属性改为java.util.Date(推荐)

如果你的持久层用的是JPA(比如Hibernate),其实不需要在实体类中直接使用java.sql.Timestamp。JPA会自动将java.util.Date映射到数据库的TIMESTAMP字段,只要你在实体属性上标注正确的注解:

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Event {
    // 其他属性...
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "datum")
    private Date datum;

    // getter和setter...
}

这种方式最省心,不需要额外的转换器,JSF的默认DateTimeConverter就能直接工作,JPA会帮你处理和数据库的类型映射。

方案2:自定义JSF转换器直接转换为java.sql.Timestamp

如果你必须保留实体类中的java.sql.Timestamp类型,可以自定义一个转换器来替代默认的DateTimeConverter:

步骤1:实现自定义转换器类

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@FacesConverter("timestampConverter")
public class TimestampConverter implements Converter {
    private static final String PATTERN = "dd.MM.yyyy HH:mm"; // 注意:HH是24小时制,hh是12小时制,根据你的需求调整

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
            Date utilDate = sdf.parse(value);
            return new Timestamp(utilDate.getTime());
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid date format. Please use " + PATTERN, e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null) {
            return "";
        }
        if (value instanceof Timestamp) {
            SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
            return sdf.format((Timestamp) value);
        } else {
            throw new IllegalArgumentException("Value must be a java.sql.Timestamp");
        }
    }
}

步骤2:在JSF组件中使用自定义转换器

替换原来的<f:convertDateTime>,改用自定义的转换器:

<h:inputText value="#{eventMB.eventTo.datum}">
    <f:converter converterId="timestampConverter" />
</h:inputText>

方案3:在ManagedBean的setter方法中手动转换

这种方式比较取巧,适合快速临时解决问题:
在你的EventMB中,给eventTo的datum属性添加一个额外的setter,接受java.util.Date类型,然后手动转成Timestamp:

public class EventMB {
    private Event eventTo;

    // 原有的getter和setter...
    
    // 新增一个接受Date类型的setter,供JSF调用
    public void setDatum(Date date) {
        if (date != null) {
            eventTo.setDatum(new Timestamp(date.getTime()));
        } else {
            eventTo.setDatum(null);
        }
    }
}

然后JSF页面中的代码可以保留原来的<f:convertDateTime>,因为现在setter接受的是Date类型了。

最后提醒一下:注意日期格式中的小时部分,hh是12小时制(需要配合AM/PM),如果你的输入是24小时制的时间,一定要改成HH,否则会出现转换错误。

内容的提问来源于stack exchange,提问作者Rugo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:58:50