• 自己定义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?urlu003dabc}"}



  • 相关阅读:
    【转】聚集索引和非聚集索引的区别
    【转】【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式,并把SQLite的数据库文件存储在SD卡中!!!
    【转】数据库范式(1NF 2NF 3NF BCNF)详解一
    【转】数据库 无损连接分解
    如何防止被路由器限速如何更改电脑网卡的MAC地址
    BZOJ 1497 最大权闭合图
    POJ 1966 无向图点联通度 最小割
    POJ 1815 最小割
    POJ 2987 最大权闭合图
    POJ 2391 floyd+二分+最大流
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4220393.html
Copyright © 2020-2023  润新知