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

如何解决JavaScript传JSON到Java时Timestamp类型不兼容错误?

问题

前端通过JavaScript向Java后端发送包含日期的JSON请求体时,出现类型不兼容错误:

org.apache.struts2.json.JSONException: Incompatible types for property setBillingDate

相关代码如下:

JSP代码

<div class="inv-row">
    <span class="labels-alignment inv-label">Invoice Date:&nbsp;</span> 
        <input type="text" id="dtPaymentDate"
            style="height: 30px;background-color: #fff; cursor: pointer; max-width: 185px;"
            onblur="dateFieldBlur(this)" class="form-control dp"
            placeholder="mm/dd/yyyy" required ng-model="dtPaymentDate">
        <span class="text-danger fade in" style="width: 100%; float: left; position: relative; margin-top: 5px;">{{paymentDateError}} {{paymentGreaterDueDateError}}</span>
</div>
<div class="inv-row">
    <span class="labels-alignment inv-label">Due Date:&nbsp;</span> 
        <input type="text" id="dtDuePaymentDate"
            style="height: 30px;background-color: #fff; cursor: pointer; max-width: 185px;"
            onblur="dateFieldBlur(this)" class="form-control dp"
            placeholder="mm/dd/yyyy" required ng-model="dtDuePaymentDate">
        <span class="text-danger fade in" style="width: 100%; float: left; position: relative; margin-top: 5px;">{{dueDateError}}</span>
</div>

JavaScript代码

jQuery('#dtPaymentDate').val(this.objScope.PaymentDate);
jQuery('#dtDuePaymentDate').val(this.objScope.DueDate);
var reqParams =
{
    userId: this.objScope.userId,
    billingDate : this.objScope.PaymentDate,
    billingDueDate : this.objScope.DueDate          
};
var strFunctionToCall = "javaController.action" + "?" + "action=processFormCall";

this.makeCall(strFunctionToCall, reqParams,this.processFormStartComplete.bind(this), this.processFormStartComplete.bind(this));

Java后端接收字段

private Timestamp billingDate;
private Timestamp billingDueDate;

解决方案

方法一:前端转换日期格式为后端可识别的标准格式

前端传递的mm/dd/yyyy字符串无法被Struts2的JSON插件直接转换为Timestamp,可转换为ISO 8601格式或时间戳(毫秒数):

转ISO格式示例:

// 把mm/dd/yyyy字符串转为ISO格式
function formatDateToISO(dateStr) {
    const [month, day, year] = dateStr.split('/');
    return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}T00:00:00`;
}

var reqParams =
{
    userId: this.objScope.userId,
    billingDate : formatDateToISO(this.objScope.PaymentDate),
    billingDueDate : formatDateToISO(this.objScope.DueDate)          
};

转时间戳示例:

// 把mm/dd/yyyy字符串转为时间戳(毫秒)
function getTimestamp(dateStr) {
    const [month, day, year] = dateStr.split('/');
    return new Date(year, month - 1, day).getTime();
}

var reqParams =
{
    userId: this.objScope.userId,
    billingDate : getTimestamp(this.objScope.PaymentDate),
    billingDueDate : getTimestamp(this.objScope.DueDate)          
};

后端Timestamp可直接接收时间戳(若为秒级时间戳需乘以1000)。

方法二:后端修改字段处理逻辑

  1. 临时转换:将字段改为String,在setter中手动转换
    修改后端字段类型为String,在setter方法中把字符串转为Timestamp:

    private Timestamp billingDate;
    
    public void setBillingDate(String billingDateStr) throws ParseException {
        // 匹配前端的mm/dd/yyyy格式
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        Date date = sdf.parse(billingDateStr);
        this.billingDate = new Timestamp(date.getTime());
    }
    

    需处理ParseException,或添加全局异常处理。

  2. 使用Struts2自定义类型转换器
    实现Struts2的TypeConverter接口,自定义日期到Timestamp的转换逻辑,再在配置文件中注册:

    • 编写转换器类:
      public class TimestampConverter extends StrutsTypeConverter {
          private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
      
          @Override
          public Object convertFromString(Map context, String[] values, Class toClass) {
              if (values == null || values.length == 0 || StringUtils.isEmpty(values[0])) {
                  return null;
              }
              try {
                  Date date = DATE_FORMAT.parse(values[0]);
                  return new Timestamp(date.getTime());
              } catch (ParseException e) {
                  throw new RuntimeException("日期转换失败", e);
              }
          }
      
          @Override
          public String convertToString(Map context, Object o) {
              if (o instanceof Timestamp) {
                  return DATE_FORMAT.format((Timestamp) o);
              }
              return "";
          }
      }
      
    • 在xwork-conversion.properties中配置:
      java.sql.Timestamp=com.yourpackage.TimestampConverter
      

方法三:配置Struts2 JSON插件的日期格式

在Struts2配置文件中指定JSON插件的日期转换格式,匹配前端传递的mm/dd/yyyy:

<package name="default" extends="json-default">
    <action name="javaController" class="com.yourpackage.JavaController">
        <result type="json">
            <param name="dateFormat">MM/dd/yyyy</param>
            <param name="root">result</param>
        </result>
    </action>
</package>

此方式可让JSON插件自动按指定格式将字符串转为Timestamp。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:54:31