golang JSON数据编码与解码

golang 专栏收录该内容
6 篇文章 0 订阅

JSON编码常用函数

  • func NewEncoder(w io.Writer) Encoder
    NewEncoder创建一个将数据写入w的
    Encoder。

  • func (enc *Encoder) Encode(v interface{}) error
    Encode将v的json编码写入输出流,并会写入一个换行符

  • func Marshal(v interface{}) ([]byte, error)
    Marshal函数返回v的json编码。

  • func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
    MarshalIndent类似Marshal但会使用缩进将输出格式化。

  • func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
    Indent函数将json编码的调整缩进之后写入dst。每一个json元素/数组都另起一行开始,以prefix为起始,一或多个indent缩进(数目看嵌套层数)。写入dst的数据起始没有prefix字符,也没有indent字符,最后也不换行,因此可以更好的嵌入其他格式化后的json数据里

示例:

// parse_json.go
package main

import (
	// "bytes"
	"encoding/json"
	"fmt"
	"os"
)

type user struct {
	Name string
	Age  int
	Sex  bool
}

func main() {

	var user_map = map[int]user{1: {"zhangsan", 20, true}, 2: {"lisi", 20, false}}
	// 编码JSON数据并返回
	bt_data, _ := json.Marshal(user_map)
	fmt.Println(string(bt_data))

	// 编码JSON数据并以缩进方式返回
	indent_bt_data, _ := json.MarshalIndent(user_map, "", "  ")
	fmt.Println("indent_bt_data = ", string(indent_bt_data))

	// 将编码完的JSON数据直接写入到文件中
	json_w_fd, _ := os.OpenFile("./out.json", os.O_CREATE, 0666)

	json_encoder := json.NewEncoder(json_w_fd)
	json_encoder.Encode(user_map)
	json_w_fd.Close()

	// 将编码完的JSON数据合并到其他数据中
	// dst := bytes.NewBuffer(indent_bt_data)
	// json.Indent(dst, bt_data, "", "")
	// fmt.Println(dst.String())

}

运行结果:

json_encode

JSON解码常用函数

  • func NewDecoder(r io.Reader) Decoder
    NewDecoder创建一个从r读取并解码json对象的
    Decoder,解码器有自己的缓冲,并可能超前读取部分json数据

  • func (dec *Decoder) Decode(v interface{}) error
    Decode从输入流读取下一个json编码值并保存在v指向的值里,参见Unmarshal函数的文档获取细节信息。

  • func Unmarshal(data []byte, v interface{}) error
    Unmarshal函数解析json编码的数据并将结果存入v指向的值。

Unmarshal和Marshal做相反的操作,必要时申请映射、切片或指针,有如下的附加规则:

要将json数据解码写入一个指针,Unmarshal函数首先处理json数据是json字面值null的情况。此时,函数将指针设为nil;否则,函数将json数据解码写入指针指向的值;如果指针本身是nil,函数会先申请一个值并使指针指向它。

要将json数据解码写入一个结构体,函数会匹配输入对象的键和Marshal使用的键(结构体字段名或者它的标签指定的键名),优先选择精确的匹配,但也接受大小写不敏感的匹配。

要将json数据解码写入一个接口类型值,函数会将数据解码为如下类型写入接口:

Bool 对应JSON布尔类型
float64 对应JSON数字类型
string 对应JSON字符串类型
[]interface{} 对应JSON数组
map[string]interface{} 对应JSON对象
nil 对应JSON的null
如果一个JSON值不匹配给出的目标类型,或者如果一个json数字写入目标类型时溢出,Unmarshal函数会跳过该字段并尽量完成其余的解码操作。如果没有出现更加严重的错误,本函数会返回一个描述第一个此类错误的详细信息的UnmarshalTypeError。

JSON的null值解码为go的接口、指针、切片时会将它们设为nil,因为null在json里一般表示“不存在”。 解码json的null值到其他go类型时,不会造成任何改变,也不会产生错误。

当解码字符串时,不合法的utf-8或utf-16代理(字符)对不视为错误,而是将非法字符替换为unicode字符U+FFFD。

代码

// json_decode.go
package main

import (
	// "bytes"
	"encoding/json"
	"fmt"
	"os"
)

type user struct {
	Name string
	Age  int
	Sex  bool
}

func main() {
	var user_map map[int]user
	// bt_data []byte

	json_rd_fd, _ := os.Open("./out.json")

	json_decode := json.NewDecoder(json_rd_fd)
	json_decode.Decode(&user_map)
	
	fmt.Println(user_map)
	json_rd_fd.Close()

	json_str := "{\"1\":{\"Name\":\"wangwu\",\"Age\":18,\"Sex\":true},\"2\":{\"Name\":\"chenliu\",\"Age\":29,\"Sex\":false}}"
	json.Unmarshal([]byte(json_str), &user_map)
	
	fmt.Println(user_map)

}

运行结果:

在这里插入图片描述

下面是RawMessage类型的JSON处理方法:

  • type RawMessage []byte

RawMessage类型是一个保持原本编码的json对象。本类型实现了Marshaler和Unmarshaler接口,用于延迟json的解码或者预计算json的编码。
即在第一次解码时,RawMessage类型的数据先保留JSON格式。

如下代码来自golang标准文档库

type Color struct {
    Space string
    Point json.RawMessage // delay parsing until we know the color space
}
type RGB struct {
    R   uint8
    G   uint8
    B   uint8
}
type YCbCr struct {
    Y   uint8
    Cb  int8
    Cr  int8
}
var j = []byte(`[
		{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
		{"Space": "RGB",   "Point": {"R": 98, "G": 218, "B": 255}}
	]`)
var colors []Color
err := json.Unmarshal(j, &colors)
if err != nil {
    log.Fatalln("error:", err)
}
for _, c := range colors {
    var dst interface{}
    switch c.Space {
    case "RGB":
        dst = new(RGB)
    case "YCbCr":
        dst = new(YCbCr)
    }
    err := json.Unmarshal(c.Point, dst)
    if err != nil {
        log.Fatalln("error:", err)
    }
    fmt.Println(c.Space, dst)
}

结果:

YCbCr &{255 0 -10}
RGB &{98 218 255}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

ps:主要解决在webservice中,我们想从另外一个项目调用webservice项目的接口,也就是跨项目调用接口 这里主要用到了xfire wsdl 废话不说了 直接上东西 1. 首先新建一个项目 2. 在src下创建两个文件: a) 第一个是你想要访问的webservice的接口,比如我想访问的接口是 ReleaseService 那就在当前项目创建一个ReleaseService接口(接口中的方法必须和你想要访问的webservice的接口中的方法相同) b) 第二个是你的调用类 3. 导入相应的jar包,这些包不能引用,一定要复制到lib文件夹下面在引用 4. 具体的实现代码 TestWebService方法的代码: package com.isanta.webServiceTest; import java.io.InputStream; import java.net.MalformedURLException; import java.util.Properties; import java.util.Scanner; import org.codehaus.xfire.XFireFactory; import org.codehaus.xfire.client.XFireProxyFactory; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.service.binding.ObjectServiceFactory; public class TestWebService { /** * @param args */ public static void testWebService() throws MalformedURLException, Exception{ // TODO Auto-generated method stub /** *这里是我的参数放在了properties文件中,我在读取里面的参数,这里我们也可以通过方法传参数 *如 : testWebService(String url,String xMlStr)() 那么在调用的时候就可以直接传进来了 *url 是你访问的webservice 的tomcat 的服务器地址 */ Properties pro = new Properties(); InputStream in = null; in = TestWebService.class.getResourceAsStream("/request.properties"); pro.load(in); String url = pro.getProperty("url"); String xMLstr = pro.getProperty("xMLstr"); Service s=new ObjectServiceFactory().create(ReleaseService.class); XFireProxyFactory xf=new XFireProxyFactory(XFireFactory.newInstance().getXFire()); System.out.println("url="+url); try { //这里就是获取webservice的接口的实例对象 ReleaseService seleaseService=(ReleaseService) xf.create(s,url); System.out.println("进入接口----------------->请求报文:"+xMLstr); //这里就是调用你需要的接口的方法 String st=seleaseService.queryReceiptDatas(xMLstr); System.out.print(st); } catch(Exception e) { e.printStackTrace(); } } } 5. 将整个项目打包成jar 6. 将打好的jar包引入到你想要调用的项目中,然后就想 正常的代码一样来调用,如: import java.net.MalformedURLException; import com.isanta.webSe
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值