Jackson将json转换成泛型List

获取泛型类型

/**
* 获取泛型类型
*
* @return
*/
protected Class<T> getGenericsType() {
final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {
};
final Class<T> type = (Class<T>) typeToken.getRawType();
return type;
}

Jackson库--json转换成泛型List

/**
* 获取Jackson的{@code List<T>}类型
*
* @param mapper
* @return
*/
protected JavaType getListType(ObjectMapper mapper) {
JavaType javaType = getCollectionType(mapper, ArrayList.class, getGenericsType());
return javaType;
} /**
* 获取Jackson的集合类型
*
* @param mapper
* @param collectionClass 集合类型
* @param elementClasses 集合元素类型
* @return
*/
protected JavaType getCollectionType(ObjectMapper mapper, Class<?> collectionClass, Class<?>... elementClasses) {
return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}

Json转换操作

 ObjectMapper mapper = new ObjectMapper();
List<T> queryResults = mapper.readValue(jsonStr, getListType(mapper));

使用

 IGraphiteQueryTemplete<GraQueryResultSub> queryTempleteWithType = new AbstractGraphiteQueryTemplete<GraQueryResultSub>() { };
List<GraQueryResultSub> queryResults = queryTempleteWithType.postQuery(queryParam);

完整代码

接口

import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryParam;
import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryResult; import java.io.IOException;
import java.util.List; public interface IGraphiteQueryTemplete<T extends GraphiteQueryResult> {
/**
* post请求,查询Graphite数据,默认格式为:json
*
* @param queryParam
* @return
*/
List<T> postQuery(GraphiteQueryParam queryParam) throws IOException;
}

抽象基类

import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryParam;
import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryResult;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.reflect.TypeToken;
import org.assertj.core.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate; import java.text.SimpleDateFormat;
import java.util.ArrayList; public abstract class GraphiteQueryTempleteBase<T extends GraphiteQueryResult> implements IGraphiteQueryTemplete<T> {
private static final Logger logger = LoggerFactory.getLogger(GraphiteQueryTempleteBase.class); @Autowired
protected RestTemplate restTemplate;
// protected RestTemplate restTemplate = new RestTemplate(); /**
* 获取 Graphite 查询 post 请求体<br/>
*
* @param queryParam Graphite查询参数
* @return
*/
protected HttpEntity<MultiValueMap<String, String>> getGraphitePostHttpEntity(GraphiteQueryParam queryParam) {
// 校验输入参数
if (Strings.isNullOrEmpty(queryParam.getTarget())) {
String message = String.format("Graphite query: target can not be null(empty),%s", queryParam.toString());
logger.error(message);
throw new IllegalArgumentException(message);
} String targetQuery = Strings.isNullOrEmpty(queryParam.getAliasName()) ? queryParam.getTarget()
: String.format("alias(%s,\"%s\")", queryParam.getTarget(), queryParam.getAliasName());
String fromQuery = ObjectUtils.isEmpty(queryParam.getFrom()) ? queryParam.getFromDefault()
: String.valueOf((queryParam.getFrom().getTime() / 1000));
String untilQuery = ObjectUtils.isEmpty(queryParam.getUntil()) ? queryParam.getUntilDefault()
: String.valueOf((queryParam.getUntil().getTime() / 1000));
String formatQuery = Strings.isNullOrEmpty(queryParam.getFormat()) ? "json" : queryParam.getFormat(); // 测试使用,方便显示
SimpleDateFormat renderSdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
String fromForDebug = ObjectUtils.isEmpty(queryParam.getFrom()) ? queryParam.getFromDefault()
: renderSdf.format(queryParam.getFrom());
String untilForDebug = ObjectUtils.isEmpty(queryParam.getUntil()) ? queryParam.getUntilDefault()
: renderSdf.format(queryParam.getUntil()); // 设置HTTP post 请求体参数
MultiValueMap<String, String> bodyMap = new LinkedMultiValueMap<String, String>();
bodyMap.add("target", targetQuery);
bodyMap.add("format", formatQuery);
bodyMap.add("from", fromQuery);
bodyMap.add("until", untilQuery);
bodyMap.add("fromForDebug", fromForDebug);
bodyMap.add("untilForDebug", untilForDebug); // 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 设置 HTTP Request
HttpEntity<MultiValueMap<String, String>> requestBody = new HttpEntity<MultiValueMap<String, String>>(bodyMap, headers); return requestBody;
} /**
* 获取泛型类型
*
* @return
*/
protected Class<T> getGenericsType() {
final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {
};
final Class<T> type = (Class<T>) typeToken.getRawType();
return type;
} /**
* 获取Jackson的{@code List<T>}类型
*
* @param mapper
* @return
*/
protected JavaType getListType(ObjectMapper mapper) {
JavaType javaType = getCollectionType(mapper, ArrayList.class, getGenericsType());
return javaType;
} /**
* 获取Jackson的集合类型
*
* @param mapper
* @param collectionClass 集合类型
* @param elementClasses 集合元素类型
* @return
*/
protected JavaType getCollectionType(ObjectMapper mapper, Class<?> collectionClass, Class<?>... elementClasses) {
return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
}

泛型实现类

import com.chinamobile.epic.graphite.query.GraphiteQueryTempleteBase;
import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryParam;
import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils; import java.io.IOException;
import java.util.List; @SuppressWarnings("Duplicates")
public abstract class AbstractGraphiteQueryTemplete<T extends GraphiteQueryResult> extends GraphiteQueryTempleteBase<T> {
private static final Logger logger = LoggerFactory.getLogger(AbstractGraphiteQueryTemplete.class); @Override
public List<T> postQuery(GraphiteQueryParam queryParam) throws IOException {
logger.info("GraphitePostQuery - Begin to graphite post query...");
HttpEntity<MultiValueMap<String, String>> requestBody = getGraphitePostHttpEntity(queryParam);
logger.info("GraphitePostQuery - {GraphiteQueryParam: {}, requestBody: {}}", queryParam.toString(), requestBody.toString()); // 查询
ResponseEntity<String> responseEntity = restTemplate.exchange(queryParam.getRenderUrl(), HttpMethod.POST, requestBody, String
.class);
logger.info("GraphitePostQuery - query finished, begin to convert query result"); // 获取结果
List<T> queryResults = null;
if (responseEntity.getStatusCode() == HttpStatus.OK) { //返回成功
if (!StringUtils.isEmpty(responseEntity.getBody())) {
ObjectMapper mapper = new ObjectMapper();
try {
// queryResults = (List<T>) mapper.readValue(responseEntity.getBody(), new TypeReference<List<T>>() { });
queryResults = mapper.readValue(responseEntity.getBody(), getListType(mapper));
} catch (IOException e) {
throw new IOException("Convert graphiteResult failed", e);
}
}
} else {//返回失败
throw new RuntimeException(String.format("Graphite post query failed,[ statusCode: %s,queryParam: %s, requestBody: %s]",
responseEntity.getStatusCode(), queryParam, requestBody));
}
logger.info("GraphitePostQuery - convert query result finish, queryResults.size(): {}", queryResults.size()); return queryResults;
}
}

model类

GraphiteQueryResult.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; import java.util.List; /**
* Desc: Graphite查询结果, 参考:MetricDataModel.java;
* 该类的所有子类都可以用于接收Graphite查询结果转换;
* <p>
* <p>
* <pre>
* [
* {
* "target": "10_144_202_150",
* "datapoints": [
* [
* 1025968.9066666667,
* 1511861400
* ],
* [
* 254849.70666666667,
* 1511861700
* ]
* ]
* },
* {
* "target": "10_144_202_151",
* "datapoints": [
* [
* 447786.56,
* 1511861400
* ],
* [
* 103653.6,
* 1511861700
* ]
* ]
* }
* ]
* </pre>
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GraphiteQueryResult {
private String target;
private List<List<Object>> datapoints;
}

GraphiteQueryParam.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; import java.util.Date; @Data
@AllArgsConstructor
@NoArgsConstructor
public class GraphiteQueryParam {
private String renderUrl; //示例:http://10.144.202.150:5000/render
private String target;
private String aliasName; //别名 /**
* Graphite支持"-10min, now, -1d"等格式的时间表示,也支持以Date的时间表示;
* 在处理from(fromDefault)/until(untilDefault)时:
* 1. 优先使用from/until;
* 2. 当from/until为null时,使用 fromDefault/untilDefault 的形式
*/
private String fromDefault = "-10min"; //默认查询最近10min数据
private String untilDefault = "now"; //以String形式表示的结束时间
private Date from; //以date形式表示的开始时间
private Date until; //以date形式表示的结束时间 private String format = "json";
}

测试类

import com.chinamobile.epic.graphite.query.IGraphiteQueryTemplete;
import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryParam;
import com.chinamobile.epic.tako.model.performance.v2.graphite.GraphiteQueryResult;
import lombok.Data;
import lombok.ToString;
import org.junit.Before;
import org.junit.Test; import java.util.List; public class AbstractGraphiteQueryTempleteTest {
private GraphiteQueryParam queryParam; @Before
public void init() {
System.out.println("init...");
queryParam = new GraphiteQueryParam();
queryParam.setRenderUrl("http://10.144.202.150:5000/render");
queryParam.setTarget("groupByNode(scale(perSecond(summarize(EPIC.pm.{*}.interface.{*}.if_octets.rx, '5min', 'last', false)), 8), " +
"2, 'sum')");
} @Test
public void postQueryWithType() throws Exception {
IGraphiteQueryTemplete<GraQueryResultSub> queryTempleteWithType = new AbstractGraphiteQueryTemplete<GraQueryResultSub>() {
};
List<GraQueryResultSub> queryResults = queryTempleteWithType.postQuery(queryParam);
System.out.println(queryResults);
/**
* 输出:
* [AbstractGraphiteQueryTempleteTest.GraQueryResultSub(super=GraphiteQueryResult(target=10_144_201_1, datapoints=[[null,
* 1511925900], [null, 1511926200]]), resourceId=null),
* AbstractGraphiteQueryTempleteTest.GraQueryResultSub(super=GraphiteQueryResult(target=10_144_202_150, datapoints=[[null,
* 1511925900], [983632.64, 1511926200]]), resourceId=null),
* AbstractGraphiteQueryTempleteTest.GraQueryResultSub(super=GraphiteQueryResult(target=10_144_202_151, datapoints=[[null,
* 1511925900], [441477.6533333333, 1511926200]]), resourceId=null)]
*/
} @Data
@ToString(callSuper = true)
public static class GraQueryResultSub extends GraphiteQueryResult {
private String resourceId;
}
}

参考

Jackson将json转换成泛型List

【Json】Jackson将json转换成泛型List的更多相关文章

  1. Json 的日期格式转换成DateTime

    JSON 的日期形式:”/Date(1242357713797+0800)/” , 下面我们就用以下C#的方法将他转换成DateTime类型: /// <summary> /// Json ...

  2. (精华)将json数组和对象转换成List和Map(小龙哥和牛徳鹤的对话)

    将java标准的数据结构ArrayList和HashMap转换成json对象和数组很简单 只需要JSONArray.fromObject(obj);或者JSONObject.fromObject(ob ...

  3. json中把非json格式的字符串转换成json对象再转换成json字符串

    JSON.toJson(str).toString()假如key和value都是整数的时候,先转换成jsonObject对象,再转换成json字符串

  4. Jackson将json字符串转换成泛型List

    Jackson,我感觉是在Java与Json之间相互转换的最快速的框架,当然Google的Gson也很不错,但是参照网上有人的性能测试,看起来还是Jackson比较快一点 Jackson处理一般的Ja ...

  5. iOS开发之JSON转PLIST(把存储json格式的文件转换成plist文件)

    p.p1 { margin: 0.0px 0.0px 0.0px 60.0px; font: 16.0px "PingFang SC"; color: #586e75 } p.p2 ...

  6. 把json格式的字符串转换成javascript对象或数组

      第一种 JSON.parse(jsonString) 第二种 eval("("+jsonString+")") 第三种 var obj=(function ...

  7. 将json的时间格式转换成正常的时间格式

    /** * 对Date的扩展,将 Date 转化为指定格式的String * 月(M).日(d).12小时(h).24小时(H).分(m).秒(s).周(E).季度(q) 可以用 1-2 个占位符 * ...

  8. 使用jackson来进行数组格式的json字符串转换成List。

    有一个字符串如下.如下,也是通过jackson把list转换成的json字符串,我想把它转过来,看网上的内容都不尽人如意,都是片断的内容.估计只有写的知道怎么使用,所以就直接看了jackson的官网, ...

  9. 前台 JSON对象转换成字符串 相互转换 的几种方式

    在最近的工作中,使用到JSON进行数据的传递,特别是从前端传递到后台,前台可以直接采用ajax的data函数,按json格式传递,后台Request即可,但有的时候,需要传递多个参数,后台使用requ ...

随机推荐

  1. 基于hiredis,redis C客户端封装

    项目中需要用到redis就封装了一下,基于hiredis,只封装了string和哈希的部分方法.编译时加入-D__USER_LOCK__添加线程安全. suntelRedisCli.h #ifndef ...

  2. dp——环形石子合并(区间dp)

    环形的解决很巧妙 #include <iostream> #include <cstring> #include <string> #include <map ...

  3. 为何linux(包括mac系统)执行指令要加上 ./ ??

    比如,现在要在$HIVE_HOME/bin下执行hive指令来启动hive,则该指令的执行顺序如下所示: 1 先找PATH路径 1.1 如果PATH路径下配置了$HIVE_HOME/bin,无论PAT ...

  4. .net core 微服务架构-docker的部署-包括网关服务(Ocelot)+认证服务(IdentityServer4)+应用服务(asp.net core web api)

    本文主要介绍通过Docker来部署通过.Net Core开发的微服务架构,部署的微服务主要包括统一网关(使用Ocelot开发).统一认证(IdentityServer4).应用服务(asp.net c ...

  5. Linux,IDS入侵防御系统

    https://www.comparitech.com/net-admin/network-intrusion-detection-tools/11 2018年的顶级入侵检测工具 https://op ...

  6. Python知识点整理,基础4 - 集合操作

  7. mongodb备份与还原

    mongodb单机: 备份所有的库: mongodump --host 10.10.7.33:27019 --gzip --out /home/mongodb/0415_bf 备份指定的库: mong ...

  8. S老师 Shader 学习

    Mesh Filter : 存储一个Mesh(网格,模型的网格,就是模型的由哪些三角面组成,组成一个什么样子的模型,三角面的一些顶点信息) Mesh Renderer:用来渲染一个模型的外观,就是样子 ...

  9. promise对象的回调函数resolve的参数为另一个promise对象

    /*如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数. reject函数的参数通常是Error对象的实例,表示抛出的错误: resolve函数的参数除了正常的值 ...

  10. 笔记本centos 取消 关闭盖子自动挂起

    修改 vi /etc/systemd/logind.conf HandleLidSwitch=ignore ( 操作盖子开关=忽略  ) 这样关闭盖子 就不会挂起了.