自己定义GSON类型适配器
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类型适配器的更多相关文章
- Gson 基础教程 —— 自定义类型适配器(TypeAdapter)
1,实现一个类型适配器(TypeAdapter) 自定义类型适配器需要实现两个接口: JsonSerializer<T> JsonDeserializer<T> 和两个方法: ...
- SQL 用户定义表类型,在存储过程里使用表类型,表参数作参数
.定义表类型SUTDENTTYPE,包含三个字段,分别对应学生表的NAME,SEX和PHONE.之所以如此创建,我是准备在插入新学生数据的存储过程中,以它为参数. GO CREATE TYPE S ...
- C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)
今天在进行代码测试时发现,尝试在一个方法中定义一个委托,注意是定义一个委托,而不是声明一个委托变量,在编写的时候没有报错,VS也能智能提示,但在编译时却报语法不完整,缺少方括号,但实际查询并没有缺少, ...
- Android中常用适配器及定义自己的适配器
转载:http://blog.chinaunix.net/uid-11898547-id-3303153.html http://www.tudou.com/home/_328390108/item ...
- 【VBA研究】变量定义的类型和实际赋值类型
作者:iamlaosong VBA中变量能够先定义后使用,也能够不定义直接使用.假设模块前面加了Option Explicit语句,则变量必须先定义后使用. 只是.实验发现.VBA对变量类型没有进行严 ...
- Sql server 浅谈用户定义表类型
1.1 简介 SQL Server 中,用户定义表类型是指用户所定义的表示表结构定义的类型.您可以使用用户定义表类型为存储过程或函数声明表值参数,或者声明您要在批处理中或在存储过程或函数的主体中使用的 ...
- 使用typedef语句定义数组类型
使用typedef语句定义数组类型 1. 一维数组类型的定义格式 typedef <元素类型关键字><数组类型名>[<常量表达式>]; 例如: (1) ty ...
- typedef定义数组类型
typedef语句定义数组类型 1. 一维数组类型的定义格式 typedef <元素类型关键字><数组类型名>[<常量表达式>]; 例如: (1) typedef ...
- sqlserver 若字段定义的类型为datetime
sqlserver 若字段定义的类型为datetime,插入为''(空),那么会默认值为1900-01-01 00:00:00.000 解决 插入 NULL 或者程序判断
随机推荐
- Dictionary带来的一种隐式内存泄漏
当心Dictionary带来的一种隐式内存泄漏 最近在看Dictionary的源代码的时候, 突然想到Dictionary的不当使用中有一种隐含内存泄漏的可能. 简化使用场景 小A正在写一个简单的图书 ...
- HttpLuaModule——翻译(Nginx API for Lua) (转)
现在我已经将翻译的内容放到:http://wiki.nginx.org/HttpLuaModuleZh Nginx API for Lua Introduction 各种各样的*_by_lua和*_b ...
- Linux中查看socket状态(转)
Linux中查看socket状态:cat /proc/net/sockstat #(这个是ipv4的) sockets: used 137 TCP: inuse 49 orphan 0 tw 3272 ...
- HDU4866 Shooting (要持久段树)
意甲冠军: 给你一些并行x行轴.总是询问坐标x的顶部之前,k一个段高度,.标题是必须在线. 思路: 首先要会可持久化线段树(又称主席树和函数式线段树).不会的能够去做下POJ 2104. 把全部线段高 ...
- crm创建基于fetch自己的自定义报告
在解决方案资源管理器,右键点击"报表"目录.然后点击"增加了新的报告". 打开"报表向导". 在"欢迎来到报表向导"前, ...
- 可以改变文本行距(行间距)的Label
////////////////////////////////////////////////////// /// ///功能:可以改变文本行距(行间距)的Label ///作者:emanlee / ...
- Unity3D-RPG项目实战(1):发动机的特殊文件夹
前言 从8月份開始.下定决心正式開始学习Unit3D啦.尽管自己写过两代端游引擎,被应用的项目也超过10个,Unreal Engine也搞过几年,只是做手游.哥确实还是个新手.Unity3D这个引擎我 ...
- 基于HTML5气3D仿真培训系统
根据最近的上线HTML5的燃气3D培训仿真系统.曾经的老系统是採用基于C++和OpenGL的OpenSceneGraph引擎设计的,OSG引擎性能和渲染效果各方面还是不错的,但由于这次新产品需求要求能 ...
- Centos安装后,没有ifconfig工具
yum install net-tools yum不能用时,就下载rpm来安装 hostname -f, --fqdn, --long Display the FQDN (Fully Qualifie ...
- 大约Java有点感悟---开发商根本上感悟学习
这些年来一直从事大C.C++,有些局部底.一直想知道更多关于顶级什么. 所以,在工作之余.阅读更多Java哪些方面,还使用了一些建筑结构的一些简单的程序,在这里我想简单谈谈自己的一点感悟. 1.Jav ...