Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jackson: converting JSON which contains object class to Map

Object Class:

class User{
    public String name;
    public String password;
}

JSON:

{ sc:"200", msg:"something", userInfo:{name:"n", password:"p"} }

I want to get results like this:

Map->contains 3 key-value
"sc"="200"
"msg"="something"
"userInfo"=User(Object Class)

How can I do this? Or, how can I get it to use another JAR tools package?

like image 962
YETI Avatar asked Dec 06 '11 13:12

YETI


2 Answers

You have to choose if you want "untyped" (Maps, Lists, wrappers), which are easy enough to get:

Map<String,Object> map = new ObjectMapper().readValue(json, Map.class);

or POJOs. The thing is, mapper really can't know that you want "userInfo" to map to a specific object, but other values to something else.

But I would rather just create another class, like:

public class Request {
   public int sc;
   public String message;
   public User userInfo;
   // and/or getters, setters, if you prefer
}

and bind to that:

Request req = new ObjectMapper().readValue(json, Request.class);

Why mess with inconvenient Maps when you can have real POJOs, right? :)

like image 87
StaxMan Avatar answered Oct 05 '22 07:10

StaxMan


As a slight modification of StaxMan's answer, if it's somehow desirable to have everything that is not the User object in a map, Jackson provides the @JsonAnySetter and @JsonAnyGetter annotations to get the job done. The following example demonstrates how this might be used.

import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    // {"sc":"200","msg":"something","userInfo":{"name":"n","password":"p"}}
    String jsonInput = "{\"sc\":\"200\",\"msg\":\"something\",\"userInfo\":{\"name\":\"n\",\"password\":\"p\"}}";

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);

    Result result = mapper.readValue(jsonInput, Result.class);
    System.out.println(result);
    // output: 
    // Result: userInfo=User: name=n, password=p, otherThings={sc=200, msg=something}
  }
}

class Result
{
  Map otherThings = new HashMap();
  User userInfo;

  @JsonAnySetter
  void addThing(String key, Object value)
  {
    otherThings.put(key, value);
  }

  @Override
  public String toString()
  {
    return String.format("Result: userInfo=%s, otherThings=%s", userInfo, otherThings);
  }
}

class User
{
  String name;
  String password;

  @Override
  public String toString()
  {
    return String.format("User: name=%s, password=%s", name, password);
  }
}
like image 35
Programmer Bruce Avatar answered Oct 05 '22 08:10

Programmer Bruce