【问题标题】:How to convert Map<String, Map<MetricName, ? extends Metric>> into JsonObject如何转换 Map<String, Map<MetricName, ?将 Metric>> 扩展为 JsonObject
【发布时间】:2020-04-19 04:40:42
【问题描述】:

我正在尝试将 Map> 转换为 JSON 对象。我尝试了两种不同的转换方式。

  1. 使用 ObjectMapper:

这里的代码看起来像,但返回 null。

       @GetMapping("/showRawKafkaMetrics")
            public String getMetrics() throws JsonProcessingException {
                StringBuilder sb = new StringBuilder();
                ObjectMapper objectMapper = new ObjectMapper();
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry
                        .getListenerContainers()) {
    // The below map of metrics I'm trying to convert into json Object
                    Map<String, Map<MetricName, ? extends Metric>> metrics = messageListenerContainer.metrics();
                     metrics.forEach((clientid, metricMap) -> {
                        log.info("Client Id:"+sb.toString());
                         String json = null;
                         try {
                             json = objectMapper.writeValueAsString(metricMap);
                         } catch (JsonProcessingException e) {
                             e.printStackTrace();
                         }
                         log.info("JSON Metrics :"+json);
                        metricMap.forEach((metricName, metricValue) -> {
                            log.info("------------ Metric name: " + metricName.name() + " ----------- Metric value: "
                                    + metricValue.metricValue() + LINE_BREAK);
                        });
                    });
                }
                String metrics = sb.toString();
                return metrics;
            }

****2. Using JSON Object 

Here is the code looks like:****
         @GetMapping("/showRawKafkaMetrics")
                    public String getMetrics() throws JsonProcessingException {
                        StringBuilder sb = new StringBuilder();
                        JsonObject jsonObject = new JsonObject();
                        for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry
                                .getListenerContainers()) {
    // The below map of metrics I'm trying to convert into json Object
    // The below map of metrics I'm trying to convert into json Object

                            Map<String, Map<MetricName, ? extends Metric>> metrics = messageListenerContainer.metrics();

                            metrics.forEach((clientid, metricMap) -> {
                                log.info("Client Id:"+sb.toString());
                                metricMap.forEach((metricName, metricValue) -> {
                                    log.info("------------ Metric name: " + metricName.name() + " ----------- Metric value: "
                                            + metricValue.metricValue() + LINE_BREAK);
                                    jsonObject.add(metricName.toString(), (JsonElement) metricValue);
                                    log.info("JSON METRICS:"+jsonObject);
                                });
                            });
                        }
                        String metrics = sb.toString();
                        return metrics;
                    }

在这两种情况下,我都会得到空指针。谁能建议我将度量地图转换为 JsonObject 的最佳方法。因此,我可以进一步处理它以创建仪表板。

【问题讨论】:

  • 您尝试过 Jackson 和原生 JSON,但您是否尝试过 GSON。

标签: java json jackson gson metrics


【解决方案1】:

让 Spring 为您完成。添加@ResponseBody 和produces = "application/json"。

问题是关于Map&lt;String, Map&lt;MetricName, ? extends Metric&gt;&gt;,这是messageListenerContainer.metrics()返回的内容,但是你有一个messageListenerContainer对象的列表,所以你真正想要的是其中的List,要转换为JSON .

@GetMapping(path = "/showRawKafkaMetrics", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String getMetrics() {
    List<Map<String, Map<MetricName, ? extends Metric>>> list = new ArrayList<>();
    for (MessageListenerContainer container : kafkaListenerEndpointRegistry.getListenerContainers())
        list.add(container.metrics());
    return list;
}

【讨论】:

  • 我收到了 500 responseCode 并进行了上述更改。抛出一些异常。 “消息”:“类型定义错误:[简单类型,classorg.apache.kafka.common.metrics.KafkaMetric];嵌套异常 iscom.fasterxml.jackson.databind.exc.InvalidDefinitionException:找不到类 org.apache.kafka 的序列化程序.common.metrics.KafkaMetric 并且没有发现用于创建 BeanSerializer 的属性
  • @TechGeek 所以这也是你得到空值的原因,因为它失败了,你吞下了异常,留下变量json 具有其预初始化的空值。这意味着您需要为Metric 创建一个Serializer,或者您需要将其转换为可以序列化的POJO 对象。参见例如Jackson How-To: Custom Serializers
【解决方案2】:

它不起作用并且你得到null 的原因是你试图序列化MetricName 和Metric 类本身。

我想,ObjectMapper 的示例会抛出一个 JsonProcessingException,它只是打印在控制台中,这就是为什么 json 保留为 null。

要使用fastxml ObjectMapper 进行这项工作,请准备您自己的DTO 类结构,或者仅使用java.util.Map 并使用ObjectMapper#writeValueAsString 对其进行序列化。

请参阅FasterXML docs 和示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-29
    • 2014-02-27
    • 1970-01-01
    • 2021-05-26
    • 2013-05-24
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多