Search code examples
javajsonpojo

JSON text to Java conversion issue with random number generation


For example my JSON text is coming like this.

"pages":{"42010":{"pageid":42010,"ns":0,"title":"Queen (band)"}}

Because everytime my json text is coming with different number which is inside pages tag.

How do i convert this to Java equivalent class?

Currently my generated java class is something like this.

@Generated("org.jsonschema2pojo")
public class Pages {

    @SerializedName("42010")
    @Expose
    private _42010 _42010;
}

That _42010 class contains the inner fields like "pageid":42010,"ns":0,"title":"Queen (band)", since i am getting everytime new number inside pages, its not working. its working only for the specific json text.


Solution

  • You can use a custom deserialiser that ignored the changing number. For example:

    package jacksonTest;
    
    import java.io.IOException;
    import java.lang.reflect.Type;
    
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    
    public class CustomDeserialiser {
    
    
    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
        String json = "{\"42010\":{\"pageid\":42010,\"ns\":0,\"title\":\"Queen (band)\"}}";
        String json2 = "{\"12345\":{\"pageid\":12345,\"ns\":0,\"title\":\"Queen (band)\"}}";
    
        Gson g = new GsonBuilder().registerTypeAdapter(Pages.class, new PagesDeserialiser()).create(); 
    
        Pages fromJson = g.fromJson(json, Pages.class);
        System.out.println(fromJson);
    
        fromJson = g.fromJson(json2, Pages.class);
        System.out.println(fromJson);
    }
    
    public static class PagesDeserialiser implements JsonDeserializer<Pages> {
    
        @Override
        public Pages deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                throws com.google.gson.JsonParseException {
            JsonObject object = json.getAsJsonObject();
    
            Pages p = new Pages();
            object.entrySet().forEach( e -> {
                JsonObject tmp = e.getValue().getAsJsonObject();
                if(tmp.get("pageid") != null) {
                    // right object
                    p._42010 = new _42010();
                    p._42010.ns = tmp.get("ns").getAsInt();
                    p._42010.pageid = tmp.get("pageid").getAsInt();
                    p._42010.title = tmp.get("title").getAsString();
                }
            });
    
            return p;
        }
    
    }
    
    public static class Pages {
    
        _42010 _42010;
    
        @Override
        public String toString() {
            return _42010.toString();
        }
    
    
    }
    
    public static class  _42010 {
        int pageid;
        int ns;
        String title;
    
        @Override
        public String toString() {
            return title + " " + pageid + " " + ns;
        }
    }
    

    }

    The deserialiser for type pages simply checks the entries to find the one that contains a pageId and then populates the class.

    Running my test gives you:

    Queen (band) 42010 0
    Queen (band) 12345 0
    

    I am assuming that you are using Gson as your json library.

    Regards,

    Artur