zoukankan      html  css  js  c++  java
  • 【Json】Jackson将json转换成泛型List

    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

  • 相关阅读:
    LeetCode Longest Uncommon Subsequence II
    Leetcode Longest Uncommon Subsequence I
    LeetCode 557. Reverse Words in a String III
    LeetCode 394. Decode String
    LeetCode 419. Battleships in a Board
    LeetCode 366. Find Leaves of Binary Tree
    LeetCode 408. Valid Word Abbreviation
    LeetCode 532. K-diff Pairs in an Array
    LeetCode Minimum Absolute Difference in BST
    LeetCode 414. Third Maximum Number
  • 原文地址:https://www.cnblogs.com/ssslinppp/p/7919775.html
Copyright © 2011-2022 走看看