用json(Jackson框架)将类转换为另一个类

时间:2015-08-02 09:28:59

标签: java json jackson

两个类具有相似的字段,但它们没有超类。在我的代码中:FirstSecond类。我需要编写方法convertToAnother,什么是类resultClassObject的返回对象,其中包含来自对象one的字段值。 这两个类都有Json注释。该注释具有属性的vaule等于小写的类的名称(在我的代码类First中有className = "first"

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.StringReader

public class Solution {
    public static void main(String[] args) throws IOException {
        Second s = (Second) convertOneToAnother(new First(), Second.class);
        First f = (First) convertOneToAnother(new Second(), First.class);
    }

    public static Object convertOneToAnother(Object one, Class resultClassObject) throws IOException {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String obj = mapper.writeValueAsString(one);
            obj = obj.replace("\"className\":\"" + one.getClass().getSimpleName().toLowerCase() + "\"", "\"className\":\"" + resultClassObject.getSimpleName().toLowerCase() + "\"");
            return new ObjectMapper().readValue(new StringReader(obj), resultClassObject);
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,  property="className")
    @JsonSubTypes(@JsonSubTypes.Type(value=First.class,  name="first"))
    public static class First {
        public int i;
        public String name;
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,  property="className")
    @JsonSubTypes(@JsonSubTypes.Type(value=Second.class, name="second"))
    public static class Second {
        public int i;
        public String name;
    }
}

也许存在另一个决定?

5 个答案:

答案 0 :(得分:1)

我想提供这样的解决方案,例如First类:

First first = new First();
first.i = 1;
first.name = "first";
Second s = (Second) convertOneToAnother(first, Second.class);
System.out.println(s.name); // first

ObjectMapper mapper = new ObjectMapper();

// here we disable uses annototions, since by the condition of the 
// problem, we have two classes have similar fields
mapper.disable(MapperFeature.USE_ANNOTATIONS);

StringWriter writer = new StringWriter();
mapper.writeValue(writer, one);
//writer.toString() == {"i":1,"name":"first"}

mapper.readValue(writer.toString, resultClassObject);

如果我们不使用mapper.disable()方法,我们将为编写者提供诸如字符串{"className":"first","i":1,"name":"first"}

答案 1 :(得分:0)

使用jackson执行此操作的唯一正确方法是将实例编组为json然后取消编组。我建议在java对象的级别上使用convertion - 使用Dozer:http://dozer.sourceforge.net

答案 2 :(得分:0)

对于这种任务,使用像Dozer(http://dozer.sourceforge.net/

这样的对象映射器是正确的

答案 3 :(得分:0)

You can replace value of className without String manipulations

ObjectReader reader = mapper.reader();

JsonNode node = reader.readTree(writer.toString());

((ObjectNode)node).put("className",resultClassObject.getSimpleName().toLowerCase());

Also if you don't know the name of the field where name of the class is stored, but you know it is in the annotations, you can try and get the first field from JsonNode (in your code you assume that the field name is "className", but what if it is not).

ObjectMapper mapper1 = new ObjectMapper();
Map<String, Object> result = mapper1.convertValue(node, Map.class);
String key1 = result.keySet().toArray()[0].toString();

And now you can replace the value for the key1 field, which should be the field where class name is stored.

答案 4 :(得分:0)

您可以为模型映射编写如下代码:

public class ModelConverter {

public static void main(String[] args) throws IOException {
    Test1 t1 = new Test1();
    ObjectMapper mapper1 = new ObjectMapper();
    String jsonString = mapper1.writeValueAsString(t1);
    System.out.println(jsonString);
    Test2 t2 = mapper1.readValue(jsonString, Test2.class);
    System.out.println(t2);
}
}
public class Test1 implements Serializable {
private int i = 10;
private String name = "demo1";
private Test3 test3 = new Test3();

public int getI() {
    return i;
}

public void setI(int i) {
    this.i = i;
}

public String getName() {
    return name;
}

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

public Test3 getTest3() {
    return test3;
}

public void setTest3(Test3 test3) {
    this.test3 = test3;
}

@Override
public String toString() {
    return "test1 [i=" + i + ", name=" + name + ", Test3=" + test3 + "]";
}
}
public class Test2 implements Serializable {
private int i = 11;
private String name = "demo2";
private Test3 test3;

public int getI() {
    return i;
}

public void setI(int i) {
    this.i = i;
}

public String getName() {
    return name;
}

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

public Test3 getTest3() {
    return test3;
}

public void setTest3(Test3 test3) {
    this.test3 = test3;
}

@Override
public String toString() {
    return "test2 [i=" + i + ", name=" + name + ", Test3=" + test3 + "]";
}
}

public class Test3 implements Serializable {
private int i = 12;
private String name = "demo3";

public int getI() {
    return i;
}

public void setI(int i) {
    this.i = i;
}

public String getName() {
    return name;
}

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

@Override
public String toString() {
    return "test3 [i=" + i + ", name=" + name + "]";
}
}