Deserializing JSON with special characters into a string
Asked Answered
H

1

6

I'm trying to parse a json file that looks like this

{
  "foo": "v2",
  "bar": [
    "abc/bcf<object@twenty>.xyz",
    "abc/fgh<object@thirtu>.xyz"
  ]
}

The code I have is currently this:

Config.java

private static final ObjectMapper OBJECT_MAPPER;

    static {
        OBJECT_MAPPER = new ObjectMapper();
     OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        OBJECT_MAPPER.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
        OBJECT_MAPPER.enableDefaultTyping();
    }

@JsonCreator
    public Config(
            @JsonProperty(value = "foo", required = true) final String version,
            @JsonProperty(value = "bar") final List<String> barTypes) {
     // rest of constructor
}

public static Config fromJson(final Reader reader)
            throws IOException {
        return OBJECT_MAPPER.readValue(reader, Config.class);
}

I am getting an error:

Failed to parse type 'abc/bcf<object@twenty>.xyz' (remaining: '<object@twenty>.xyz'): Cannot locate class 'abc/bcf', problem: abc/bcf"

Is there something special I need to do in order to read "<" as String?

I'm reading the file into a BufferReader with StandardCharsets.UTF_8 like this:

try (BufferedReader reader = Files.newBufferedReader(configFile.toPath(), StandardCharsets.UTF_8)) {
            config = Config.fromJson(reader);
}

Edit: I actually do need defaultTyping for an ArrayList that has polymorphic types:

"Vehicles": [
    "java.util.ArrayList",
    [
      {
        "name": "Car"
      },
      {
        "name": "Train"
      }
   ]

I currently use a MixIn for declaring the subtypes. However, this stops working if I remove DefaultTyping.
Haemophilic answered 9/6, 2020 at 2:22 Comment(8)
You didn't include the contents of this fromJson method.Edmundoedmunds
Done @chrylis-cautiouslyoptimistic- :)Haemophilic
This is strange. What happens if you go with a traditional-type POJO with a default constructor and setter methods instead of the creator constructor?Edmundoedmunds
(As a note, "treat unknown enum values as null" is generally dangerous, and I don't recommend it.)Edmundoedmunds
Works fine when you directly use json as String OBJECT_MAPPER.readValue(JSON_STRING, Config.class); but fails when reading from file.Gurdwara
It works if you remove OBJECT_MAPPER.enableDefaultTyping();Gurdwara
do you need enableDefaultTyping option? try to remove it, it looks like Jackson tries to deserialize "abc/bcf<object@twenty>.xyz" as an object and tries to find a class with this nameEcchymosis
I do need to use OBJECT_MAPPER.enableDefaultTyping() :( Any other solution?Haemophilic
G
0

Remove OBJECT_MAPPER.enableDefaultTyping(); and it will work fine. This method is anyway deprecated.

In case you want to read automatic polymorphic types, use activateDefaultTyping(PolymorphicTypeValidator ptv).

Gurdwara answered 9/6, 2020 at 5:38 Comment(4)
Yes that indeed was the issue. I removed it and it worked. :)Haemophilic
I do need to use DefaultTyping. :(Haemophilic
In that case you should have a class corresponding to abc/fgh<object@thirtu>.xyz, you can read a bit about default typing at jackson docs.Gurdwara
Also, instead of editing the question, you can create a new question with details related to requirement.Gurdwara

© 2022 - 2024 — McMap. All rights reserved.