Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for deseralization with no type information. #16

Closed
JakeAngell opened this issue Nov 23, 2016 · 13 comments
Closed

Support for deseralization with no type information. #16

JakeAngell opened this issue Nov 23, 2016 · 13 comments

Comments

@JakeAngell
Copy link

Jackson will default to using LinkedHashMap to represent JSON where there is no type information given, or the type information is given as Object.class.

Is there any support for this type of behaviour with dsl-json?

I am looking to deserialize json where a field may have varying types. For example, in my model class I have an instance variable declared as Map<String, Object> fieldName. The object value may be represented in the JSON as a string, int, object or array etc. Does dsl-json support a method of generically deserializing this into some sort of structure so it can be accessed from the instance variable.

Here is an example of some JSON that I hope to deserialize into a Map<String, Object>

 "fieldName": {
            "alwaysString": {
                "fieldInsideObject": 5
            },
            "anotherString": 40
        }

Thanks

@zapov
Copy link
Member

zapov commented Nov 23, 2016

Yes, you can use converter in property annotation.

@JakeAngell
Copy link
Author

Will the databinding have to be done manually? The json structure may be different every time.

@zapov
Copy link
Member

zapov commented Nov 23, 2016

Not sure what you mean by manually.
You will have to set up your own converter. You can reuse existing methods from library.
For example:

@JsonAttribute(converter=MyConverter.class)
public Object property;

class MyConverter {
  public static final JsonReader.ReadObject<Object> JSON_READER = new JsonReader.ReadObject<Object>() {
    public Object read(JsonReader reader) throws IOException {
      return DslJson.deserializeObject(reader);
    }
  };
  public static final JsonWriter.WriteObject<Object> JSON_WRITER = null;
}

You can find working example at: https://github.com/ngs-doo/dsl-json/blob/master/examples/Maven/src/main/java/com/dslplatform/maven/Example.java#L33

@JakeAngell
Copy link
Author

JakeAngell commented Nov 23, 2016

Okay great I think that's what I'm looking for. However, in the case of your SupportArrayList example you call a method deserializeIntNullableCollection. As far as I know there is no equivalent for a Map on the NumberConverter class?

@zapov
Copy link
Member

zapov commented Nov 23, 2016

https://github.com/ngs-doo/dsl-json/blob/master/library/src/main/java/com/dslplatform/json/DslJson.java#L477

@JakeAngell
Copy link
Author

Ah it's in the DslJson class, perfect. Thanks again.

@zapov
Copy link
Member

zapov commented Nov 23, 2016

np :)

@zapov zapov closed this as completed Nov 23, 2016
@JakeAngell
Copy link
Author

Okay so using the following custom conversion class works fine apart from some unusual type resolving.

public class ExtConverter {
    public static final JsonReader.ReadObject<Map<String, Object>> JSON_READER = new JsonReader.ReadObject<Map<String, Object>>() {
        @Override
        public Map<String, Object> read(JsonReader jsonReader) throws IOException {
            return DslJson.deserializeMap(jsonReader);
        }
    };

This converter, when deserializing the following JSON will resolve the field skippable into a Long, and the player_type field into a Big Decimal.

 "ext": {
                "skippable": 2,
                "player_type": 2
            }

However, adding a trailing space to skippable's field value (as below) causes it to resolve into a BigDecimal along with player_type.

 "ext": {
                "skippable": 2 ,
                "player_type": 2
            }

Is this expected behaviour? Is there any way to change how the types are resolved? Ideally the above JSON should resolve into ints.

Thanks,
Jake

@zapov
Copy link
Member

zapov commented Nov 24, 2016

Yes, this is the expected behavior.
Fast path is not chosen because there is trailing whitespace after the number.

The issue is that in: https://github.com/ngs-doo/dsl-json/blob/master/library/src/main/java/com/dslplatform/json/NumberConverter.java#L1055
stops at the , instead of whitespace.
This causes it to go into slow path.

It's only an issue for this generic JSON parsing (when there are no types).

@zapov
Copy link
Member

zapov commented Nov 24, 2016

If you wish to change how types are resolved... you'll have to write/copy paste your own number and map converters :(

@zapov
Copy link
Member

zapov commented Nov 24, 2016

Hm... thinking about it some more... it's true that this could be improved...

I'll look into it when I find some free time.

@JakeAngell
Copy link
Author

Thanks, will code around the problem for now. Aside from that great work on the library

@zapov
Copy link
Member

zapov commented Nov 28, 2016

I've released 1.2.1 with fixes for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants