JSON Merge Patch 合并结构体字段数据

作者:matrix 发布时间:2023 年 10 月 18 日 分类:Golang

图片5697-JSON Merge Patch 合并结构体字段数据

json Merge Patch,是一个Internet Engineering Task Force(IETF)标准。基本思想是,你有一个原始的JSON对象,然后根据提供的“补丁”JSON对象,最终生成原始JSON对象需要修改的结果。这种机制适用于部分更新(也称为PATCH更新)的场景。

例子

原始对象:

{
  "Account": "old_account",
  "Name": "old_name",
  "Avatar": "old_avatar"
}

补丁对象(patch object):

{
  "Account": "new_account",
  "Name": null
}

应用补丁对象后的待更新数据(PATCH更新):

{
  "Account": "new_account",
  "Avatar": "old_avatar"
}

简单来说,补丁对象(patch object)描述了以下几种修改:

  • 添加或更新字段:如果补丁中的一个字段在原始对象中不存在,它会被添加;如果存在,它会被更新。

  • 删除字段:如果补丁中的一个字段设置为null,并且该字段在原始对象中存在,那么该字段会被删除。

golang使用

使用实现IETF标准的JSON Merge Patch依赖库 json-patch

go get -u github.com/evanphx/json-patch
// JOSN PATCH
// dst 原始对象
// patch 补丁对象
// return 将补丁应用到原始对象
func MergePatch(dst, patch interface{}) error {
    // 序列化目标(原始)结构体到JSON
    dstJSON, err := json.Marshal(dst)
    if err != nil {
        return err
    }

    // 序列化补丁结构体到JSON,这个补丁描述了如何修改目标(原始)对象
    patchJSON, err := json.Marshal(patch)
    if err != nil {
        return err
    }

    // 使用补丁合并目标(原始)对象
    mergedJSON, err := jsonpatch.MergePatch(dstJSON, patchJSON)
    if err != nil {
        return err
    }

    // 反序列化合并后的JSON回到目标(原始)结构体
    return json.Unmarshal(mergedJSON, dst)
}


调用:


if err := MergePatch(&originJSON, &patchJSON); err != nil { u.JSONResponseError(ctx, err) return } // originJSON 就是应用过补丁的最新原始结构数据

参考:
https://datatracker.ietf.org/doc/html/rfc7396

php的json_decode函数无法解析json

作者:matrix 发布时间:2014 年 9 月 4 日 分类:零零星星

phpjson_decode函数用来解析json数据很方便,但是有时候却解析不了。

究其原因找到如下可能性:

1.键名没有用双引号括起来

['name':n,'age',a]
[name:n,age,a]

这两个都不能解析

2.出现多余逗号

['name':n,'age',a,]

###3.有些转义不支持
数据中出现\x26这样的会失败,有时候\'都无法解析。
stripslashes()去掉转义即可!

4.json不支持gbk编码

iconv('GBK', 'UTF-8', $json_data);//使用iconv()函数将GBK转到UTF-8编码

json数据解析前用检测工具测试一下较好:http://www.bejson.com/

150515添加

/* 
 格式化错误的json数据,使其能被json_decode()解析 
 不支持健名有中文、引号、花括号、冒号 
 不支持健指有冒号 
*/  
function format_ErrorJson($data,$quotes_key=false)  
{  
    $con = str_replace('\'','"',$data);//替换单引号为双引号 
    $con = str_replace(array('\\"'),array('<|YH|>'),$con);//替换 
    $con = preg_replace('/(\w+):[ {]?((?<YinHao>"?).*?\k<YinHao>[,}]?)/is', '"$1": $2',$con );//若键名没有双引号则添加  
    if($quotes_key)  
    {  
        $con = preg_replace('/("\w+"): ?([^"\s]+)([,}])[\s]?/is', '$1: "$2"$3',$con );//给键值添加双引号 
    } 
    $con = str_replace(array('<|YH|>'),array('\\"'),$con);//还原替换  
    return $con;  
}  

参考:http://bbs.csdn.net/topics/390496037

http://chenwei.me/p/59.html

ajax跨域请求json数据

作者:matrix 发布时间:2014 年 3 月 13 日 分类:零零星星

 

刚开始仅仅想获取一个他域的json数据,没想到牵扯到很多的问题。
每次都请求失败:
chrome面板的status为(canceled)

在Request Header这里显示CAUTION Provisional headers are shown

 

后来才知道是ajax跨域问题导致:

也就是ajax同源策略(同源是指域名,协议,端口相同)。
跨域可以实现在自己的网站之间传递数据。但是如果你想用“跨域”盗取其它网站的数据,那还是放弃吧。除非目标网站有给你提供JSONP的接口,或者有某些可以利用的漏洞,要不然真没什么办法实现。
跨域问题的产生,最主要原因是COOKIE的安全问题。因为COOKIE是属于一个域的,如果允许跨域,客户端浏览器上储存的COOKIE就可以被它的所有者之外的程序访问到。举个例子吧,假如没有跨域问题,我现在就可以给百度发送个HTTP请求,获取你在百度上登录的用户名。或者获取SessionID,直接冒充你的帐号登录。为了避免这些问题,所以跨域访问的限制是非常有必要的。

利用jsonp跨域

要跨域必须要有回调函数的接口,这里用jsonp试试 阅读剩余部分 »