Java 对象toString()之后转化成json对象

2023-11-06

在平时的工作中经常遇到Java对象toString()之后打印出来,在发生线上问题时需要参数重新调用时,无法转化参数

如下图:

[TransOccupyRequestDTO(newOrderId=390310807, transOccupyDetails=[TransOccupyDetail(orderId=389507562, orderType=3Sent, orderListId=811181368, newOrderId=390310807, newOrderListId=812635303, batchId=197987597, num=2), TransOccupyDetail(orderId=389507562, orderType=3Sent, orderListId=811181368, newOrderId=390310807, newOrderListId=812635303, batchId=197987597, num=1), TransOccupyDetail(orderId=389507562, orderType=3Sent, orderListId=811181369, newOrderId=390310807, newOrderListId=811181369, batchId=202747933, num=4)])]

下面是一个工具类实现Java对象转化成json 

import com.alibaba.fastjson.JSON;
import javafx.util.Pair;
import org.apache.commons.lang.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

public class ToStringUtils {

    /**
     * toString格式反序列化
     */

    /**
     * 数字类型匹配(包括整形和浮点型) & 日期类型匹配 & 对象类型匹配 & ...
     */
    public static Pattern datePattern = Pattern.compile("^[a-zA-Z]{3} [a-zA-Z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} CST ((19|20)\\d{2})$");
    public static Pattern numPattern = Pattern.compile("^-?[0-9]+\\.?[0-9]*$");
    public static Pattern objectPattern = Pattern.compile("^[a-zA-Z0-9\\.]+\\(.+\\)$");
    public static Pattern listPattern = Pattern.compile("^\\[.*\\]$");
    public static Pattern mapPattern = Pattern.compile("^\\{.*\\}$");
    public static Pattern supperPattern = Pattern.compile("^super=[a-zA-Z0-9\\.]+\\(.+\\)$");
    public static final String NULL = "null";

    /**
     * toString -> json
     */
    public static String toJSONString(String toString) throws ParseException {
        return JSON.toJSONString(toMap(toString));
    }

    /**
     * toString -> object
     */
    public static <T> T toObject(String toString, Class<T> clazz) throws ParseException {
        return JSON.parseObject(toJSONString(toString), clazz);
    }

    /**
     * toString -> map
     */
    private static Map<String, Object> toMap(String toString) throws ParseException {
        if (StringUtils.isEmpty(toString = StringUtils.trim(toString))) {
            return toString == null ? null : new HashMap<>();
        }

        // 移除最外层"()"
        toString = StringUtils.substringAfter(toString, "(").trim();
        toString = StringUtils.substringBeforeLast(toString, ")").trim();

        String token;
        Map<String, Object> map = new HashMap<>();
        while (StringUtils.isNotEmpty(toString) && StringUtils.isNotEmpty(token =splitToken(toString))) {
            toString = StringUtils.removeStart(StringUtils.removeStart(toString, token).trim(), ",").trim();

            // 如果带"super="(lombok的@ToString(callSuper=true)引入),按照当前层继续处理
            if (supperPattern.matcher(token).matches()) {
                token = token.substring(token.indexOf("(") + 1, token.length() - 1);
                toString = String.format("%s,%s", token, toString);
                continue;
            }

            Pair<String, String> keyValue = parseToken(token);
            map.put(keyValue.getKey(), buildTypeValue(keyValue.getKey(), keyValue.getValue()));
        }
        return map;
    }
    static Pair<String, String> parseToken(String token) {
        assert Objects.nonNull(token) && token.contains("=");
        int pos = token.indexOf("=");
        return new javafx.util.Pair<>(token.substring(0, pos), token.substring(pos + 1));
    }

    /**
     * 单个token解析
     *
     * @param key 可根据key设置自定义序列化操作
     */
    private static Object buildTypeValue(String key, String value) throws ParseException {
        if (StringUtils.isEmpty(value)) {
            return null;
        } else if (value.equals(NULL)) {
            return null;
        }

        // 日期类型
        if (datePattern.matcher(value).matches()) {
            return new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", new Locale("us")).parse(value).getTime();
        }
        // 数字类型
        if (numPattern.matcher(value).matches()) {
            return value;
        }
        // 集合类型
        if (listPattern.matcher(value).matches()) {
            return buildListValue(value);
        }
        // map类型
        if (mapPattern.matcher(value).matches()) {
            return buildMapValue(value);
        }
        // 对象类型
        if (objectPattern.matcher(value).matches()) {
            return toMap(value);
        }

        // 其他都认为是string类型
        return value;
    }

    /**
     * 集合类型
     */
    private static Object buildListValue(String value) throws ParseException {
        List<Object> result = new ArrayList<>();

        value = value.substring(1, value.length() - 1).trim();
        if (StringUtils.isEmpty(value)) {
            return result;
        }

        String token = null;
        while (StringUtils.isNotBlank(value) && StringUtils.isNotBlank(token = splitToken(value))) {
            result.add(buildTypeValue(null, token));
            value = StringUtils.removeStart(StringUtils.removeStart(value, token).trim(), ",").trim();
        }

        return result;
    }

    static String splitToken(String toString) {
        if (StringUtils.isBlank(toString)) {
            return toString;
        }

        int bracketNum = 0;
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < toString.length(); i++) {
            Character c = toString.charAt(i);
            if (tokenMap.containsValue(c)) {
                stack.push(c);
            } else if (tokenMap.containsKey(c) && Objects.equals(stack.peek(), tokenMap.get(c))) {
                stack.pop();
            } else if ((c == ',') && stack.isEmpty()) {
                return toString.substring(0, i);
            }
        }
        if (stack.isEmpty()) {
            return toString;
        }
        throw new RuntimeException("splitFirstToken error, bracketNum=" + bracketNum + ", toString=" + toString);
    }

    /**
     * 获取第一个token,注意: toString不再包括最外层的()
     */
    private final static Map<Character, Character> tokenMap = new HashMap<>();
    static {
        tokenMap.put(')', '(');
        tokenMap.put('}', '{');
        tokenMap.put(']', '[');
    }


    /**
     * map类型
     */
    private static Map<Object, Object> buildMapValue(String value) throws ParseException {
        Map<Object, Object> result = new HashMap<>();
        value = value.substring(1, value.length() - 1).trim();
        if (StringUtils.isEmpty(value)) {
            return result;
        }

        String token = null;
        while (StringUtils.isNotEmpty(token =splitToken(value))) {
            Pair<String, String> keyValue =parseToken(token);
            result.put(buildTypeValue(keyValue.getKey(), keyValue.getKey()), buildTypeValue(keyValue.getKey(), keyValue.getValue()));

            value = StringUtils.removeStart(StringUtils.removeStart(value, token).trim(), ",").trim();
        }

        return result;
    }



}

最终测试结果

String str="[TransOccupyRequestDTO(newOrderId=390310807, transOccupyDetails=[TransOccupyDetail(orderId=389507562, orderType=3Sent, orderListId=811181368, newOrderId=390310807, newOrderListId=812635303, batchId=197987597, num=2), TransOccupyDetail(orderId=389507562, orderType=3Sent, orderListId=811181368, newOrderId=390310807, newOrderListId=812635303, batchId=197987597, num=1), TransOccupyDetail(orderId=389507562, orderType=3Sent, orderListId=811181369, newOrderId=390310807, newOrderListId=811181369, batchId=202747933, num=4)])]";
TransOccupyRequestDTO transOccupyRequestDTO = ToStringUtils.toObject(str,TransOccupyRequestDTO.class);
System.out.println(JSON.toJSON(transOccupyRequestDTO));

Connected to the target VM, address: '127.0.0.1:62799', transport: 'socket'
{"newOrderId":390310807,"transOccupyDetails":[{"orderType":"3Sent","orderListId":811181368,"orderId":389507562,"newOrderId":390310807,"newOrderListId":812635303,"num":2,"batchId":197987597},{"orderType":"3Sent","orderListId":811181368,"orderId":389507562,"newOrderId":390310807,"newOrderListId":812635303,"num":1,"batchId":197987597},{"orderType":"3Sent","orderListId":811181369,"orderId":389507562,"newOrderId":390310807,"newOrderListId":811181369,"num":4,"batchId":202747933}]}
Disconnected from the target VM, address: '127.0.0.1:62799', transport: 'socket'

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 对象toString()之后转化成json对象 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • 微信小程序授权登录,跳转页面后在跳回首页不用再次登录

    小程序授权登录要使用wx getUserProfile 获得用户投头像后 做一些页面跳转功能 但是如果需要再次跳转首页的话 小程序就会有回到登录前的状态 这样体验感会很差 要想不用再次登录 也不难 只需要判断userInfo是否还存有信息就
  • 三种方式部署单机版Minio,10行命令干就完了~

    必要步骤 安装MinIO 拉取MinIO镜像 docker pull quay io minio minio 创建文件挂载点 mkdir home docker MinIO data 文件挂载点映射 默认是 mydata minio dat
  • JS中splice的详细用法介绍

    splice 是一个用于修改数组的方法 它可以实现添加 删除或替换数组中的元素 下面是 splice 方法的中文解释 splice 方法的语法如下 array splice start deleteCount item1 item2 参数说
  • 推荐系统学习总结

    前段时间参加了泰迪杯数据挖掘挑战赛 选的是B题电视产品营销推荐 由于涉及到推荐系统这一块比较大的知识领域 之前没有学过 于是在比赛之初找了一些网上的资料自学了几天 有了一些初步的了解与认识 因实训的项目中推荐系统仍是很重要的一部分 故重新再
  • win7下linux 双系统安装教程,【系统安装】双系统——Win7下安装linux系统详细步骤...

    preface html 1 在Win7下安装linux系统以前 若是以前安装过linux系统 可能会遇到须要从新安装的问题 linux 由于linux系统是安装在win7系统下的一个系统盘分区中 若是须要卸载linux直接把分区删除就能够
  • VLC使用教程(一):使用VLC录制屏幕

    1 打开VLC 选择媒体 gt 打开捕获设备 2 选择捕获设备 捕获模式选择桌面 捕获期望的帧率以及更多选项中的缓冲根据需求设置 3 点击播放按钮右侧的下拉三角 选择转换 4 点击目标文件右侧的浏览 选择文件放置路径 填写MP4文件的名字
  • nova6se可以升级鸿蒙吗,EMUI11支持哪些机型 华为EMUI11适配支持机型汇总

    华为最新的EMUI11公布了 不少的用户都想试试华为最新的这个EMUI11系统 下面就来为大家分享一下华为EMUI11适配支持机型汇总 1 首批支持EMUI11 更新的机型有 P40 系列 Mate30 系列 MatePad Pro系列等
  • 打印U盘文件计算机有记录吗,技术员教你win10系统查看打印机打印历史记录的问题...

    技术员教你win10系统查看打印机打印历史记录的问题 很多朋友安装win10系统后 在使用的过程中会遇到对win10系统查看打印机打印历史记录进行设置的情况 可能有很多用户还是不能自己对win10系统查看打印机打印历史记录进行设置吧 其实简
  • 添加购物车接口

    添加购物车接口 1 判断商品是否存在 是否上架 库存足够 2 判断商品之前是否已经在购物车里 3 返回的是当前用户的所有购物车物品信息 注意 测试 controller层 获取当前用户id下的购物车信息 1 判断商品是否存在 是否上架 库存
  • 华为OD机试真题- 字符串统计-2023年OD统一考试(B卷)

    题目描述 给定两个字符集合 一个为全量字符集 一个为已占用字符集 已占用的字符集中的字符不能再使用 要求输出剩余可用字符集 输入描述 1 输入为一个字符串 一定包含 符号 前的为全量字符集 后的字为已占用字符集 2 已占用字符集中的字符一定
  • MFC——获取当前字体的高度、宽度等信息

    当我们想往屏幕上面写多行内容时 我们需要之前当前文本的宽度和高度信息 我们可以采用以下方法 void CDialogView OnDraw CDC pDC CDialogDoc pDoc GetDocument ASSERT VALID p
  • JAVA String 常用方法(超详细)

    文章目录 一 常见String类的获取功能 1 length 获取字符串长度 2 charAt int index 获取指定索引位置的字符 3 indexOf int ch 返回指定字符在此字符串中第一次出现处的索引 数字是ASCII码中对
  • Android中保存图片到本地功能实现

    本文描述将一个Bitmap对象保存为一个图片文件的主要步骤 保存的图片文件能够立刻在系统相册和图库中找到 主要步骤 这里只介绍按下 保存 后如何将一个Bitmap对象保存为图片文件的执行步骤 对图片的下载 图片到Bitmap对象的转换 Bi
  • Unity如何获取鼠标当前帧和上一帧的屏幕坐标差

    在实际开发过程中 经常用到获取鼠标当前帧和上一帧的屏幕坐标差 今天我就简单写一个框架 希望对大家有所帮助 注意在计算两帧坐标时 一定要记得把第一帧去除 否则会出现跳动 给人以不连续感觉 FR 海涛高软 Hunk Xu QQ群 3864767
  • Java中的运行时异常

    Throwable 是所有 Java 程序中错误处理的父类 有两种子类 Error 和 Exception Error 表示由 JVM 所侦测到的无法预期的错误 由于这是属于 JVM 层次的严重错误 导致 JVM 无法继续执行 因此 这是不
  • 软件工程专业计算机毕设选题推荐

    同学们好 这里是海浪学长的毕设系列文章 对毕设有任何疑问都可以问学长哦 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难
  • 【MySQL数据库

    目录 编辑 前言 DML介绍 语法详情 1 插入数据 特点 1 给指定字段添加数据 代码示例 运行结果 2 给所有的字段添加数据 代码示例 运行结果 3 批量添加数据 代码示例1 运行结果1 代码示例2 运行结果2 2 修改数据 有条件的代
  • MyBatis传入参数为list、数组、map写法

    1 美图 如果传入的参数只是一个list
  • Kafka消费者之Offset、重复消费、消费者事务及消息积压

    一 offset 位移 1 1 offset 的默认维护位置 consumer offsets 主题里面采用 key 和 value 的方式存储数据 key 是 group id topic 分区号 value 就是当前 offset 的值
  • Java 对象toString()之后转化成json对象

    在平时的工作中经常遇到Java对象toString 之后打印出来 在发生线上问题时需要参数重新调用时 无法转化参数 如下图 TransOccupyRequestDTO newOrderId 390310807 transOccupyDeta