使用Jackson解析JSON时,如何将逗号分隔字符串转为多元素Integer列表?
Absolutely, you can make this work with Jackson! The core issue here is that your JSON structure has a single comma-separated string inside the array (instead of three distinct numeric values), so Jackson defaults to treating it as one element in the list. Here are two clean approaches to fix this:
Approach 1: Custom JsonDeserializer (Recommended for Map Use Case)
You can create a custom deserializer that takes the comma-separated string, splits it, and converts each part to an Integer. Then register this deserializer with your ObjectMapper so it knows how to handle List<Integer> fields in your map.
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 java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class CommaSeparatedIntegerListDeserializer extends JsonDeserializer<List<Integer>> { @Override public List<Integer> deserialize(JsonParser parser, DeserializationContext context) throws IOException { String rawValue = parser.getText(); // Handle empty or null values gracefully if (rawValue == null || rawValue.trim().isEmpty()) { return Collections.emptyList(); } // Split by commas (ignoring any surrounding whitespace) and convert to Integers return Arrays.stream(rawValue.split(",\\s*")) .map(Integer::parseInt) .collect(Collectors.toList()); } }
Next, register this deserializer with your ObjectMapper and parse the JSON:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import java.util.List; import java.util.Map; public class JsonParsingExample { public static void main(String[] args) throws Exception { String jsonString = "{\"LIST_OF_IDS_FOR_RETRANSFER\":[\"50, 39, 29\"]}"; ObjectMapper mapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); // Register the deserializer for List<Integer> type customModule.addDeserializer(new com.fasterxml.jackson.core.type.TypeReference<List<Integer>>() {}, new CommaSeparatedIntegerListDeserializer()); mapper.registerModule(customModule); // Now parse the JSON into your desired Map structure Map<String, List<Integer>> params = mapper.readValue(jsonString, new com.fasterxml.jackson.core.type.TypeReference<Map<String, List<Integer>>>() {}); // Verify the result: params.get("LIST_OF_IDS_FOR_RETRANSFER") will have [50, 39, 29] } }
Approach 2: Manual Post-Processing (Quick Fix)
If you don't want to create a custom deserializer, you can first parse the JSON into a Map<String, List<String>>, then manually convert the string element to a list of Integers:
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class QuickFixExample { public static void main(String[] args) throws Exception { String jsonString = "{\"LIST_OF_IDS_FOR_RETRANSFER\":[\"50, 39, 29\"]}"; ObjectMapper mapper = new ObjectMapper(); Map<String, List<String>> tempMap = mapper.readValue(jsonString, new com.fasterxml.jackson.core.type.TypeReference<Map<String, List<String>>>() {}); // Convert the single string to a list of Integers List<Integer> ids = tempMap.get("LIST_OF_IDS_FOR_RETRANSFER").stream() .flatMap(s -> Arrays.stream(s.split(",\\s*"))) .map(Integer::parseInt) .collect(Collectors.toList()); // If needed, you can put this back into a Map<String, List<Integer>> Map<String, List<Integer>> finalMap = Map.of("LIST_OF_IDS_FOR_RETRANSFER", ids); } }
Why Your Original Code Didn't Work
Your JSON array contains a single string value "50, 39, 29"—not three separate numeric values like [50, 39, 29]. Jackson has no built-in logic to split this string automatically, so it treats it as one element in the list. The custom deserializer or manual processing adds that splitting logic.
内容的提问来源于stack exchange,提问作者Mike

