Java JSON转对象遇JsonMappingException:无法从START_OBJECT反序列化String
Hey there! That error usually pops up when your Java entity class has a field typed as String, but the corresponding part in your JSON is actually an object (wrapped in {}). Jackson can't convert an entire JSON object into a String, hence the exception. Let's fix this step by step.
Step 1: Break down your JSON structure
First, let's clarify the structure of the JSON you're working with to map it correctly:
{"usage":{"text_characters":22,"features":1,"text_units":1},"entities":[{"count":1,"text":"pisos","disambiguation":{"subtype":["NONE"]},"type":"Producto"},{"count":1,"text":"No hay","disambiguation":{"subtype":["NONE"]},"type":"Quiebre_Stock"},{"count":1,"text":"madera","disambiguation":{"subtype":["NONE"]},"type":"Producto"}],"language":"es"}
Key components:
- Root object has 3 fields:
usage(object),entities(array of objects),language(string) usageis an object with numeric fields:text_characters,features,text_units- Each item in the
entitiesarray includes:count(number),text(string),disambiguation(object),type(string) disambiguationis an object containing asubtypearray of strings
Step 2: Create matching Java entity classes
You need to define classes that mirror this structure exactly. Here's the correct code:
// Root response class import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class NlpResponse { private Usage usage; private List<Entity> entities; private String language; // Getters and setters (or use Lombok @Data if you have it) public Usage getUsage() { return usage; } public void setUsage(Usage usage) { this.usage = usage; } public List<Entity> getEntities() { return entities; } public void setEntities(List<Entity> entities) { this.entities = entities; } public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } } // Class for the "usage" object class Usage { @JsonProperty("text_characters") private int textCharacters; private int features; @JsonProperty("text_units") private int textUnits; // Getters and setters public int getTextCharacters() { return textCharacters; } public void setTextCharacters(int textCharacters) { this.textCharacters = textCharacters; } public int getFeatures() { return features; } public void setFeatures(int features) { this.features = features; } public int getTextUnits() { return textUnits; } public void setTextUnits(int textUnits) { this.textUnits = textUnits; } } // Class for items in the "entities" array class Entity { private int count; private String text; private Disambiguation disambiguation; private String type; // Getters and setters public int getCount() { return count; } public void setCount(int count) { this.count = count; } public String getText() { return text; } public void setText(String text) { this.text = text; } public Disambiguation getDisambiguation() { return disambiguation; } public void setDisambiguation(Disambiguation disambiguation) { this.disambiguation = disambiguation; } public String getType() { return type; } public void setType(String type) { this.type = type; } } // Class for the "disambiguation" object class Disambiguation { private List<String> subtype; // Getters and setters public List<String> getSubtype() { return subtype; } public void setSubtype(List<String> subtype) { this.subtype = subtype; } }
Step 3: Parse the JSON correctly
Now you can safely use mapper.readValue() to convert the JSON into your NlpResponse class:
ObjectMapper mapper = new ObjectMapper(); String json = "{\"usage\":{\"text_characters\":22,\"features\":1,\"text_units\":1},\"entities\":[{\"count\":1,\"text\":\"pisos\",\"disambiguation\":{\"subtype\":[\"NONE\"]},\"type\":\"Producto\"},{\"count\":1,\"text\":\"No hay\",\"disambiguation\":{\"subtype\":[\"NONE\"]},\"type\":\"Quiebre_Stock\"},{\"count\":1,\"text\":\"madera\",\"disambiguation\":{\"subtype\":[\"NONE\"]},\"type\":\"Producto\"}],\"language\":\"es\"}"; NlpResponse response = mapper.readValue(json, NlpResponse.class);
Common Pitfall to Avoid
The mistake you made was almost certainly defining a field like private String usage; or private String disambiguation; in your entity class. Jackson tries to read the JSON object (like {"text_characters":22,...}) into that String field, which triggers the exception. Always double-check that each field's type matches the JSON structure (object → class, array → List/array, primitive → primitive/String).
内容的提问来源于stack exchange,提问作者neo_free

