fastjson反序列化formate时间等特殊格式处理,@JSONField的name属性首字母为大转JSON后变小写处理

5 篇文章 0 订阅
2 篇文章 0 订阅

背景

今天在实际编码过程中碰到一个问题,需要将实体格式化转为JSON,然后再将JSON反序列化为数据库对象存储到数据库中。@JSONField注解用的不亦乐乎,然后测试的时候悲剧了,JSON换格式要求为“yyyyMMddHHmmss”,那么果断“@JSONField(name = “xxxxxxx”, format = “yyyyMMddHHmmss”)”。当将转换的JSON对方反序列化发现时间格式字段无法反序列化并报错。网上各种找资料发现阿里的fastjson反序列化并不支持format。心里一万头草泥马奔过。没办法别人不提供咱自己弄吧(网上的感觉都不那么靠谱),亲测有效,如有性能等高要求的请略过。

注如果需要实现多级嵌套实体JSON间转换,请自行改造递归,此处不提供

序第二个问题当@JSONField的name属性首字母为大写,同时实体使用lombok的@data、@get、@set(不愿意写get、set,也就是@JSONField直接写在属性上而不是写在get方法上)测试转换为JSON对象时首字母变小写了。

干货-代码

问题一代码

public static <T> T JosnToObject(String json, Class<T> clazz) {
        JSONObject jsonObject = JSON.parseObject(json);
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            Object objValue = jsonObject.get(fieldName);
            if (objValue != null) {
                //如果是日期类型
                if (field.getGenericType().getTypeName().equals("java.sql.Timestamp")) {
                    JSONField jsonField = field.getAnnotation(JSONField.class);
                    if (jsonField != null) {
                        String formtStr = jsonField.format();
                        String nowVal = objValue.toString();
                        switch (formtStr) {
                            case "yyyyMMddHHmmss":
                                if (nowVal.length() == nowVal.length()) {
                                    nowVal = nowVal.substring(0, 4)
                                            + "-" + nowVal.substring(4, 6)
                                            + "-" + nowVal.substring(6, 8)
                                            + " " + nowVal.substring(8, 10)
                                            + ":" + nowVal.substring(10, 12)
                                            + ":" + nowVal.substring(12, 14);
                                }
                                break;
                            case "yyyyMMdd":
                                if (nowVal.length() == nowVal.length()) {
                                    nowVal = nowVal.substring(0, 4)
                                            + "-" + nowVal.substring(4, 6)
                                            + "-" + nowVal.substring(6, 8)
                                            + " 00:00:00";
                                }
                                break;
                            default:
                                break;
                        }

                        jsonObject.put(fieldName, Timestamp.valueOf(nowVal));
                    }
                }
            }
        }
        return JSONObject.toJavaObject(jsonObject, clazz);
    }

问题二代码

/**
     * json 序列化
     * @return
     */
    public static <T extends Object> String objToJson(T obj,Class<T> clazz){
        // 输出的JSON对象
        JSONObject newObj = new JSONObject();
        // 输入的JSON对象
        JSONObject jsonObj = (JSONObject) JSON.toJSON(obj);
        for(String key : jsonObj.keySet()){
            for(Field field : clazz.getDeclaredFields()){
                if(field.getName().toLowerCase().equals(key.toLowerCase())){
                    // 获取字段注解内容
                    JSONField annotation = field.getAnnotation(JSONField.class);
                    Object o = jsonObj.get(key);
                    if(o != null){
                        // 重新封装JSON对象
                        newObj.put(annotation.name(),o);
                    }
                }
            }
        }
        return newObj.toJSONString();
    }

原理

  • 问题一
    • 将JSON转换为JSONObject对象
    • 获取转换后实体所有属性
    • 遍历实体属性
    • 获取属性上JSONField注解对象
    • 检测到format属性为需要重新格式化时
    • 原值格式化为正确格式类型(源码只提供了时间格式,其他格式自行添加不赘述)
    • 修改JSONObject对象中对应属性值为格式化后的值
    • 调用JSONObject.toJavaObject转为实体返回
  • 问题二
    • 创建输出JSONObject对象
    • json反序列化输入JSONObject对象
    • 嵌套循环输入JSONObject对象与实体属性集合
    • 名称转小写比对一致则替换
    • 调用JSONObject.toJavaObject转为实体返回
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值