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. 左右canvas.drawArc,canvas.drawOval 和RectF 关联

    1.paint.setStyle(Paint.Style.STROKE) // radius="100dp" // interRadius="40dp" // ...

  2. Project_2007关键

    本人今天成功用这个密钥,安装project2007. 分享给着急的小伙伴们. W2JJW-4KYDP-2YMKW-FX36H-QYVD8 版权声明:本文博客原创文章.博客,未经同意,不得转载.

  3. 基于高性能的硬件配置Nginx

    Nginx高级配置将涉及硬件,假设你配置不好,直接使各种性能下降. 我这里总结一下.怎样依据server的硬件设备来配置Nginx. 见下图: 低訪问量的网络,能够这样配置. 标准的网络訪问量,能够这 ...

  4. 11gRAC CHM 管理

    Cluster Health Monitor(缩写CHM)是Oracle提供的工具,自己主动的资源来收集操作系统(CPU.内存.SWAP.过程.I/O与网络)用法. CHM数据被收集每秒一次,11.2 ...

  5. [ACM] HDU 1227 Fast Food (经典Dp)

    Fast Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  6. bat(批处理文件)初步 第一篇 基本符号

    近期我使用的一款软件中须要大量的环境变量设置,而我又不想讲这些变量都加入到系统的环境变量中,一方面是由于有一些同名的库文件的版本号却不一样,都 写在系统环境中会相互干扰:还有一方面则是大部分的路径仅仅 ...

  7. Oracle批量执行脚本文件

    以下是Oracle批量执行脚本文件的步骤和方法 1.创建脚本文件(xx.sql): 例如文件CreateTable Create table tb1( id varchar2(30), Name va ...

  8. NuttX 介绍

    (嵌入式 实时操作系统 rtos nuttx 7.1) NuttX 介绍 转载请注明出处:http://blog.csdn.net/zhumaill/article/details/24197637 ...

  9. windows屏幕保护程序opengl模板

    Visual Studio 2013 屏幕保护程序opengl模板 ScreenSaver.cpp #define VC_EXTRALEAN #include <windows.h> #i ...

  10. Objective-C路成魔【2-Objective-C 规划】

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 编译执行O ...