使用javax.json从JSON String到Java Object [英] From JSON String to Java Object using javax.json

查看:348
本文介绍了使用javax.json从JSON String到Java Object的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 com.google.gson.Gson API将JSON字符串转换为Java对象:

I'm using the com.google.gson.Gson API to convert a JSON string to a Java object:

Gson gson = new Gson();
User u = gson.fromJson(jsonString, User.class);

我想知道 javax.json中是否存在等效的API api做同等的事情。
谢谢!

I'd like to know if there's an equivalent API in javax.json api to do the equivalent. Thanks!

推荐答案

对于像Gson一样的oneliner,这绝对是不可能的。 javax.json API的级别非常低。它只返回一个JSON对象结构,你需要将其细分并进一步映射到javabean。

This is definitely not possible with an oneliner like as with Gson. The javax.json API is very low level. It only returns you a JSON object structure which you've to breakdown and map to a javabean further all by yourself.

为了达到(几乎)相同的效果 Gson#fromJson(),这是样板代码的启动示例。在某种程度上支持参数化类型和javabeans。它是所有标准的Java SE API,javabeans在 java.beans API的帮助下进行了内省。

In order to achieve (nearly) the same effect as Gson#fromJson(), here's a kickoff example of the boilerplate code. Parameterized types and javabeans are supported to certain extent. It's all standard Java SE API, the javabeans are introspected with little help of java.beans API.

@SuppressWarnings("unchecked")
public static <T> T fromJson(String json, Class<T> beanClass) {
    JsonValue value = Json.createReader(new StringReader(json)).read();
    return (T) decode(value, beanClass);
}

private static Object decode(JsonValue jsonValue, Type targetType) {
    if (jsonValue.getValueType() == ValueType.NULL) {
        return null;
    }
    else if (jsonValue.getValueType() == ValueType.TRUE || jsonValue.getValueType() == ValueType.FALSE) {
        return decodeBoolean(jsonValue, targetType);
    }
    else if (jsonValue instanceof JsonNumber) {
        return decodeNumber((JsonNumber) jsonValue, targetType);
    }
    else if (jsonValue instanceof JsonString) {
        return decodeString((JsonString) jsonValue, targetType);
    }
    else if (jsonValue instanceof JsonArray) {
        return decodeArray((JsonArray) jsonValue, targetType);
    }
    else if (jsonValue instanceof JsonObject) {
        return decodeObject((JsonObject) jsonValue, targetType);
    }
    else {
        throw new UnsupportedOperationException("Unsupported json value: " + jsonValue);
    }
}

private static Object decodeBoolean(JsonValue jsonValue, Type targetType) {
    if (targetType == boolean.class || targetType == Boolean.class) {
        return Boolean.valueOf(jsonValue.toString());
    }
    else {
        throw new UnsupportedOperationException("Unsupported boolean type: " + targetType);
    }
}

private static Object decodeNumber(JsonNumber jsonNumber, Type targetType) {
    if (targetType == int.class || targetType == Integer.class) {
        return jsonNumber.intValue();
    }
    else if (targetType == long.class || targetType == Long.class) {
        return jsonNumber.longValue();
    }
    else {
        throw new UnsupportedOperationException("Unsupported number type: " + targetType);
    }
}

private static Object decodeString(JsonString jsonString, Type targetType) {
    if (targetType == String.class) {
        return jsonString.getString();
    }
    else if (targetType == Date.class) {
        try {
            return new SimpleDateFormat("MMM dd, yyyy H:mm:ss a", Locale.ENGLISH).parse(jsonString.getString()); // This is default Gson format. Alter if necessary.
        }
        catch (ParseException e) {
            throw new UnsupportedOperationException("Unsupported date format: " + jsonString.getString());
        }
    }
    else {
        throw new UnsupportedOperationException("Unsupported string type: " + targetType);
    }
}

private static Object decodeArray(JsonArray jsonArray, Type targetType) {
    Class<?> targetClass = (Class<?>) ((targetType instanceof ParameterizedType) ? ((ParameterizedType) targetType).getRawType() : targetType);

    if (List.class.isAssignableFrom(targetClass)) {
        Class<?> elementClass = (Class<?>) ((ParameterizedType) targetType).getActualTypeArguments()[0];
        List<Object> list = new ArrayList<>();

        for (JsonValue item : jsonArray) {
            list.add(decode(item, elementClass));
        }

        return list;
    }
    else if (targetClass.isArray()) {
        Class<?> elementClass = targetClass.getComponentType();
        Object array = Array.newInstance(elementClass, jsonArray.size());

        for (int i = 0; i < jsonArray.size(); i++) {
            Array.set(array, i, decode(jsonArray.get(i), elementClass));
        }

        return array;
    }
    else {
        throw new UnsupportedOperationException("Unsupported array type: " + targetClass);
    }
}

private static Object decodeObject(JsonObject object, Type targetType) {
    Class<?> targetClass = (Class<?>) ((targetType instanceof ParameterizedType) ? ((ParameterizedType) targetType).getRawType() : targetType);

    if (Map.class.isAssignableFrom(targetClass)) {
        Class<?> valueClass = (Class<?>) ((ParameterizedType) targetType).getActualTypeArguments()[1];
        Map<String, Object> map = new LinkedHashMap<>();

        for (Entry<String, JsonValue> entry : object.entrySet()) {
            map.put(entry.getKey(), decode(entry.getValue(), valueClass));
        }

        return map;
    }
    else try {
        Object bean = targetClass.newInstance();

        for (PropertyDescriptor property : Introspector.getBeanInfo(targetClass).getPropertyDescriptors()) {
            if (property.getWriteMethod() != null && object.containsKey(property.getName())) {
                property.getWriteMethod().invoke(bean, decode(object.get(property.getName()), property.getWriteMethod().getGenericParameterTypes()[0]));
            }
        }

        return bean;
    }
    catch (Exception e) {
        throw new UnsupportedOperationException("Unsupported object type: " + targetClass, e);
    }
}

用法:

User u = YourJsonUtil.fromJson(jsonString, User.class);

如果您看到 UnsupportedOperationException 来自 decodeXxx()方法之一,只需将所需的转换逻辑添加到相关方法中。当然,这可以进一步重构以应用策略模式,以便它具有灵活性和可扩展性,但是我们基本上重新发明了Gson。

In case you're seeing an UnsupportedOperationException coming from one of decodeXxx() methods, just add the desired conversion logic to the method in question. Of course this could be refactored further to apply the strategy pattern and such so that it's flexible and extensible, but then we're basically reinventing Gson.

这篇关于使用javax.json从JSON String到Java Object的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆