jackson 尝试读取JSON并将其转换为POJO(反序列化)时出现NullPointerException

uubf1zoe  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(116)

我们的目标是:解析json文件并将其反序列化为java POJO
堆栈跟踪如下所示:

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)

我们尝试解析的文件如下所示:

{
  "properties": {
    "anon": {
      "/brief/versicherungsnehmer/vorname": true,
      "/brief/versicherungsnehmer/nachname": true
    }
  }
}

名为JSONMuncher的Json解析器类如下所示:

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;
    }
}

这是我们的ProfileSerializer类:

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();
    }
}

这是我们的ProfileDeserializer类:

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;
    }

}

这是Properties类:

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;
    }*/
}

Properties类用于在POJO中存储json值。
我们试了试:

  • 更改类Properties的继承类类型
  • 将fasterXML的供应商从codehaus更改为fasterxml,因为所有示例都使用fasterXML。
  • 将行this.vorname = (boolean) anon.get("/brief/versicherungsnehmer/vorname");更改为Map<Boolean,Boolean> vorname = (Map<Boolean,Boolean>) anon.get("/brief/versicherungsnehmer/vorname");
  • mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);添加到Map器配置中以防止出现空指针
  • StdSerializer更改为JsonSerializer

编辑:我刚刚尝试打印profileNode中的所有字段,看起来应该存在的节点(因为它们存在于json中)实际上并不存在:

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
mfpqipee

mfpqipee1#

好的,我可以通过修改我的deserialize()函数来解决这个问题,并获得正确的值,如下所示:

@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;

}

相关问题