kubernetes官方java客户端序列化问题

问题描述

A为中台项目,B为节点项目,B通过client-java-api.jar获取prometheus监控数据,A通过接口调用定时获取节点监控信息,A、B项目均为springboot项目。

开发过程中,A调用B接口失败,查看A项目日志,B接口返回500,查看B项目日志有错误信息如图所示:
在这里插入图片描述

问题分析

B返回json数据给A项目需要经过对象序列化成json,springboot接口序列化默认使用Jackson,而k8s client-java-api.jar包返回的对象中有IntOrString类型,值为百分比(例如25%),jackson在序列化成json时会调用该类型的IntOrString.getIntValue方法,导致报错。

问题解决

解决方法一:使用Gson排除Jackson,考虑到B项目功能较多较复杂,不宜采用这种方式。

解决方法二:B接口返回时先使用new Gson().toJson(xxx)转成字符串放入Result对象,A项目使用Gson重新把字符串解析为对象

处理代码

由于Gson处理joda日期时间会出现Failed to invoke public org.joda.time.Chronology() with no args错误,所以还需要在使用Gson时指定datetime处理方式,网上找了很多DateTimeSerializer都报错,下面是本人修改后亲测可用的代码:

import com.google.gson.*;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.lang.reflect.Type;

public class DateTimeSerializer implements JsonDeserializer<DateTime>, JsonSerializer<DateTime>
{
    private static final String FORMAT_FULL_TIME_NO_ZONE = "yyyy-MM-dd HH:mm:ss";
    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public DateTime deserialize(final JsonElement je, final Type type,
                                final JsonDeserializationContext jdc) throws JsonParseException
    {
        final String dateAsString = je.getAsString();
        if (dateAsString.length() == 0)
        {
            return null;
        }
        else
        {
            return dateTimeFormatter.parseDateTime(dateAsString);
        }
    }

    @Override
    public JsonElement serialize(final DateTime src, final Type typeOfSrc,
                                 final JsonSerializationContext context)
    {
        String retVal;
        if (src == null)
        {
            retVal = "";
        }
        else
        {
            retVal = new DateTime(src).toString(FORMAT_FULL_TIME_NO_ZONE);
        }
        return new JsonPrimitive(retVal);
    }
 
}

A项目Gson处理

final GsonBuilder builder = new GsonBuilder().registerTypeAdapter(DateTime.class, new DateTimeSerializer());
final Gson gson = builder.create();
Map<String, List<V1Deployment>> deploymentMap = gson.fromJson(responseResult.getData(), new TypeToken<Map<String, List<V1Deployment>>>() {}.getType());

B项目Gson处理

final GsonBuilder builder = new GsonBuilder().registerTypeAdapter(DateTime.class, new DateTimeSerializer());
final Gson gson = builder.create();
return ResponseEntity.ok(new Result.Builder<>(true).data(gson.toJson(result)).build());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值