有没有办法从json响应创建bean类

2022-09-03 05:14:52

将 JSON 转换为 Java

上述问题与上述线程中描述的内容有关。有许多 API 提供了以 XML 或 JSON 格式返回响应的灵活性。**我想知道是否有一种方法可以自动构造对应于JSON响应的java bean。**


答案 1

假设你得到一个对象,比如

    [
        {
        "name":"Java 6 Greatest Hits",
        "Author":"Jim Bob Jones",
        "price":10.25
        },
        {
        "name":"How to raise a goat",
        "Author":"Sir Paxton",
        "price":55.97   
        },
        {
        "name":"Snow - It is cold",
        "Author":"Dr. White",
        "price":9.99    
        }
   ]

你想要一个像这样的类

public class Book{
    private String author;
    private String name;
    private Number price
}

使用 getters 和 setters 一种选择是使用像 JSONGen 这样的服务,这将创建该类。您需要首先使用它,并将生成的代码包含在项目中。另一种选择可能是使用javassist或CGLib动态生成类,但除非你使用反射来访问其成员,否则该类将毫无用处,因此即使它是一个类,它的行为也会像一个非常烦人的Map。使用JSONObject绝不会比简单更好


答案 2

似乎一个简单的消息类型实体不符合您的要求?

如果你想将一个json转换为一个已经存在的和已知的java bean类,

许多lib可以这样做,比如

http://json-lib.sourceforge.net/apidocs/net/sf/json/class-use/JSONObject.html

 JSONObject.toBean(JSONObject jsonObject, Class beanClass)
      Creates a bean from a JSONObject, with a specific target class.

顺便说一句,如果您正在与restful webservice进行通信,org.springframework.web.client.RestTemplate将帮助您获得直接的bean结果而不是json。

如果类不存在,则需要具有java反射机制的程序。尝试使用CGLIB,http://cglib.sourceforge.net/,动态创建一些类,如BeanMap。我写了一个简单的示例,但要注意,opearing类字节很难,你可能会遇到JVM的奇怪麻烦。强烈不鼓励这样做。

  public static BeanMap generateBean(JSONObject json) {
    BeanGenerator generator = new BeanGenerator();

    Iterator keys = json.keys();

    while (keys.hasNext()) {
        Object key = keys.next();
        Object value = json.get(key);
        Class keyClass = guessValueClass(value);
        generator.addProperty(key.toString(), keyClass);

    }

    Object result = generator.create();
    BeanMap bean = BeanMap.create(result);
    keys = json.keys();

    while (keys.hasNext()) {
        Object key = keys.next();
        Object value = json.get(key);
        bean.put(key, value);
    }

    return bean;
}

/**
 * TODO fix guess
 */
static Class guessValueClass(Object value) {

    try {
        Integer.parseInt(value.toString());
        return Integer.class;
    } catch (NumberFormatException e1) {

    }
    try {
        Double.parseDouble(value.toString());
        return Double.class;
    } catch (NumberFormatException e1) {

    }
    return String.class;
}