Skip to content

Tree Model (JsonNode) with global typing  #353

@cemo

Description

@cemo

I am trying to persist my spring security based entities to database. I need to serialize Session Attributes Map<String, Object> to database correctly by preserving their id infos. I had enabled object mapper as this: mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.NON_FINAL, "@class"); . However when I tried to deserialize, I am having an issue.

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property '@class' that is to contain type id  (for class com.fasterxml.jackson.databind.JsonNode)
 at [Source: java.io.StringReader@b240236; line: 1, column: 193]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:784)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:147)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:95)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromAny(AsPropertyTypeDeserializer.java:165)

I can actually see @class in my output but still causing an error.
{"@class":"com.fasterxml.jackson.databind.jsontype.TestDefaultForObject$SavedCookie","name":"Cemo","value":"a","comment":"co","domain":"do","maxAge":12,"path":"/asd","secure":true,"version":12}

I started to consider that there is little bug. You can also check yourself too.

 public class SavedCookie implements Serializable {
      private final java.lang.String name;
      private final java.lang.String value;
      private final java.lang.String comment;
      private final java.lang.String domain;
      private final int maxAge;
      private final java.lang.String path;
      private final boolean secure;
      private final int version;

      public SavedCookie(String name, String value, String comment, String domain, int maxAge, String path, boolean secure, int version) {
         this.name = name;
         this.value = value;
         this.comment = comment;
         this.domain = domain;
         this.maxAge = maxAge;
         this.path = path;
         this.secure = secure;
         this.version = version;
      }

      public String getName() {
         return name;
      }

      public String getValue() {
         return value;
      }

      public String getComment() {
         return comment;
      }

      public String getDomain() {
         return domain;
      }

      public int getMaxAge() {
         return maxAge;
      }

      public String getPath() {
         return path;
      }

      public boolean isSecure() {
         return secure;
      }

      public int getVersion() {
         return version;
      }
   }


   public class SavedCookieDeserializer extends JsonDeserializer<SavedCookie> {
      @Override
      public SavedCookie deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
         ObjectCodec oc = jsonParser.getCodec();
         JsonNode node = oc.readTree(jsonParser);
         return new SavedCookie( node.get("name") != null ? node.get("name").asText() : null,
                                 node.get("value") != null ? node.get("value").asText() : null,
                                 node.get("comment") != null ? node.get("comment").asText() : null,
                                 node.get("domain") != null ? node.get("domain").asText() : null,
                                 node.get("maxAge") != null ? node.get("maxAge").asInt() : 0,
                                 node.get("path") != null ? node.get("path").asText() : null,
                                 node.get("secure") != null && node.get("secure").asBoolean(),
                                 node.get("version") != null ? node.get("version").asInt() : 0);
      }
   }

    public void testIssue() throws Exception
    {
       ObjectMapper mapper = new ObjectMapper();

      mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.NON_FINAL, "@class");

       SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null, "TEST", "TEST"));
       testModule.addDeserializer(SavedCookie.class, new SavedCookieDeserializer());
       mapper.registerModule(testModule);

       SavedCookie savedCookie = new SavedCookie("Cemo", "a", "co", "do", 12, "/asd", true, 12);
       // persist at db
       String x = mapper.writeValueAsString(savedCookie);
       // read from db
       SavedCookie o = mapper.reader(SavedCookie.class).readValue(x);
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions