Java:Jackson多态JSON反序列化与基本抽象类/接口及其实现?

时间:2014-02-04 17:05:23

标签: java json serialization

我遇到了对Java Object反序列化JSON的问题:

Json Model看起来像:

{
   "name":"q",
   "userId":"1",
   "expression":
   {
    "_type":"Expressions.BinaryExpression",
    "left":
     {
        "_type":"Expressions.MemberExpression",
        "name":"PID_DOB"
     },
     "right":
     {
      "_type":"Expressions.ConstantExpression",
      "value":"2/3/2014","type":"date"
     },

     "binaryType":"Equal"
    }
}

映射对象:

public class QueryDTO implements java.io.Serializable
{

    private static final long serialVersionUID = 696730802013569236L;

    private Long id;
    private String name;
    private long userId;
    private String visibility = "private";

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "expression")
    @JsonSubTypes(
    {
            @Type(value = BinaryExpression.class, name = "Expressions.BinaryExpression"),
            @Type(value = ConstantExpression.class, name = "Expressions.ConstantExpression"),
            @Type(value = MemberExpression.class, name = "Expressions.MemberExpression"),
            @Type(value = UnaryExpression.class, name = "Expressions.UnaryExpression"),
            @Type(value = MethodExpression.class, name = "Expressions.MethodExpression")
    })
    private Expression expression;

    public QueryDTO()
    {
        super();
    }

    public QueryDTO(Long id, String name, long userId, String visibility, Expression expression)
    {

        super();
        this.id = id;
        this.name = name;
        this.userId = userId;
        this.visibility = visibility;
        this.expression = expression;

    }

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getVisibility()
    {
        return visibility;
    }

    public void setVisibility(String visibility)
    {
        this.visibility = visibility;
    }

    public Expression getExpression()
    {
        return expression;
    }

    public void setExpression(Expression expression)
    {
        this.expression = expression;
    }

    public long getUserId()
    {
        return userId;
    }

    public void setUserId(long userId)
    {
        this.userId = userId;
    }
}


public interface Expression
{
}

public class BinaryExpression implements Expression {

    private Expression left;
    private Expression right;
    private BinaryTypes binaryType;


    @JsonCreator
    public BinaryExpression(
            @JsonProperty("left") Expression left, 
            @JsonProperty("right") Expression right, 
            @JsonProperty("expressionType") BinaryTypes expressionType ) {
        this.left = left;
        this.right = right;
        this.binaryType = expressionType;
    }

    /**
     * The binary operation type
     */
    public BinaryTypes getBinaryType() {
        return binaryType;
    }

    /**
     * The left expression
     */
    public Expression getLeft() {
        return left;
    }

    /**
     * The right expression
     */
    public Expression getRight() {
        return right;
    }
}

public enum BinaryTypes {
    Equal,
    NotEqual,
    LessThan,
    GreaterThan,
    LessThanOrEqual,
    GreaterThanOrEqual,
    AndAlso,
    And,
    Or,
    OrElse

}

public class ConstantExpression implements Expression {
    private Object value;
    private Class<?> type;

    @JsonCreator
    public ConstantExpression(
            @JsonProperty("value") Object value, 
            @JsonProperty("type") Class<?> type) {
        this.value = value;
        this.type = type;
    }



    public ConstantExpression(Object value) {
        this.value = value;
        this.type = value.getClass();
    }

    /**
     * The type of the value of this constant expression
     */
    public Class<?> getType() {
        return type;
    }

    /**
     * The value of the constant expression
     */
    public Object getValue() {
        return value;
    }
}


public class MemberExpression implements Expression {

    private String name;

    @JsonCreator
    public MemberExpression(@JsonProperty("name") String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}


public class MethodExpression implements Expression {

    private MemberExpression declaringType;
    private String name;
    private ArrayList<Expression> arguments ;

    public MethodExpression(MemberExpression member, String name, Iterable<Expression> arguments) {
        this.declaringType = member;
        this.name = name;
        this.arguments = new ArrayList<Expression>();
        for (Expression expression : arguments) {
            this.arguments.add(expression);
        }
    }



    public ArrayList<Expression> getArguments() {
        return arguments;
    }

    public MemberExpression getDeclaringType() {
        return declaringType;
    }

    public String getName() {
        return name;
    }

}

public class UnaryExpression implements Expression {
    private UnaryTypes expressionType;
    private Expression expression;

    @JsonCreator
    public UnaryExpression(
            @JsonProperty("expression") Expression expression, 
            @JsonProperty("expressionType") UnaryTypes expressionType) {
        this.expression = expression;
        this.expressionType = expressionType;
    }

    public Expression getExpression() {
        return expression;
    }

    public UnaryTypes getExpressionType() {
        return expressionType;
    }
}

public enum UnaryTypes {
    Not
}

低于错误: JsonTest:

public class JSONTest
{

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
        try
        {
            ClassLoader classloader = Thread.currentThread().getContextClassLoader();
            InputStream is = classloader.getResourceAsStream("query.json");
            //mapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
            QueryDTO queryDTO = mapper.readValue(is, QueryDTO.class);
            System.out.println(queryDTO);
        }
        catch (JsonParseException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (JsonMappingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

org.codehaus.jackson.map.JsonMappingException:无法构造Expressions.Expression的实例,问题:抽象类型只能用其他类型信息实例化  在[来源:java.io.BufferedInputStream@3e0694a5; line:3,column:14](通过引用链:xx.xx.xx.xx.QueryDTO [“expression”])

0 个答案:

没有答案