2

I have a slightly odd question. I have created an object, let's call it a Profile, that successfully parses single JSON objects via an API that I call. There is also a multi-profile interface that will return a JSON array of Profile objects. The problem is, the multi-profile interface turns the sub objects into strings. Is there an automatic way I can tell jackson to parse these into objects?

Example of a single object: { "foo": "bar" }

Example of a multi object: [ "{ \"foo\": \"bar\" }", "{ \"blah\": \"ugh\" }" ]

(Sorry can't use real data)

Notice that the sub objects are actually strings, with escaped quotes inside them.

For completeness, my code for the multi object parse looks like this:

ObjectMapper mapper = new ObjectMapper();
Profile[] profile_array = mapper.readValue(response.content, Profile[].class);
for (Profile p: profile_array)
{
    String user = p.did;
    profiles.put(user, p);
}

As I said, in the single-profile case, the Profile object parses. In the multi-profile case, I get this exception:

Exception: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.xyz.id.profile.Profile, problem: no suitable creator method found to deserialize from JSON String
2
  • Is Profile a class or an interface? Why not just implement fromValue(String) on it and place the parse logic in there? Commented Jun 12, 2012 at 0:56
  • Profile is a class which is a container for the JSON profile object data. Commented Jun 12, 2012 at 18:10

3 Answers 3

2

I suppose you'll have to create a custom deserializer and apply it to the every element of that array.

class MyCustomDeserializer extends JsonDeserializer<Profile> {
    private static ObjectMapper om = new ObjectMapper();

    @Override
    public Profile deserialize(JsonParser jp, DeserializationContext ctxt) {
        // this method is responsible for changing a single text node:
        // "{ \"foo\": \"bar\" }"
        // Into a Profile object

        return om.readValue(jp.getText(), Profile.class);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I was afraid that was the answer. I'll give it a try, thanks.
0

There is no out-of-the-box support for "re-parsing" of embedded JSON-in-JSON content. But this sounds like a possible request for enhancement (RFE)...

Comments

0

Have you tried using JAXB?

            final ObjectMapper mapper = new ObjectMapper();

            // Setting up support of JAXB
            final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

            // make deserializer use JAXB annotations (only)
            mapper.getDeserializationConfig().setAnnotationIntrospector(
                    introspector);

            // make serializer use JAXB annotations (only)
            mapper.getSerializationConfig().setAnnotationIntrospector(
                    introspector);

            final StringReader stringReader = new StringReader(response);
            respGetClasses = mapper.readValue(stringReader,
                    FooBarClass.class);

The above should get you started...

Also, you would need to mark each subclass like so:

@XmlElement(name = "event")
public List<Event> getEvents()
{
    return this.events;
}

4 Comments

While one can use JAXB annotations this way, how would this help with the actual issue at hand?
@StaxMan his issue is that he wants to force the parsing of JSON into complex objects and he is having issues. I'm just putting forward my solution (using JAXB), as I have used it to solve issues like his when I was using the Jackson lib...
Actually I don't think his problem is really that: if you look carefully at JSON sample he is showing, the multi-object case, there is the bigger issue of content being a String, not JSON. But even if it was JSON, there would be structural difference between arrays and objects. This is why I asked: you are showing how to specify property names, which can be useful, but it does not seem to be something submitter is struggling with. So I thought maybe I was missing something here....
@StaxMan - ahhhh, my mistake. Although he is asking how to prevent them from becoming strings, which my solution would help with. Basically he has normal JSON, once he's passed it through his 'multi-profile interface' they are returned as strings rather than objects. I'm approaching this with a view to fix his 'multi-profile interface' rather than parse the strings into an object. But perhaps I'm not understanding the OP correctly, it's happened before, and it'll happen again! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.