I am trying to read a string from a text file and want to map it to a bean class but I am getting an unusual exception from jackson library.
I have a made a POJO named Question.java that has all the values that I have to read from the text file.
private String Code;
private String QuestionCode;
private String Description;
private String Type;
private String LastUpdated;
I have main class where I read the string from the text file and try to map it to Question class
public class QuestionParser {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("Sample.txt"));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
String ls = System.getProperty("line.separator");
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
reader.close();
String content = stringBuilder.toString();
System.out.println(content);
String sample = content.replaceAll("\\\\", " ");
ObjectMapper mapper = new ObjectMapper();
Question question = mapper.readValue(sample, Question.class);
System.out.println(question);
}
}
The Sample.txt looks like
{\"Code\":\"60\",
\"QuestionCode\":\"7000\",
\"Description\":\"What is your favorite movie?\",
\"Type\":\"R\",
\"LastUpdated\":\"2015-05-21\"
}
After all this when I run the code it gives me below exception
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Code " (class Question), not marked as ignorable (5 known properties: "type", "questionCode", "description", "code", "lastUpdated"])
at [Source: (String)"{ "Code ": "60 ",
"QuestionCode ": "7000 ",
"Description ": "What is your favorite movie? ",
"Type ": "R ",
"LastUpdated ": "2015-05-21 "
}
"; line: 1, column: 13] (through reference chain: Question["Code "])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1127)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1984)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1701)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1679)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:319)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4620)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3575)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3543)
at QuestionParser.main(QuestionParser.java:33)
CodePudding user response:
You're defining and reading the file incorrectly. JSON is not line-delimited, so don't read it as lines
JSON should look like this, for example, no backslashes...
(file extension should ideally be .json
as well, but doesn't matter except for your text editor)
{
"Code": "60",
"QuestionCode":"7000"
}
Also, the Java field names should be annotated or exactly match the JSON fields; Java fields should be lower-case. You could also remove the quotes in the JSON values if you wanted to use integers or other datatypes than strings
public class Question {
public Question() { }
@JsonProperty("Code")
private String code;
// getters and setters
}
Then you can open that using the ObjectMapper directly
ObjectMapper om = new ObjectMapper();
// File should be in `src/main/resources` folder of a Java project
InputStream is = QuestionParser.class.getResourceAsStream("/questions.json");
Question q = om.readValue(is, Question.class);
CodePudding user response:
Your replace is creating all the issues. String sample = content.replaceAll("\\\\", " ");
is adding an additional whitespace to every JSON key. Please use the following code instead:
public class QuestionParser {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("Sample.txt"));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
String ls = System.getProperty("line.separator");
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
reader.close();
String content = stringBuilder.toString();
System.out.println(content);
String sample = content.replaceAll("\\\\", "");
ObjectMapper mapper = new ObjectMapper();
Question question = mapper.readValue(sample, Question.class);
System.out.println(question);
}
}
Mind the changed line: String sample = content.replaceAll("\\\\", "");
.
Additionally, as @Jens already mentioned, follow Java conventions and follow camelcase for Java property name. Having said this, please also change your Question
to:
public class Question {
private String code;
private String questionCode;
private String description;
private String type;
private String lastUpdated;
//getters & setters
}
Finally, you also need to adjust your JSON as follows:
{\"code\":\"60\",
\"questionCode\":\"7000\",
\"description\":\"What is your favorite movie?\",
\"type\":\"R\",
\"lastUpdated\":\"2015-05-21\"
}
UPDATE
Assuming you can't change the JSON file you are trying to read you would need to use @JsonProperty
annotation in your Question
class to "glue" the properties together. In this case, JSON would still look as you added in the question:
{\"Code\":\"60\",
\"QuestionCode\":\"7000\",
\"Description\":\"What is your favorite movie?\",
\"Type\":\"R\",
\"LastUpdated\":\"2015-05-21\"
}
But your Question
class would have a bunch of @JsonProperty
annotations (you can read more about it at https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonProperty.html):
public class Question {
@JsonProperty("Code")
private String code;
@JsonProperty("QuestionCode")
private String questionCode;
@JsonProperty("Description")
private String description;
@JsonProperty("Type")
private String type;
@JsonProperty("LastUpdated")
private String lastUpdated;
//getters & setters
}
CodePudding user response:
After parsing your string contains variable Code like "Code " with whitespace. You should fix replace logic or use annotation.
@JsonProperty("Code ")
private String Code;