【问题标题】:java library for parsing javaScript objects with numeric keys用于解析带有数字键的 JavaScript 对象的 java 库
【发布时间】:2012-03-15 08:20:25
【问题描述】:

我在解析从 Web 服务器接收到的 javaScript 对象时遇到了一些问题。 这些对象应该是 JSON,但包含数字键。

javaScript 对象:

{a: "alpha", 2: "two"}   

问题是如何在 java 中解码这样的 javascript 对象? 有没有可以使用的现有库?如果有如何在 java 中表示该对象:

public class JavaObject {
   private String a;           // for field - a: "alpha"
   private ???                 // for field - 2: "two"
}

谢谢

【问题讨论】:

  • JavaScript 对象键总是字符串;你可以写a,这使得键"a",而2变成"2"。当你JSON.stringify一个对象时,它的所有键都会被引用。
  • 10 倍的答案。在 JSON.stringify 之后,可以将我的 javaScript 数据解码为 JSONObject,但仍无法将数据表示为 java 类。 :(

标签: javascript json key numeric


【解决方案1】:

由于我在网络上没有找到任何解决我的问题的方法,我自己实现了一个 GSON 库的适配器来处理此类数据。

众所周知,JSON 仅支持字符串键。 如果 a 有这样的 json 数据 {"a": "alpha", "2": "two", "3":3} 我可以将其转换为常规 JSONObject,但我仍然无法将其转换为我自己的 java 对象。 为了处理这种情况,我创建了一个 ObjectMap 对象

// ObjectMap.java
import java.util.Map;

public class ObjectMap<V> {

    private Map<String, V> map;

    public ObjectMap(Map<String, V> map) {
        setMap(map);
    }

    public Map<String, V> getMap() {
        return map;
    }

    public void setMap(Map<String, V> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "ObjectMap [map=" + map + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((map == null) ? 0 : map.hashCode());
        return result;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ObjectMap other = (ObjectMap) obj;
        if (map == null) {
            if (other.map != null)
                return false;
        } else if (!map.equals(other.map))
            return false;
        return true;
    }
}

还有一个用于它的 gson 适配器 ObjectMapAdapter。

//ObjectMapAdapter.java
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

public class ObjectMapAdapter<V> extends TypeAdapter<ObjectMap<V>> {

    public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public <T> TypeAdapter create(Gson gson, TypeToken<T> typeToken) {

            Type type = typeToken.getType();
            Class<? super T> rawType = typeToken.getRawType();

            if (!ObjectMap.class.isAssignableFrom(rawType)) {
                return null;
            }

            // if (rawType != ObjectMap.class) {
            // return null;
            // }

            Type componentType;
            if (type instanceof ParameterizedType) {
                componentType = ((ParameterizedType) type).getActualTypeArguments()[0];
            } else {
                componentType = Object.class;
            }

            TypeAdapter<?> componentTypeAdapter = gson.getAdapter(TypeToken.get(componentType));
            return new ObjectMapAdapter(gson, componentTypeAdapter, $Gson$Types.getRawType(componentType));

        }
    };

    // private final Class<V> valueType;
    private final TypeAdapter<V> valueTypeAdapter;

    public ObjectMapAdapter(Gson context, TypeAdapter<V> componentTypeAdapter, Class<V> componentType) {
        this.valueTypeAdapter = new TypeAdapterRuntimeTypeWrapper<V>(context, componentTypeAdapter, componentType);
        // this.valueType = componentType;
    }

    public ObjectMap<V> read(JsonReader in) throws IOException {

        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }

        Map<String, V> map = new LinkedHashMap<String, V>();
        in.beginObject();
        while (in.hasNext()) {
            String key = in.nextName();
            V comp = valueTypeAdapter.read(in);
            map.put(key, comp);
        }
        in.endObject();

        return new ObjectMap<V>(map);
    }

    @Override
    public void write(JsonWriter out, ObjectMap<V> map) throws IOException {
        if (map == null) {
            out.nullValue();
            return;
        }

        out.beginObject();
        for (Entry<String, V> entry : map.getMap().entrySet()) {
            out.name(entry.getKey());
            valueTypeAdapter.write(out, entry.getValue());
        }
        out.endObject();
    }
}

创建自定义 GSON 构建器并注册此工厂

gsonBuilder.registerTypeAdapterFactory(ObjectMapAdapter.FACTORY);

你已经准备好像这样解码数据了

{"a": "alpha", "2": "two", "3":3}

进入地图

ObjectMap [map={a=alpha, 2=two, 3=3}]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多