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

Jackson反序列化报错:无法将Object转为java.lang.String的解决方法求助

解决Jackson反序列化类型不匹配的问题

问题根源

你判断的完全正确:ConfigurationProperties类中propertiesJson字段定义为String类型,但输入JSON中对应的是嵌套JSON对象,Jackson尝试将对象解析为字符串时,必然抛出MismatchedInputException类型不匹配异常。

解决方案

根据是否允许修改类结构,提供两种可行方案:

方案1:修改ConfigurationProperties类的字段类型(推荐)

如果可以调整类结构,直接将propertiesJson的类型从String改为JsonNode或Object,让Jackson直接解析嵌套对象:

修改后的ConfigurationProperties类

public class ConfigurationProperties {
    private String propertiesClass;
    // 替换为JsonNode,保留JSON结构信息
    private JsonNode propertiesJson;
}

后续解析为具体类型

反序列化整个Configurations后,再根据propertiesClass指定的类名,将JsonNode转换为对应的Java对象:

ObjectMapper objectMapper = new ObjectMapper();
// 开启字符串转数值特性,处理latency、permittedTransactionsPerSecond的字符串格式数值
objectMapper.enable(DeserializationFeature.ACCEPT_STRING_AS_NUMERIC_VALUE);

// 反序列化整体配置
Configurations configs = objectMapper.readValue(input, Configurations.class);

// 获取第一个配置项的属性节点
ConfigurationProperties configProps = configs.getConfigurations().get(0).getConfigurationProperties();
JsonNode propertiesNode = configProps.getPropertiesJson();
// 根据propertiesClass反射获取目标类
Class<?> targetClass = Class.forName(configProps.getPropertiesClass());
// 将JsonNode转换为具体对象
Object properties = objectMapper.treeToValue(propertiesNode, targetClass);

方案2:自定义反序列化器,将JSON对象转为字符串(不修改类结构)

如果必须保留propertiesJson为String类型,需要自定义反序列化器,将输入的JSON对象序列化为JSON字符串:

1. 编写自定义反序列化器

public class JsonObjectToStringDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        // 将JSON节点转换为JSON字符串
        JsonNode node = parser.getCodec().readTree(parser);
        return parser.getCodec().writeValueAsString(node);
    }
}

2. 给propertiesJson字段添加注解

public class ConfigurationProperties {
    private String propertiesClass;
    // 指定使用自定义反序列化器
    @JsonDeserialize(using = JsonObjectToStringDeserializer.class)
    private String propertiesJson;
}

3. 后续解析具体类型

反序列化完成后,再将JSON字符串转换为目标类对象:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.ACCEPT_STRING_AS_NUMERIC_VALUE);

Configurations configs = objectMapper.readValue(input, Configurations.class);
String propsJsonStr = configs.getConfigurations().get(0).getConfigurationProperties().getPropertiesJson();
// 转换为具体类
SchoolProperties schoolProps = objectMapper.readValue(propsJsonStr, SchoolProperties.class);

额外处理:possibleExceptions字段的反序列化

输入JSON中possibleExceptions是类名字符串数组,而SchoolProperties中是Class<? extends Throwable>[]类型,需要额外自定义反序列化器:

编写Class数组反序列化器

public class ThrowableClassArrayDeserializer extends JsonDeserializer<Class<? extends Throwable>[]> {
    @Override
    public Class<? extends Throwable>[] deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        JsonNode node = parser.getCodec().readTree(parser);
        List<Class<? extends Throwable>> classList = new ArrayList<>();
        for (JsonNode itemNode : node) {
            try {
                Class<?> clazz = Class.forName(itemNode.asText());
                // 校验是否为Throwable子类
                if (Throwable.class.isAssignableFrom(clazz)) {
                    classList.add((Class<? extends Throwable>) clazz);
                } else {
                    throw new IOException("Class " + itemNode.asText() + " is not a subclass of Throwable");
                }
            } catch (ClassNotFoundException e) {
                throw new IOException("Failed to load class: " + itemNode.asText(), e);
            }
        }
        return classList.toArray(new Class[0]);
    }
}

给possibleExceptions字段添加注解

public class SchoolProperties {
    @JsonProperty("serviceName")
    String serviceName;

    @JsonProperty("operationName")
    String operationName;

    @JsonProperty("latency")
    Long latency;

    @JsonProperty("permittedTransactionsPerSecond")
    int permittedTransactionsPerSecond;

    @JsonDeserialize(using = ThrowableClassArrayDeserializer.class)
    Class<? extends Throwable>[] possibleExceptions;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:35:16