【玩转Golang】 自定义json序列化对象时,非法字符错误原因

  由于前台web页面传来的日期对象是这样的格式“2010-11-03 15:23:22”,所以我安装网上查来的办法,自定义包装了time.Time对象,实现自己的Marshal和UnMarshal方法

type DateTime struct {
    time.Time
}

const ctLayout = "2006-01-02 15:04:05"
const ctLayout_nosec = "2006-01-02 15:04"
const ctLayout_date = "2006-01-02"

func (this *DateTime) UnmarshalJSON(b []byte) (err error) {

    if b[0] == ‘"‘ && b[len(b)-1] == ‘"‘ {
        b = b[1 : len(b)-1]
    }
    loc, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        panic(err)
    }
    sv := string(b)
    if len(sv) == 10 {
        sv += " 00:00:00"
    } else if len(sv) == 16 {
        sv += ":00"
    }
    this.Time, err = time.ParseInLocation(ctLayout, string(b), loc)
    if err != nil {
        if this.Time, err = time.ParseInLocation(ctLayout_nosec, string(b), loc); err != nil {
            this.Time, err = time.ParseInLocation(ctLayout_date, string(b), loc)
        }
    }

    return
}

func (this *DateTime) MarshalJSON() ([]byte, error) {

    rs := []byte(this.Time.Format(ctLayout))

    return rs, nil
}

var nilTime = (time.Time{}).UnixNano()

func (this *DateTime) IsSet() bool {
    return this.UnixNano() != nilTime
}

然后,把结构中声明为time.Time的都修改为自定义的类型DateTime,试了一下,发现已经可以正确解析网页发来的时间,但是在输出时,总是不对,好像并没有调用自定义的Marshal方法。编写测试方法发现,原来json.Marshal方法调用DateTime.Marshal时出错了!

 invalid character ‘-‘ after top-level value 

开始没有认真看,以为“-”号不合法,就换了一个,结果错误一样:

 invalid character ‘/‘ after top-level value 

看来,根本不是分割符的问题,仔细分析错误,发现“top-level”字样,我这返回的就是一个字符串,怎么可能top-level呢!想到这儿突然醒悟,是不是返回字符串应该自己加引号呢,急忙修改代码一试,果然!~_~

最终代码如下:

type DateTime struct {
    time.Time
}

const ctLayout = "2006-01-02 15:04:05"
const ctLayout_nosec = "2006-01-02 15:04"
const ctLayout_date = "2006-01-02"

func (this *DateTime) UnmarshalJSON(b []byte) (err error) {

    if b[0] == ‘"‘ && b[len(b)-1] == ‘"‘ {
        b = b[1 : len(b)-1]
    }
    loc, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        panic(err)
    }
    sv := string(b)
    if len(sv) == 10 {
        sv += " 00:00:00"
    } else if len(sv) == 16 {
        sv += ":00"
    }
    this.Time, err = time.ParseInLocation(ctLayout, string(b), loc)
    if err != nil {
        if this.Time, err = time.ParseInLocation(ctLayout_nosec, string(b), loc); err != nil {
            this.Time, err = time.ParseInLocation(ctLayout_date, string(b), loc)
        }
    }

    return
}

func (this *DateTime) MarshalJSON() ([]byte, error) {

    rs := []byte(fmt.Sprintf(`"%s"`, this.Time.Format(ctLayout)))

    return rs, nil
}

var nilTime = (time.Time{}).UnixNano()

func (this *DateTime) IsSet() bool {
    return this.UnixNano() != nilTime
}
时间: 2024-10-10 00:29:27

【玩转Golang】 自定义json序列化对象时,非法字符错误原因的相关文章

EF中Json序列化对象时检测到循环引用的解决办法

第一种方法:使用Newtonsoft.Json中的方法注释,在Json序列化的时候忽略导航属性 例:using Newtonsoft.Json; public class Users { public int Id { get; set; } public string LoginId { get; set; } public string LoginPwd { get; set; } [JsonIgnore] public virtual ICollection Roles { get; se

使用DataContractJsonSerializer发序列化对象时出现的异常

最近服务器上的某个程序的错误日志中频繁出现以下异常: Deserialising: There was an error deserializing the object of type {type}. The token '"' was expected but found 'Â' 通过分析发现是使用DataContractJsonSerializer发序列化对象时出现的异常 但是把日志中出错的json串拷贝到本机测试时又没有问题,很是费解,最后在网上找到了解决办法 http://stacko

【翻译自mos文章】使用aum( Automatic Undo Management) 时遇到 ORA-01555错误--- 原因和解决方案。

使用aum( Automatic Undo Management) 时遇到 ORA-01555错误--- 原因和解决方案. 参考原文: ORA-01555 Using Automatic Undo Management - Causes and Solutions (Doc ID 269814.1) 适用于: Oracle Database - Enterprise Edition - Version 9.0.1.0 and later Information in this document

转载:在ASP.net 3.5中 用JSON序列化对象(两种方法)

asp.net3.5中已经集成了序列化对象为json的方法. 1:System.Runtime.Serialization.Json;    2:System.Web.Script.Serialization两个命名空间下的不同方法进行序列化和反序列化. 第一种方法:System.Runtime.Serialization.Json public class JsonHelper    {        /// <summary>        /// 生成Json格式        /// 

Gson序列化对象时排除字段

import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; /** *Gson序列化对象排除属性 *调用方法: *String[] keys = { "id" }; *Gson gson = new GsonBuilder().setExclusionStrategies(new JsonKit(keys)).create(); */ public class JsonKit imp

.NET 自定义Json序列化时间格式

Intro 和 JAVA 项目组对接,他们的接口返回的数据是一个json字符串,里面的时间有的是Unix时间戳,有的是string类型,有的还是空,默认序列化规则没办法反序列化为时间, 所以自定义了一个 Json 时间转换器,支持可空时间类型.string.long(Unix时间戳毫秒) Show me the code public class CustomDateTimeConverter : JavaScriptDateTimeConverter { /// <summary> ///

golang的json序列化

json就是简单的数据交换格式,语法类似javascript的对象和列表,是最常见的后端和运行在网页上的js之间的通信格式. encoding: 编码json数据需要使用到Marshal()函数. func Marshal(v interface{}) ([]byte, error) type Message struct { Name string Body string Time int64 } m := Message{"Alice", "Hello", 12

json序列化对象

//新的DATASNAP已经支持TPARAMS作为远程方法里面的参数,会自动序列TPARAMS,无需手动序列它. //在此只是记录一些JSON序列的用法,无实际意义 unit uSerialize; interface uses   System.SysUtils, Data.Win.ADODB, Data.DBXJSON, Data.DBXJSONReflect,   System.Variants, Data.DB; type   TSerialize = class   public   

测试一下golang的json序列化Marshal

func test_json() { x, _ := json.Marshal([]string{"aaa:123", "bbb:456"}) fmt.Println(x) var caps []string json.Unmarshal(x, &caps) fmt.Println(caps) } //输出结果 ------------------------------- [91 34 97 97 97 58 49 50 51 34 44 34 98 98