flexjson用点“。”反序列化属性字符串。内

时间:2013-12-11 13:55:51

标签: java json deserialization flexjson

我正在尝试使用flexjson反序列化我从Web调用中获得的字符串。问题是,在属性/键中有一些点,例如:

[{... 
       "contact.name": "Erik Svensson", 
       "contact.mail": "erik.svensson@foo.bar",
       "contact.phone": "0731123243", 
...}]

现在除了这些带点的字符串之外,其他所有内容都会到位,它们在我的目标类中最终为null。我猜它是因为它不知道要映射到什么,因为我不能在我的容器类中声明一个带有点的变量。

这是我现在要反序列化的代码,

mData = new JSONDeserializer<List<Thing>>()
  .use("values", Thing.class)
  .deserialize(reader);

如何修改它以捕获带有点的字符串并将它们放在我的Things类中:

String contactName; 
String contactMail;
String contactPhone;

// getters&setters

注意我对序列化没有任何控制权。

2 个答案:

答案 0 :(得分:0)

好的所以我已经解决了这个问题,但我不得不放弃flexJson。搜索到了所有地方的一个简单的方法,但找不到一个。

相反,我和杰克逊一起去了,这就是我最终的目标:

ObjectMapper mapper = new ObjectMapper();
mThings = mapper.readValue(url, new TypeReference<List<Thing>>() {});

在我班上的事情:

@JsonProperty("contact.name")
private String contactName;

@JsonProperty("contact.mail")
private String contactMail;

@JsonProperty("contact.phone")
private String contactPhone;

// getters and setters..

如果有人知道如何使用FlexJson随意发布答案,我希望看到它。

答案 1 :(得分:0)

我很好奇,如果这种类型的任务可以轻松完成,我已经玩了一些代码,这就是我想出来的。 (我在这里张贴它,因为它可能对某些人有一些相关问题很有帮助,或者只是从一开始就有用。)

PrefixedObjectFactory(见下文)将从JSON对象的字段名称中删除固定前缀,并使用此名称查找匹配的bean属性。可以轻松更改代码以进行替换(例如,将.后面的第一个字母设置为大写并删除.

可以像这样使用:

List<Thing> l = new JSONDeserializer<List<Thing>>().use("values", new PrefixedObjectFactory(Thing.class, "contact.")).deserialize(source);

代码:

import flexjson.ObjectBinder;
import flexjson.ObjectFactory;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Type;
import java.util.Map;

public class PrefixedObjectFactory<T> implements ObjectFactory {

    protected Class<T> clazz;
    protected String prefix;

    public PrefixedObjectFactory(Class<T> c, String prefix) {
        this.clazz = c;
        this.prefix = (prefix == null) ? "" : prefix;
    }

    @Override
    public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) {
        try {
            Class useClass = this.clazz;
            T obj = (T)useClass.newInstance();
            if (value instanceof Map) {
                // assume that the value is provided as a map
                Map m = (Map)value;
                for (Object entry : m.entrySet()) {
                    String propName = (String)((Map.Entry)entry).getKey();
                    Object propValue = ((Map.Entry)entry).getValue();
                    propName = fixPropertyName(propName);
                    propValue = fixPropertyValue(propValue);
                    assignValueToProperty(useClass, obj, propName, propValue);
                }
            } else {
                // TODO (left out here, to keep the code simple)
                return null;
            }
            return obj;
        } catch (Exception ex) {
            return null;
        }
    }

    protected String fixPropertyName(String propName) {
        if (propName.startsWith(this.prefix)) {
            propName = propName.substring(this.prefix.length());
        }
        return propName;
    }

    protected Object fixPropertyValue(Object propValue) {
        return propValue;
    }

    protected PropertyDescriptor findPropertyDescriptor(String propName, Class clazz) {
        try {
            return new PropertyDescriptor(propName, clazz);
        } catch (Exception ex) {
            return null;
        }
    }

    protected void assignValueToProperty(Class clazz, Object obj, String propName, Object propValue) {
        try {
            PropertyDescriptor propDesc = findPropertyDescriptor(propName, clazz);
            if (propDesc != null) {
                propDesc.getWriteMethod().invoke(obj, propValue);
            }
        } catch (Exception ex) {
        }
    }
}