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

Spring Boot 2中Jackson反序列化空Map失败报错咨询

Fixing Jackson Deserialization Error for Map<String, String> in Spring Boot 2

Hey there, let's break down this deserialization issue you're facing. The core problem here is a mismatch between the JSON input your application is receiving and what Jackson expects for your settings field.

What's Causing the Error?

Your DTO's Map<String, String> settings uses @JsonInclude(value=Include.NON_EMPTY, content=Include.NON_NULL) — but important to note: this annotation only affects serialization (converting Java objects to JSON), not deserialization (turning incoming JSON into Java objects).

The error message tells us Jackson is trying to parse an empty string ('') into a LinkedHashMap, which fails because LinkedHashMap has no constructor that accepts a string as input. This means whatever is sending the JSON (like a frontend or external service) is passing {"settings": ""} instead of a valid Map structure, such as {"settings": {"theme": "dark", "notifications": "enabled"}} or an empty object {"settings": {}}.

Solutions to Resolve This

1. Fix the Input Source (Recommended)

The cleanest fix is to ensure the sender provides a valid Map structure for the settings field. If there are no settings to send, they should either:

  • Omit the settings field entirely
  • Send null
  • Send an empty object {}

All of these options will work seamlessly with your existing @JsonInclude configuration.

2. Custom Deserializer to Handle Empty Strings

If you can't control the input source (e.g., dealing with a legacy system that sends empty strings), you can create a custom Jackson deserializer to convert empty strings into an empty Map.

Here's how to implement it:

  • First, create the custom deserializer class:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class EmptyStringToEmptyMapDeserializer extends JsonDeserializer<Map<String, String>> {
    @Override
    public Map<String, String> deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        JsonNode node = parser.getCodec().readTree(parser);
        
        // Convert empty string input to an empty Map
        if (node.isTextual() && node.asText().isEmpty()) {
            return new LinkedHashMap<>();
        }
        
        // Parse valid Map structures normally
        return parser.getCodec().treeToValue(node, Map.class);
    }
}
  • Add the deserializer annotation to your settings field in the DTO:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.Map;

public class YourDTO {
    // ... other fields ...

    @JsonInclude(value = JsonInclude.Include.NON_EMPTY, content = JsonInclude.Include.NON_NULL)
    @JsonDeserialize(using = EmptyStringToEmptyMapDeserializer.class)
    private Map<String, String> settings;

    // ... getters and setters ...
}

3. Global Jackson Configuration (Optional)

If you want this behavior to apply to all Map fields across your application, you can configure a global Jackson module. Keep in mind this is less targeted and might have unintended side effects, so use it cautiously.

Key Reminder

Don't mix up the purpose of @JsonInclude: it only controls how Jackson serializes your Java objects to JSON (skipping empty collections or null values). It does not change how Jackson parses incoming JSON into Java objects — that's where deserializers or input validation come into play.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:17:07