将 JSON 反序列化为现有对象 (Java)

     2023-02-16     197

关键词:

【中文标题】将 JSON 反序列化为现有对象 (Java)【英文标题】:Deserialize JSON into existing object (Java) 【发布时间】:2012-09-13 04:09:20 【问题描述】:

我想知道如何让 Jackson JSON 库将 JSON 反序列化为现有对象?我试图找到如何做到这一点;但它似乎只能接受一个类并自己实例化它。

或者如果不可能,我想知道是否有任何 Java JSON 反序列化库可以做到这一点。

这似乎是 C# 的相应问题:Overlay data from JSON string to existing object instance。 JSON.NET 似乎有一个 PopulateObject(string,object)。

【问题讨论】:

你看过 Gson 吗? code.google.com/p/google-gson 只是粗略的。能做到以上几点吗? 好像不行,code.google.com/p/google-gson/issues/detail?id=431有一个Gson问题“问题431:填充现有对象” ...而“Gson 路线图”只有“Planned Releases: Gson 2.2.3:”和空白空间。 看这个办法***.com/questions/55426453/… 【参考方案1】:

您可以使用我的存储库:)。

Object yo = //yourObject
String js = //json source

Map remote = Object$.remoteMap(yo, false); //or you can use Bean.forInstance(yo);
Reader reader = new StringReader(js);//you can replace this with any reader :)
AtomicReference buffer = new AtomicReference(remote);

try 
    JSON.global.parse(buffer, reader, null, null);
 catch (IOException ignored) 
    //If any exception got thrown by the reader

这样,JSON 会将值解析到它在缓冲区中找到的映射。如果地图包含一个列表,并且 JSON 值也有一个列表。地图上的列表不会被替换。相反,它将用于包含值。

如果你使用Bean.forInstance(yo),返回的远程地图会有一些附加功能。

存储库:

util repo(必需):github.com/cufyorg/util

基础仓库(必需):github.com/cufyorg/base

JSON 存储库(必需):github.com/cufyorg/json

beans repo(可选):github.com/cufyorg/beans

【讨论】:

【参考方案2】:

如果您使用的是 spring 框架,您可以使用 BeanUtils 库来完成此任务。首先正常反序列化您的 json 字符串,然后使用 BeanUtils 将此对象设置在父对象中。它还期望在父对象内设置对象的变量名。 这是代码sn-p:

childObject = gson.fromJson("your json string",class.forName(argType))
BeanUtils.setProperty(mainObject, "childObjectName", childObject);

【讨论】:

谢谢。恐怕这并没有真正达到我的意图。这看起来像“手动”设置字段/属性。【参考方案3】:

总是可以加载到一个虚拟对象中并使用反射来传输数据。如果你一心只想使用 gson

例子。 假设此代码在您要将数据复制到的对象中

    public void loadObject()
Gson gson = new Gson();
//make temp object
YourObject tempStorage = (YourObject) gson.fromJson(new FileReader(theJsonFile), YourObject.class);
//get the fields for that class
ArrayList<Field> tempFields = new ArrayList<Field>();
ArrayList<Field> ourFields = new ArrayList<Field>();
getAllFields(tempFields, tempStorage.getClass());
getAllFields(thisObjectsFields, this.getClass());
for(Field f1 : tempFields)
    for(Field f2 : thisObjectsFields)
        //find matching fields
        if(f1.getName().equals(f2.getName()) && f1.getType().equals(f2.getType()))
            //transient and statics dont get serialized and deserialized.
            if(!Modifier.isTransient(f1.getModifiers())&&!Modifier.isStatic(f1.getModifiers()))
                //make sure its a loadable thing
                f2.set(this, f1.get(tempStorage));
            
        
    

public static List<Field> getAllFields(List<Field> fields, Class<?> type) 
    for (Field field : type.getDeclaredFields()) 
        fields.add(field);
    
    if (type.getSuperclass() != null) 
        fields = getAllFields(fields, type.getSuperclass());
    
    return fields;

【讨论】:

【参考方案4】:

如果您可以使用其他库而不是 Jackson,您可以尝试 Genson http://owlike.github.io/genson/。除了其他一些不错的功能(例如使用不带任何注释的非空构造函数进行反序列化、反序列化为多态类型等)之外,它还支持将 JavaBean 反序列化为现有实例。这是一个例子:

BeanDescriptorProvider provider = new Genson().getBeanDescriptorFactory();
BeanDescriptor<MyClass> descriptor = provider.provide(MyClass.class, genson);
ObjectReader reader = new JsonReader(jsonString);
MyClass existingObject = descriptor.deserialize(existingObject, reader, new Context(genson));

如果您有任何问题,请随时使用其邮件列表http://groups.google.com/group/genson。

【讨论】:

谢谢,我一定会看看的!这是他们的第一个目标,看起来很有希望:Be as much extensible as possible by allowing users to add new functionnalities in a clean and easy way. Genson applies the philosophy that "We can not think of every use case, so give to users the ability to do it by them self in a easy way". 不错,希望大家喜欢,其实我是gensons作者=)【参考方案5】:

您可以使用 Jackson 来做到这一点:

mapper.readerForUpdating(object).readValue(json);

另见Merging Two JSON Documents Using Jackson

【讨论】:

谢谢,@boberj - 奇怪的是以前没有人能找到这个;该功能在我问的时候一定是在杰克逊,因为你的链接是一个描述这个的旧答案。 但不幸的是,在这种情况下,readValue 如果无法解析 json,则不会抛出异常。是否有可能将其恢复为正常行为?【参考方案6】:

我使用 Jackson + Spring 的 DataBinder 来完成这样的事情。此代码处理数组,但不处理嵌套对象。

private void bindJSONToObject(Object obj, String json) throws IOException, JsonProcessingException 
    MutablePropertyValues mpv = new MutablePropertyValues();
    JsonNode rootNode = new ObjectMapper().readTree(json);
    for (Iterator<Entry<String, JsonNode>> iter = rootNode.getFields(); iter.hasNext(); ) 
        Entry<String, JsonNode> entry = iter.next();
        String name = entry.getKey();
        JsonNode node = entry.getValue();
        if (node.isArray()) 
            List<String> values = new ArrayList<String>();
            for (JsonNode elem : node) 
                values.add(elem.getTextValue());
            
            mpv.addPropertyValue(name, values);
            if (logger.isDebugEnabled()) 
                logger.debug(name + "=" + ArrayUtils.toString(values));
            
        
        else 
            mpv.addPropertyValue(name, node.getTextValue());
            if (logger.isDebugEnabled()) 
                logger.debug(name + "=" + node.getTextValue());
            
         
    
    DataBinder dataBinder = new DataBinder(obj);
    dataBinder.bind(mpv);

【讨论】:

【参考方案7】:

flexJson 也可以帮助您做到这一点。

这是从FlexJson Doc复制的示例

deserializeInto 函数获取您的字符串并引用现有对象。

 Person charlie = new Person("Charlie", "Hubbard", cal.getTime(), home, work );
 Person charlieClone = new Person( "Chauncy", "Beauregard", null, null, null );
 Phone fakePhone = new Phone( PhoneNumberType.MOBILE, "303 555 1234");
 charlieClone.getPhones().add( fakePhone ); 
 String json = new JSONSerializer().include("hobbies").exclude("firstname", "lastname").serialize( charlie ); 
 Person p = new JSONDeserializer<Person>().deserializeInto(json, charlieClone);

请注意,p 中返回的引用与 charlieClone 相同,只是更新了值。

【讨论】:

【参考方案8】:

一种解决方案是解析一个新的对象图/树,然后统一复制到现有的对象图/树中。但这当然效率更低,工作量更大,尤其是在具体类型因类型信息可用性较低而不同的情况下。 (所以不是真正的答案。希望有更好的答案,只是想避免别人这样回答。)

【讨论】:

如何使用 Jackson 将原始 JSON 反序列化为 Java 对象

】如何使用Jackson将原始JSON反序列化为Java对象【英文标题】:HowtodeserializerawJSONtoJavaobjectwithJackson【发布时间】:2021-05-2004:16:25【问题描述】:我有两个POJO:@lombok.ValuepublicclassFooStringfoo;Barbar;@lombok.ValuepublicclassBarStringbar;Stringbaz;我... 查看详情

使用 GSON 将 JSON 反序列化为 Java 对象时遇到问题

】使用GSON将JSON反序列化为Java对象时遇到问题【英文标题】:TroubledeserializingJSONintoJavaobjectswithGSON【发布时间】:2021-12-1316:17:05【问题描述】:我一直在努力学习GSON,但我一直在努力学习。我正在尝试使用GSON将JSON文件反序列化... 查看详情

将Json字符串反序列化为对象java

】将Json字符串反序列化为对象java【英文标题】:DeserializeJsonstringtoobjectjava【发布时间】:2020-02-0312:15:20【问题描述】:我得到了正确的字符串形式的响应。但是当我尝试将它建模到我的模型类时,我无法获得这些值。我猜我没... 查看详情

将嵌套的 JSON 字符串反序列化为 Java 对象

】将嵌套的JSON字符串反序列化为Java对象【英文标题】:DeserializenestedJSONStringtoJavaObject【发布时间】:2022-01-2006:58:55【问题描述】:我的JSON看起来像这样,让我们​​说问题"type":"String","value":"\\"text\\":\\"Question\\",\\"type\\":\\"predefi... 查看详情

java示例代码_强制java中的FlexJson将json对象反序列化为字符串

java示例代码_强制java中的FlexJson将json对象反序列化为字符串 查看详情

如何将具有不同值的相同 JSON 对象反序列化为 java 类

】如何将具有不同值的相同JSON对象反序列化为java类【英文标题】:HowdeserializethesameJSONobjectbutwithdiferentvaluesintoajavaclass【发布时间】:2019-12-2906:40:33【问题描述】:我有以下情况:有时我会得到这个JSON对象"id":1,"cp":"male","money":10.... 查看详情

将 JSON 反序列化为 JavaScript 对象

】将JSON反序列化为JavaScript对象【英文标题】:DeserializingaJSONintoaJavaScriptobject【发布时间】:2011-09-2303:36:00【问题描述】:我在使用AJAX访问的Java服务器应用程序中有一个字符串。它看起来像下面这样:varjson=["adjacencies":["nodeTo":"g... 查看详情

将 JSON 反序列化为匿名对象

】将JSON反序列化为匿名对象【英文标题】:DeserializeJSONtoanonymousobject【发布时间】:2011-10-1719:16:55【问题描述】:在C#中,我已经通过使用这样的代码成功地将匿名对象序列化为JSON...varobj=newAmount=108,Message="Hello";JavaScriptSerializerser... 查看详情

将 JSON 反序列化为对象

】将JSON反序列化为对象【英文标题】:DeserializingJSONintoanobject【发布时间】:2016-03-1707:26:47【问题描述】:我有一些JSON:"foo":["bar":"baz","bar":"qux"]我想将其反序列化为一个集合。我已经定义了这个类:publicclassFoopublicstringbarget;set;... 查看详情

将 JSON 反序列化为对象

】将JSON反序列化为对象【英文标题】:DeserializingJSONintoanobject【发布时间】:2021-12-1621:52:42【问题描述】:我有一些JSON:"foo":["bar":"baz","bar":"qux"]我想将其反序列化为一个集合。我已经定义了这个类:publicclassFoopublicstringbarget;set;... 查看详情

javascriptserializer类对象序列化为json,json反序列化为对象

JavaScriptSerializer类由异步通信层内部使用,用于序列化和反序列化在浏览器和Web服务器之间传递的数据。说白了就是能够直接将一个C#对象传送到前台页面成为javascript对象。要添加System.Web.Extensions.dll的引用。该类位于System.Web.Scri... 查看详情

使用jackson将json数组反序列化为单个java对象(代码片段)

...0的元素,而最后一个名称是索引为1的元素。我想将它反序列化为List<Person>。我使 查看详情

如何将来自 Jersey REST 服务的 JSON 响应反序列化为 Java 对象的集合

】如何将来自JerseyREST服务的JSON响应反序列化为Java对象的集合【英文标题】:HowtodeserializeJSONresponsefromJerseyRESTservicetocollectionofjavaobjects【发布时间】:2011-09-1410:59:09【问题描述】:我编写的客户端使用Jersey客户端API向REST服务发出... 查看详情

将空 JSON 数组反序列化为空 TreeMap

】将空JSON数组反序列化为空TreeMap【英文标题】:DeserializeemptyJSONarrayintoemptyTreeMap【发布时间】:2022-01-1101:18:53【问题描述】:我是Java新手,我想知道如何将空JSON数组反序列化为TreeMap&lt;String,MyOtherClass&gt;类型的空Java对象... 查看详情

使用 Json.net 将 JSON 对象反序列化为动态对象

】使用Json.net将JSON对象反序列化为动态对象【英文标题】:DeserializeJSONobjectintodynamicobjectusingJson.net【发布时间】:2011-05-3023:13:12【问题描述】:是否可以使用json.net从json反序列化返回动态对象?我想做这样的事情:dynamicjsonRespons... 查看详情

将 JSON 命名属性反序列化为 .Net 对象

】将JSON命名属性反序列化为.Net对象【英文标题】:DeserializeJSONnamedpropertyto.NetObject【发布时间】:2012-03-0109:56:21【问题描述】:我使用的API提供了JSON负载。响应的一部分有一个包含命名对象数组的属性。我想我想将这部分反序... 查看详情

将 PHP 对象图序列化/反序列化为 JSON

】将PHP对象图序列化/反序列化为JSON【英文标题】:Serialize/unserializePHPobject-graphtoJSON【发布时间】:2012-05-1610:06:15【问题描述】:我想将完整的PHP对象图序列化为JSON字符串表示,然后将其反序列化回相同的PHP对象图。以下是我考... 查看详情

Java:使用json-SpringBoot中的“​​@class”将json反序列化为rest模板中的对象

】Java:使用json-SpringBoot中的“​​@class”将json反序列化为rest模板中的对象【英文标题】:Java:Deserializeajsontoobjectinresttemplateusing"@class"injson-SpringBoot【发布时间】:2015-08-1204:56:12【问题描述】:我必须使用@class中的信息实... 查看详情