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

Jackson反序列化JSON日期字符串至Java Date时遇格式错误求助

解决Jackson自定义日期反序列化器未生效的问题

嘿Farhan,我来帮你分析下这个问题~

从你给出的错误栈能看出关键问题:你的Jackson自定义反序列化器CustomDateDeserializer根本没被执行,实际在处理日期解析的是JodaTime的DateTimeFormatter和JAXB的DateAdapter,还有EclipseLink MOXy框架——这说明你的项目里的JSON处理逻辑被其他框架接管了,Jackson的注解和自定义类没生效。

问题原因分析

错误日志里的这些信息是突破口:

Caused by: java.lang.IllegalArgumentException: Invalid format: "2017-12-27" is too short
at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945) ~[joda-time-2.9.1.jar:2.9.1]
at com.exxonmobil.ace.hybris.jaxb.DateAdapter.unmarshal(DateAdapter.java:45) ~[DateAdapter.class:?]
at org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter.convertDataValueToObjectValue(XMLJavaTypeConverter.java:149) ~[org.eclipse.persistence.moxy-2.6.1.jar:?]

  • org.eclipse.persistence.moxy是EclipseLink的MOXy框架,它是JAXB的一个实现,既可以处理XML也可以处理JSON
  • DateAdapter是你项目里的JAXB适配器类,它在用JodaTime的格式化器解析日期,但它预期的日期格式比yyyy-MM-dd更长,所以报错“太短”

这意味着你的请求数据没有经过Jackson处理,而是被MOXy/JAXB的流程接管了,所以你写的Jackson自定义反序列化器完全没起作用。

解决方案

方案1:切换回Jackson作为默认JSON处理器

如果你的项目本来应该用Jackson处理JSON,那需要排除MOXy的依赖,确保Jackson的优先级更高:

  • 如果你用Maven,可以在相关依赖里排除MOXy:
    <dependency>
        <!-- 这里是引入MOXy的那个依赖,比如spring-boot-starter-web-services之类的 -->
        <groupId>xxx</groupId>
        <artifactId>xxx</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.eclipse.persistence</groupId>
                <artifactId>org.eclipse.persistence.moxy</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  • 若是Spring Boot项目,可以在application.properties里明确指定JSON处理器:
    spring.mvc.converters.preferred-json-mapper=jackson
    

方案2:修改JAXB的DateAdapter支持短日期格式

如果你的项目必须使用MOXy/JAXB处理,那需要修改项目里的DateAdapter类,让它支持yyyy-MM-dd格式:

import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormat;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.util.Date;

public class DateAdapter extends XmlAdapter<String, Date> {
    // 支持你需要的yyyy-MM-dd格式
    private static final DateTimeFormatter SHORT_DATE_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd")
            .withZone(DateTimeZone.UTC);
    // 如果原来还有长格式的需求,可以保留并做兼容
    private static final DateTimeFormatter ORIGINAL_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
            .withZone(DateTimeZone.UTC);

    @Override
    public Date unmarshal(String dateStr) throws Exception {
        if (dateStr == null) {
            return null;
        }
        // 先尝试短格式,失败再尝试原格式
        try {
            return new Date(SHORT_DATE_FORMAT.parseMillis(dateStr));
        } catch (IllegalArgumentException e) {
            try {
                return new Date(ORIGINAL_FORMAT.parseMillis(dateStr));
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException("无法解析日期字符串: " + dateStr, ex);
            }
        }
    }

    @Override
    public String marshal(Date date) throws Exception {
        if (date == null) {
            return null;
        }
        // 序列化可以按需求选择格式,这里用短格式举例
        return SHORT_DATE_FORMAT.print(date.getTime());
    }
}

方案3:确保Jackson配置生效

如果确认要使用Jackson,除了注解外,也可以全局注册自定义反序列化器,避免注解失效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 在配置类里初始化ObjectMapper
@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        // 全局注册自定义日期反序列化器
        module.addDeserializer(Date.class, new CustomDateDeserializer());
        mapper.registerModule(module);
        return mapper;
    }
}

总结

先重点排查项目的JSON处理器到底是Jackson还是MOXy/JAXB,从错误栈来看后者在起作用,所以要么切换回Jackson,要么修改JAXB的适配器来支持目标日期格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:32:08