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. 直接插入排序---java实现

    思路:遍历无序的原数组,把第i个的后一个即i+1去与前面的i个逐个比较... 解法一: package com.sheepmu.text; import java.util.Arrays; /* * ...

  2. win7开机直接进入系统系统桌面

    在开始搜索栏输入:netplwiz   选中admin用户(也就是你登录的用户名),然后在把上面的勾去掉,点应用,会提示输入用户名和密码,输二次,是一样的密码,如果没设密码,就不用输直接应用,确定就O ...

  3. cocos2d-x box2d Demo注解

    勤奋努力,持之以恒. 核心概念 Box2D 中有一些主要的对象,这里我们先做一个简要的定义,在随后的文档里会有更具体的描写叙述. 刚体(rigid body) 一块十分坚硬的物质,它上面的不论什么两点 ...

  4. 为什么在Python3.4.1里输入print 10000L或10000L失败

    打开Python的命令行交互窗体,而且在里面进行以下的输入: Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 ...

  5. Design Pattern Command 命令设计模式

    这种设计模式是使用不同类的包裹不同的命令,达到什么样的命令执行什么操作. 有可能进一步利用map您最喜欢的对接命令字. 正在运行的类实际上已经包含了操作的所有需求,例如: class SuperMak ...

  6. Sizzle.filter [ 源代码分析 ]

    最近的研究已Sizzle选择,对于原理中我们也不得不佩服! Sizzle中间filter办法.主要负责元素表达式过滤块的集合,在内部的方法调用Sizzle.selector.fitler滤波操作的操作 ...

  7. 了解webpack

    学习笔记 一步步了解webpack   前言 demo 地址: https://github.com/yy8597/webpack-demos 之前学习了 broswerify,发现确实很好用.虽然没 ...

  8. IQ调制、整形滤波器与星座映射

    http://www.cnblogs.com/touchblue/archive/2013/01/15/2861952.html 现代通信中.IQ调制基本上属于是标准配置,由于利用IQ调制能够做出全部 ...

  9. Redis集群方案及实现

    在作出Redis群集解决方案,他跑了小半个.行表现得非常稳定在几乎相同的经历与大家分享,我写在前面的文章数据在线服务的一些探索经验,能够做为背景阅读 应用 我们的Redis集群主要承担了下面服务:1. ...

  10. hdu3836联通的强还原性点

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...