Thread: [634] Jackson ignore class from serialization

Results 1 to 8 of 8
  1. #1 [634] Jackson ignore class from serialization 
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,547
    Thanks given
    646
    Thanks received
    637
    Rep Power
    334
    I'm currently using [Only registered and activated users can see links. ]to serialize my player saves, but I can't seem to find how to ignore/skip specific classes from being serialized. I've tried using the annotation @[Only registered and activated users can see links. ]IgnoreType like it was recommended [Only registered and activated users can see links. ], but that only seems to work for actual fields (not entries in a list). I've also tried tagging the classes I want to ignore with @[Only registered and activated users can see links. ]IgnoreType and using a custom annotation introspector, but it just saves the empty classes without the fields (except for className):

    Code:
    saveMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
        @Override
        public boolean hasIgnoreMarker(AnnotatedMember m) {
            return super.hasIgnoreMarker(m) || m.getDeclaringClass().getAnnotation(JsonIgnoreType.class) != null;
        }
    });
    
    ...
    
      @[Only registered and activated users can see links. ]IgnoreType
    private static class ScriptA extends Script {
        private int dontKeep;
    
        public ScriptA() {
            dontKeep = 25;
        }
    }
    Result:

    Code:
    {
        "scripts" : [ {
            "className" : "com.JsonExemple$ScriptA"
        }, {
            "className" : "com.JsonExemple$ScriptB",
            "keep" : 50
        } ]
    }
    Here's a simplified snippet of what I'm trying to achieve:

    Code:
    package com;
    
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonTypeInfo;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.ObjectWriter;
    import com.fasterxml.jackson.databind.SerializationFeature;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author clem585
     *  @[Only registered and activated users can see links. ]d 28/02/2021 - 1:43 AM
     */
    public class JsonExemple {
    
        public static void main(String[] args) {
            try {
                // create Jackson JSON writer
                ObjectMapper saveMapper = new ObjectMapper()
                        .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    
                ObjectWriter saveWriter = saveMapper.writer().withDefaultPrettyPrinter();
    
                // instantiate class I want to save
                ExempleClass exempleClass = new ExempleClass();
    
                // create empty file
                File file = new File("D:/Desktop/exemple.json");
                new File("D:/Desktop/").mkdirs();
                file.createNewFile();
    
                saveWriter.writeValue(file, exempleClass);
                System.out.println("Saved exemple.json on the desktop of the D drive");
            } catch (Exception e) {
                System.out.println("Exception attempting to save exemple");
                e.printStackTrace();
            }
        }
    
        private static class ScriptB extends Script {
             @[Only registered and activated users can see links. ]Property
            private int keep;
    
            public ScriptB() {
                keep = 50;
            }
        }
    
        // ignore this class
        private static class ScriptA extends Script {
            private int dontKeep;
    
            public ScriptA() {
                dontKeep = 25;
            }
        }
    
         @[Only registered and activated users can see links. ]TypeInfo(use = JsonTypeInfo.Id.CLASS, property = "className")
        private static abstract class Script {
    
        }
    
        private static class ExempleClass {
             @[Only registered and activated users can see links. ]Property
            private List<Script> scripts;
    
            public ExempleClass() {
                scripts = new ArrayList<>();
                scripts.add(new ScriptA());
                scripts.add(new ScriptB());
            }
        }
    
    }
    Edit: Ended up getting some help and the easy answer seems to be to use a custom getters for the scripts:

    Code:
        @[Only registered and activated users can see links. ]Property("playerScripts")
        private List<PlayerScript> filterScriptsForJson() {
            return playerScripts.stream()
                    .filter(s -> s.getClass().getAnnotation(JsonIgnoreType.class) == null)
                    .collect(Collectors.toList());
        }
    Project thread
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  2. #2  
    Mug Club


    Join Date
    Jul 2011
    Age
    26
    Posts
    1,872
    Thanks given
    509
    Thanks received
    890
    Rep Power
    332
    Does declaring the variable as transient not work in this case? lol


    My Open Source Projects
    [Only registered and activated users can see links. ]
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  3. #3  
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,547
    Thanks given
    646
    Thanks received
    637
    Rep Power
    334
    Quote Originally Posted by Makar View Post
    Does declaring the variable as transient not work in this case? lol
    I still want to save some scripts, but not all of them.

    Skip all:

    Code:
    private transient List<PlayerScript> playerScripts;
    Partial skip:

    Code:
        @[Only registered and activated users can see links. ]Property("playerScripts")
        private List<PlayerScript> filterScriptsForJson() {
            return playerScripts.stream()
                    .filter(s -> s.getClass().getAnnotation(JsonIgnoreType.class) == null)
                    .collect(Collectors.toList());
        }
    Skip none:

    Code:
    private List<PlayerScript> playerScripts;
    Project thread
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  4. #4  
    Mug Club


    Join Date
    Jul 2011
    Age
    26
    Posts
    1,872
    Thanks given
    509
    Thanks received
    890
    Rep Power
    332
    Quote Originally Posted by clem585 View Post
    I still want to save some scripts, but not all of them.

    Skip all:

    Code:
    private transient List<PlayerScript> playerScripts;
    Partial skip:

    Code:
        @[Only registered and activated users can see links. ]Property("playerScripts")
        private List<PlayerScript> filterScriptsForJson() {
            return playerScripts.stream()
                    .filter(s -> s.getClass().getAnnotation(JsonIgnoreType.class) == null)
                    .collect(Collectors.toList());
        }
    Skip none:

    Code:
    private List<PlayerScript> playerScripts;
    Ah I see what you're going for then. That makes sense.


    My Open Source Projects
    [Only registered and activated users can see links. ]
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  5. #5  
    Registered Member

    Join Date
    Feb 2010
    Posts
    3,185
    Thanks given
    1,124
    Thanks received
    831
    Rep Power
    1508
    deserialise polymorphic types with
    Code:
      @[Only registered and activated users can see links. ]TypeInfo(use=Id.DEDUCTION)
    as such [Only registered and activated users can see links. ]
    Reply With Quote  
     

  6. Thankful user:


  7. #6  
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,547
    Thanks given
    646
    Thanks received
    637
    Rep Power
    334
    Quote Originally Posted by Fire Cape View Post
    deserialise polymorphic types with
    Code:
      @[Only registered and activated users can see links. ]TypeInfo(use=Id.DEDUCTION)
    as such [Only registered and activated users can see links. ]
    Oh I just used:

    Code:
    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "className")
    instead. Any advantage to using that method instead?
    Project thread
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  8. #7  
    Registered Member

    Join Date
    Feb 2010
    Posts
    3,185
    Thanks given
    1,124
    Thanks received
    831
    Rep Power
    1508
    Quote Originally Posted by clem585 View Post
    Oh I just used:

    Code:
    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "className")
    instead. Any advantage to using that method instead?
    if i have understood your issue correctly you want a way to tell jackson to only serialise the types in a list belonging to a particular subclass (that has a polymorphic relationship) so your issue is jackson needs to be able to distinguish between instances of A and B (without treating them as the same type)

    if my assumption is correct take a look at the above article, you can use DEDUCTION to exclude instances of B from serialisation based on the presence of a particular property, this should mean you can skip them when you deal with a list like the above
    Reply With Quote  
     

  9. #8  
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,547
    Thanks given
    646
    Thanks received
    637
    Rep Power
    334
    Quote Originally Posted by Fire Cape View Post
    if i have understood your issue correctly you want a way to tell jackson to only serialise the types in a list belonging to a particular subclass (that has a polymorphic relationship) so your issue is jackson needs to be able to distinguish between instances of A and B (without treating them as the same type)

    if my assumption is correct take a look at the above article, you can use DEDUCTION to exclude instances of B from serialisation based on the presence of a particular property, this should mean you can skip them when you deal with a list like the above
    This is just a way to add custom type identifiers during serialization (VS just using class name). It's a bit more work since you have to specify a type for each script with @[Only registered and activated users can see links. ]TypeName("name") instead of the player script doing it automatically with the annotation code I posted. At the end of the day you would still need the @[Only registered and activated users can see links. ]Property getter to exclude the scripts as this would just provide a different mean of identifying the original class during deserialization, nothing to do with filtering. Thanks for the suggestion though!
    Project thread
    [Only registered and activated users can see links. ]
    Reply With Quote  
     


Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Replies: 0
    Last Post: 02-09-2016, 10:08 PM
  2. Refactored ItemExtra class (from 666)
    By Discardedx2 in forum Snippets
    Replies: 6
    Last Post: 12-27-2012, 04:40 PM
  3. NPC Combat Classes from a Text File
    By Taylor Moon in forum Help
    Replies: 7
    Last Post: 12-24-2012, 05:47 PM
  4. Replies: 2
    Last Post: 06-22-2009, 10:03 PM
  5. Fully refactored Buffer class from 194
    By veer in forum Snippets
    Replies: 2
    Last Post: 03-01-2009, 05:23 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •