Exception in thread "main"
java.lang.RuntimeException: No-args constructor for class java.sql.Timestamp does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

#关于使用Google GSON 实现Json协议字符协议序列化和反序列化 时间戳到Timestame类型转换失败问题。

解决方式:定义自己的类型适配器。

下面代码演示了两个问题:

1.解决上面说的时间戳到Timestame类型互转问题。

2.扩展了一个基于HTTP协议URL字符串解析到POJO HttpProtocol 的互转。

Code 例如以下:

package com.kevin.luan.service;

import java.lang.reflect.Type;
import java.sql.Timestamp; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer; /**
* 实现一个自己定义的实行适配器
* <p>
* 基于Google GSON 实现JSON解析
* </p>
*
* @author kevin LUAN
*
*/
public class GsonTypeAdapterDemo {
public static void main(String[] args) {
Gson gson = new GsonBuilder().registerTypeAdapter(Timestamp.class, new TimestampAdapter()).registerTypeAdapter(HttpProtocol.class, new HttpProtocolAdapter()).create();
String json = "{\"price\":\"1.1001\",\"times\":\"" + System.currentTimeMillis() + "\",\"protocol\":\"http://www.koudai.com/abc/test.do?url=abc\"}";
Test pojo = gson.fromJson(json, Test.class);
System.out.println("JSON TO POJO:" + pojo);
json = gson.toJson(pojo);
System.err.println("POJO TO JSON:" + json);
} /**
* 实现一个类型适配器(TypeAdapter)
*
* @author kevin LUAN
*
*/
public static class TimestampAdapter implements JsonSerializer<Timestamp>, JsonDeserializer<Timestamp> { @Override
public Timestamp deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
if (json != null) {
try {
return new Timestamp(json.getAsLong());
} catch (JsonParseException e) {
throw e;
}
}
return null;
} @Override
public JsonElement serialize(Timestamp value, Type type, JsonSerializationContext context) {
if (value != null) {
return new JsonPrimitive(value.getTime());
}
return null;
} } /**
* 基于HttpProtocol的类型适配器
*
* @author kevin LUAN
*
*/
public static class HttpProtocolAdapter implements JsonSerializer<HttpProtocol>, JsonDeserializer<HttpProtocol> { @Override
public HttpProtocol deserialize(JsonElement json, Type arg1, JsonDeserializationContext arg2) throws JsonParseException {
if (json == null) {
return null;
} else {
try {
return new HttpProtocol(json.toString());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
} @Override
public JsonElement serialize(HttpProtocol src, Type arg1, JsonSerializationContext arg2) {
return new JsonPrimitive(src.toString());
} } /**
* 測试
* <p>
* JSON->POJO
* </p>
* <p>
* POJO->JSON
* </p>
*
* @author kevin LUAN
*
*/
public static class Test {
private Float price = 1.0f;
private Timestamp times;
private HttpProtocol protocol; @Override
public String toString() {
return "price:" + price + "|times:" + times + "|protocl:" + protocol + "";
} } /**
* HTTP协议POJO
*
* @author kevin LUAN
*
*/
public static class HttpProtocol {
private String protocol;
private String host;
private int port = -1;
private String uri;
private String paramQuery; @Override
public String toString() {
return protocol + "://" + host + ":" + port + uri + "?" + paramQuery + "}";
} public HttpProtocol(String value) {
if (value.startsWith("\"") && value.endsWith("\"")) {
value = value.substring(1, value.length() - 1);
}
parserProtocol(value);
} private void parserProtocol(String value) {
int endIndex = value.indexOf("://");
if (endIndex != -1) {
protocol = value.substring(0, endIndex);
parserHost(value, endIndex + 3);
}
} private void parserHost(String value, int startIndex) {
int endIndex = value.indexOf("/", startIndex);
if (endIndex != -1) {
host = value.substring(startIndex, endIndex);
splitHostPort();
parserUri(value, endIndex);
} else {
host = value.substring(startIndex);
splitHostPort();
}
} private void splitHostPort() {
if (host.indexOf(":") != -1) {
String host_port[] = host.split(":");
host = host_port[0];
port = Integer.parseInt(host_port[1]);
} else {
port = 80;
}
} private void parserUri(String value, int startIndex) {
if (value.indexOf("?", startIndex) == -1) {
uri = value.substring(startIndex);
} else {
int endIndex = value.indexOf("?", startIndex);
uri = value.substring(startIndex, endIndex);
parserQuery(value, endIndex);
}
} private void parserQuery(String value, int startIndex) {
if (value.indexOf("?", startIndex) != -1) {
int paramQueryIndex = value.indexOf("?", startIndex);
paramQuery = value.substring(paramQueryIndex + 1);
}
} }
}

执行Main结果:

JSON TO POJO:price:1.1001|times:2014-06-22 13:06:54.138|protocl:http://www.koudai.com:80/abc/test.do?url=abc}

POJO TO JSON:{"price":1.1001,"times":1403413614138,"protocol":"http://www.koudai.com:80/abc/test.do?url\u003dabc}"}

自己定义GSON类型适配器的更多相关文章

  1. Gson 基础教程 —— 自定义类型适配器(TypeAdapter)

    1,实现一个类型适配器(TypeAdapter) 自定义类型适配器需要实现两个接口: JsonSerializer<T> JsonDeserializer<T> 和两个方法: ...

  2. SQL 用户定义表类型,在存储过程里使用表类型,表参数作参数

    .定义表类型SUTDENTTYPE,包含三个字段,分别对应学生表的NAME,SEX和PHONE.之所以如此创建,我是准备在插入新学生数据的存储过程中,以它为参数.   GO CREATE TYPE S ...

  3. C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)

    今天在进行代码测试时发现,尝试在一个方法中定义一个委托,注意是定义一个委托,而不是声明一个委托变量,在编写的时候没有报错,VS也能智能提示,但在编译时却报语法不完整,缺少方括号,但实际查询并没有缺少, ...

  4. Android中常用适配器及定义自己的适配器

    转载:http://blog.chinaunix.net/uid-11898547-id-3303153.html http://www.tudou.com/home/_328390108/item ...

  5. 【VBA研究】变量定义的类型和实际赋值类型

    作者:iamlaosong VBA中变量能够先定义后使用,也能够不定义直接使用.假设模块前面加了Option Explicit语句,则变量必须先定义后使用. 只是.实验发现.VBA对变量类型没有进行严 ...

  6. Sql server 浅谈用户定义表类型

    1.1 简介 SQL Server 中,用户定义表类型是指用户所定义的表示表结构定义的类型.您可以使用用户定义表类型为存储过程或函数声明表值参数,或者声明您要在批处理中或在存储过程或函数的主体中使用的 ...

  7. 使用typedef语句定义数组类型

    使用typedef语句定义数组类型     1. 一维数组类型的定义格式 typedef <元素类型关键字><数组类型名>[<常量表达式>]; 例如: (1) ty ...

  8. typedef定义数组类型

    typedef语句定义数组类型 1. 一维数组类型的定义格式 typedef <元素类型关键字><数组类型名>[<常量表达式>]; 例如: (1) typedef ...

  9. sqlserver 若字段定义的类型为datetime

    sqlserver 若字段定义的类型为datetime,插入为''(空),那么会默认值为1900-01-01 00:00:00.000 解决 插入 NULL 或者程序判断

随机推荐

  1. 使用dfs实现1至n全阵列

    使用dfs实现1至n全阵列. 我的方法是从所述第一位置开始,使用dfs看上去就像每个头号位置, 当某个位置.从小到大枚举1至n所有号码,打假说 尚未使用之前在这个位置上的几个选择这个号码.然后搜索下 ...

  2. OCP解决问题052-- DROP PROFILE app_user

    133.You created a profile APP_USER and assigned it to the users. After a month, you decide to drop t ...

  3. UI标签库的话题:JEECG智能开发平台 BaseTag(样式表和JS标签的引入)

    UI标签库专题一:JEECG智能开发平台 BaseTag(样式表和JS引入标签) 1.BaseTag(样式表和JS引入标签) 1.1. 演示样例 <t:base type="jquer ...

  4. Directx11学习笔记【九】 【转】 3D渲染管线

    原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即给定场景的描述,包括各个物体的材质.纹理.坐标等,照相 ...

  5. 【Nginx】磁盘文件写入飞地发

    文章继续.什么时候Nginx当用户请求一个文件,这将无法读取该文件的内容加载到内存,然后从内存发送,但电话sendfile况下,从内核直接发送出去.这样做显然效率要更高.Nginx也为我们封装好了一系 ...

  6. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  7. web即时通讯2--基于Spring websocket达到web聊天室

    如本文所用,Spring4和websocket要构建web聊天室,根据框架SpringMVC+Spring+Hibernate的Maven项目,后台使用spring websocket进行消息转发和聊 ...

  8. Kotlin

    关于Kotlin,网上已有一些介绍的文章,包括Antonio Leiva的这组blog翻译稿.不过,我还是想跟进它们.翻译它们,以锻炼自己的英文翻译.各位高手发现问题,请及时“拍砖”. 原文题目:Ko ...

  9. OpenGL学习日记-2015.3.13——多实例渲染

        实例化(instancing)或者多实例渲染(instancd rendering)是一种连续运行多条同样渲染命令的方法.而且每一个命令的所产生的渲染结果都会有轻微的差异. 是一种很有效的.有 ...

  10. url参数中出现+、空格、=、%、&、#等字符的解决办法

    url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...