自己定义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 或者程序判断
随机推荐
- 使用X264编码yuv格式的视频帧使用ffmpeg解码h264视频帧
前面一篇博客介绍在centos上搭建点击打开链接ffmpeg及x264开发环境.以下就来问个样例: 1.利用x264库将YUV格式视频文件编码为h264格式视频文件 2.利用ffmpeh库将h264格 ...
- php xss过滤
XSS已知CSS (Cross Site Script) ,跨站点脚本攻击.它指的是恶意攻击者Web插入恶意网页html代码,当用户浏览网页.其中嵌入Web里面html代码运行,从而实现了一些人的攻击 ...
- 各种ESB产品比较(转)
介绍了主流商业和开源ESB的发展趋势.可借鉴的地方和其缺点: 主要介绍: Oracle Service Bus WebSphere Message Broker ...
- chrome使用技巧(转)good
阅读目录 写在前面 快速切换文件 在源代码中搜索 在源代码中快速跳转到指定的行 使用多个插入符进行选择 设备模式 设备传感仿真 格式化凌乱的js源码 颜色选择器 改变颜色格式 强制改变元素状态(方便查 ...
- 站点系统压力測试Jmeter+Badboy
近期项目须要压力測试,因此搜了几款试用,首选的是LoadRunner这款大名鼎鼎的測试软件: LoadRunner11 下载请猛戳这里 传送门LoadRunner破解文件 下载请猛戳这里 传送门Loa ...
- redis内存管理代码的目光
zmalloc.h /* zmalloc - total amount of allocated memory aware version of malloc() * * Copyright (c) ...
- RecyclerView0基于使用
(转载请注明出处:http://www.kennethyo.me/post/android/recyclerviewchu-ji-shi-yong) RecyclerView是Android在v7包中 ...
- Spring aop 小例子demo
由于最近的服务项目提供接口有一个需求,所有操作都必须检查操作的服务可用,所以感觉Aop特别适合实施.完成学习的小例子. 关于spring-Aop原理:http://m.oschina.net/blog ...
- Afinal载入网络图片及下载文件用法
Afinal高速开发框架使用起来很方便.以下将解说怎样利用Afinal载入网络图片及下载文件: 先看效果图: 注意:使用Afinal前需加入Afinal的jar,能够在这里下载:http://down ...
- 算法----选择排序(select sort)
排序不是一个时间的数组进行排序,找到最小的元素,其与阵列的第一个元素交换,因此,排序的数组. 算法: void sort::select_sort(int* a,const int n) { for( ...