调用RESTFul服务,用Gson序列化返回对象

一个应用使用 Spring Mvc 实现的 RESTFul Webservice,其Controller 用下面的类包装结果返回给调用方。

public class BaseResponse<T> {
    private String msg = "message not set";
    private T data;
	
    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    
	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}	
}

我们调用方就直接使用 Spring 的 RestTemplate 调用其服务,调用过程中发现如果有个时间字段被序列化成 Long 型,会导致简单的 Gson 反序列化出问题。网上搜了下解决方案蛮多,就抄了个下面的:

public class GsonUtil {
	public static Gson getDateGson() {
		JsonDeserializer<Date> dateJsonDeserializer = (json, typeOfT, context) -> json == null ? null : new Date(json.getAsLong());
		return new GsonBuilder().registerTypeAdapter(Date.class,dateJsonDeserializer).create();
	}
}

然后封装下 RestTemplate:

public class SpringRest<T> {
	private Type type;
	private RestTemplate rest;
	
	public SpringRest(Type type){
		rest = new RestTemplate();
		this.type = type;
	}
	
	public T doGet(String url){		
		ResponseEntity<String> entity = rest.getForEntity(url, String.class);
				
		return getResult(entity);
	}
	
	public T doPost(String url, Object input){
		ResponseEntity<String> entity = rest.postForEntity(url, input, String.class);
		
		return getResult(entity);
	}

	private T getResult(ResponseEntity<String> entity) {
		String str = entity.getBody();			
		BaseResponse<T> resp = GsonUtil.getDateGson().fromJson(str, type);
		return resp.getData();
	}
}


这里本来不打算定义 type 属性,而是直接在 getResult 方法的 fromJson 里直接传如 new TypeToken<BaseResponse<T>>() {}.getType(),也即:

BaseResponse<T> resp = GsonUtil.getDateGson().fromJson(str, new TypeToken<BaseResponse<T>() {}.getType());

但真正执行时,不起作用,T 不能运行时替换成实际类型,所以把 type 的实例作为构造函数的参数传入。测试代码:

public class Test {
	
	public static void main(final String[] args) throws Exception {
		SpringRest<List<Project>> rest = new SpringRest<>(new TypeToken<BaseResponse<List<Project>>>() {}.getType());
		List<Project> projects = rest.doGet("http://localhost:8090/MyApp/project/21/projects");
		 
		for (Project p : projects){
			System.out.println(p.getName());
		}
    } 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值