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

Java使用Jackson解析JSON数组时出现类型不匹配异常的问询

解决Jackson解析JSON数组到Wrapper类的MismatchedInputException异常

问题场景

你有如下JSON数据:

[
    {
        "Title": "New Moon in Sagittarius",
        "eventStartDate": "01/12/2024",
        "eventEndDate": "01/12/2024"
    },
    {
        "Title": "Christmas",
        "eventStartDate": "25/12/2024",
        "eventEndDate": "25/12/2024"
    },
    {
        "Title": "New Year's Eve",
        "eventStartDate": "31/12/2024",
        "eventEndDate": "31/12/2024"
    }
]

使用以下代码解析时:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(new StdDateFormat().withLenient(false));

// Convert JSON string to Wrapper Class
AstronomicalEventsWrapper wrapper = objectMapper.readValue
        (jsonString, AstronomicalEventsWrapper.class);

抛出异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.systicblanets.model.AstronomicalEventsWrapper` from Array value (token `JsonToken.START_ARRAY`)
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1767)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1541)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1488)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeFromArray(BeanDeserializer.java:656)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:211)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4899)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3846)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3814)
    at com.mysticplanets.schedulingtasks.CreateAstronomicalEventTask.sendMessage(CreateAstronomicalEventTask.java:60)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
    at io.micrometer.observation.Observation.observe(Observation.java:499)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
    at org.springframework.scheduling.config.Task$OutcomeTrackingRunnable.run(Task.java:83)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)

你的AstronomicalEventsWrapper类代码:

import java.util.List;

public class AstronomicalEventsWrapper {

    private List<AstronomicalEvent> astrologicalEvents;

    public List<AstronomicalEvent> getAstronomicalEvents() {
        return astrologicalEvents;
    }

    public void setAstronomicalEvents(List<AstronomicalEvent> astrologicalEvents) {
        this.astrologicalEvents = astrologicalEvents;
    }

    @Override
    public String toString() {
        return "AstronomicalEventsWrapper{" +
                "astrologicalEvents=" + astrologicalEvents +
                '}';
    }
}

错误原因

JSON的根节点是数组类型(用[]包裹),但你尝试将其反序列化成AstronomicalEventsWrapper这个单个对象,Jackson无法将数组直接转换为对象类型,因此抛出类型不匹配的异常。

解决方案

有两种可行的解决方式,根据你的需求选择:

方式一:修改JSON结构适配Wrapper类

将JSON调整为外层包含astrologicalEvents字段的对象结构,和AstronomicalEventsWrapper的属性对应:

{
  "astrologicalEvents": [
    {
        "Title": "New Moon in Sagittarius",
        "eventStartDate": "01/12/2024",
        "eventEndDate": "01/12/2024"
    },
    {
        "Title": "Christmas",
        "eventStartDate": "25/12/2024",
        "eventEndDate": "25/12/2024"
    },
    {
        "Title": "New Year's Eve",
        "eventStartDate": "31/12/2024",
        "eventEndDate": "31/12/2024"
    }
  ]
}

修改后,原有的解析代码可以正常运行,因为JSON根节点现在是对象,和Wrapper类结构匹配。

方式二:修改解析代码直接解析为列表

如果无法修改JSON结构,直接将JSON数组解析为List<AstronomicalEvent>,再手动赋值给Wrapper类:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(new StdDateFormat().withLenient(false));

// 直接解析为List<AstronomicalEvent>,使用TypeReference处理泛型
List<AstronomicalEvent> eventList = objectMapper.readValue(
    jsonString, new com.fasterxml.jackson.core.type.TypeReference<List<AstronomicalEvent>>() {}
);

// 手动封装到Wrapper类中
AstronomicalEventsWrapper wrapper = new AstronomicalEventsWrapper();
wrapper.setAstronomicalEvents(eventList);

注意:这里必须使用TypeReference来传递泛型信息,因为Java的类型擦除机制,直接使用List.class无法让Jackson识别具体的元素类型。

另外,确保AstronomicalEvent类的字段与JSON中的键正确映射,比如JSON里的Title可以在类的字段上添加@JsonProperty("Title")注解来匹配大小写,或者开启Jackson的驼峰命名自动转换配置:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);

内容的提问来源于stack exchange,提问作者Nunyet Calçada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:37:33