Reputation: 101
Our goal is to: parse a json file and deserialize it into a java POJO
The stacktrace looks like this:
16:39:21,628 ERROR [stderr] (default task-1) java.lang.NullPointerException
16:39:21,628 ERROR [stderr] (default task-1) at deployment.webservice_child.war //ProfileDeserializer.deserialize(ProfileDeserializer.java:31)
16:39:21,628 ERROR [stderr] (default task-1) at deployment.webservice_child.war //ProfileDeserializer.deserialize(ProfileDeserializer.java:16)
The files we are trying to parse look like this:
{
"properties": {
"anon": {
"/brief/versicherungsnehmer/vorname": true,
"/brief/versicherungsnehmer/nachname": true
}
}
}
Our Json Parser class called JSONMuncher
looks like this:
public class JSONMuncher {
private final ObjectMapper objectMapper;
public JSONMuncher() {
this.objectMapper = createObjectMapper();
}
public ObjectMapper getObjectMapper() {
return objectMapper;
}
private static ObjectMapper createObjectMapper() {
SimpleModule module = new SimpleModule()
.addSerializer(Properties.class, new ProfileSerializer())
.addDeserializer(Properties.class, new ProfileDeserializer());
return new ObjectMapper(new JsonFactory()
.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT))
.registerModule(module);
}
public Object readConfig(String filepath) {
try {
ObjectMapper mapper = createObjectMapper();
SimpleModule module = new SimpleModule();
mapper.configure(Feature.AUTO_CLOSE_SOURCE, true);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// do not serialize null value fields
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
module.addSerializer(Properties.class, new ProfileSerializer());
module.addDeserializer(Properties.class, new ProfileDeserializer());
mapper.registerModule(module);
InputStream is = new FileInputStream(filepath);
System.out.println("[DEBUG!!!!!!!!!111!!!]: " + is.read());
Properties anon = mapper.readValue(is, Properties.class);
System.out.println(anon.getVorname());
System.out.println(anon.getNachname());
return anon;
} catch (IOException e) {
System.out.println("Beep Boop Err!!! 🤖");
e.printStackTrace();
}
return null;
}
}
This is our ProfileSerializer Class:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
public class ProfileSerializer extends StdSerializer<Properties> {
public ProfileSerializer() {
this(null);
}
public ProfileSerializer(Class<Properties> src) {
super(src);
}
@Override
public void serialize(Properties property, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
if (property != null) {
gen.writeObjectField("vorname", property.getVorname());
gen.writeObjectField("nachname", property.getNachname());
}
gen.writeEndObject();
}
}
This is our ProfileDeserializer Class:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
@JsonDeserialize(using = Properties.class)
public class ProfileDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<Properties> {
public ProfileDeserializer() {
this(null);
}
public ProfileDeserializer(Class<?> vc) {
super();
}
@Override
public Properties deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
JsonNode profileNode = jsonParser.getCodec().readTree(jsonParser);
Properties property = new Properties();
property.setVorname(profileNode.get("vorname").booleanValue());
property.setNachname(profileNode.get("nachname").booleanValue());
//property.un
return property;
}
}
And this is the Properties
class:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
//import org.codehaus.jackson.map.annotate.JsonDeserialize;
import java.io.IOException;
import java.util.Map;
public class Properties extends com.fasterxml.jackson.databind.JsonDeserializer<Properties> {
private boolean vorname;
private boolean nachname;
public void setVorname(boolean vorname) {
this.vorname = vorname;
}
public void setNachname(boolean nachname) {
this.nachname = nachname;
}
public boolean getVorname() {
return this.vorname;
}
public boolean getNachname() {
return this.nachname;
}
@SuppressWarnings("unchecked")
@JsonProperty("anon")
private void unpackNested(Map<Boolean, Object> anon) {
//this.vorname = (boolean) anon.get("/brief/versicherungsnehmer/vorname");
//this.nachname = (boolean) anon.get("/brief/versicherungsnehmer/nachname");
Map<Boolean,Boolean> vorname = (Map<Boolean,Boolean>) anon.get("/brief/versicherungsnehmer/vorname");
Map<Boolean,Boolean> nachname = (Map<Boolean,Boolean>) anon.get("/brief/versicherungsnehmer/nachname");
this.vorname = (boolean) vorname.get("vorname");
this.nachname = (boolean) nachname.get("nachname");
//Map<Boolean,Boolean> owner = (Map<Boolean,Boolean>)anon.get("owner");
//this.ownerName = owner.get("name");
}
@Override
public Properties deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
JsonNode profileNode = jsonParser.getCodec().readTree(jsonParser);
Properties property = new Properties();
property.setVorname(profileNode.get("vorname").booleanValue());
property.setNachname(profileNode.get("nachname").booleanValue());
//property.un
return property;
}
/*@Override
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return null;
}*/
}
The Properties
class is used to store the json values in POJOs.
We tried:
codehaus
to fasterxml
because all of the examples used fasterxml.this.vorname = (boolean) anon.get("/brief/versicherungsnehmer/vorname");
to Map<Boolean,Boolean> vorname = (Map<Boolean,Boolean>) anon.get("/brief/versicherungsnehmer/vorname");
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
to the mapper config to prevent NullPointersStdSerializer
to JsonSerializer
Edit: I just tried out printing all the fields inside profileNode and it looks like the nodes that should exist because they exist in the json are in fact not present:
09:22:07,049 INFO [stdout] (default task-1) Child nodes: dokumenttyp
09:22:07,049 INFO [stdout] (default task-1) Child nodes: sprache
09:22:07,049 INFO [stdout] (default task-1) Child nodes: vertragsdaten
09:22:07,064 INFO [stdout] (default task-1) Child nodes: sachbearbeiter
09:22:07,064 INFO [stdout] (default task-1) Child nodes: versicherungsnehmer
09:22:07,064 INFO [stdout] (default task-1) Child nodes: bankverbindung
09:22:07,064 INFO [stdout] (default task-1) Child nodes: person
Upvotes: 1
Views: 1625
Reputation: 101
Ok so I was able to fix this issue and getting the correct values by modifying my deserialize() function like this:
@Override
public Properties deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
JsonNode profileNode =
jsonParser.getCodec().readTree(jsonParser);
Properties property = new Properties();
System.out.println(profileNode.get("properties").get("anon").get("/brief/versicherungsnehmer/vorname").booleanValue());
property.setVorname(profileNode.get("properties").get("anon").get("/brief/versicherungsnehmer/vorname").booleanValue());
System.out.println(profileNode.get("properties").get("anon").get("/brief/versicherungsnehmer/nachname").booleanValue());
property.setNachname(profileNode.get("properties").get("anon").get("/brief/versicherungsnehmer/nachname").booleanValue());
return property;
}
Upvotes: 2