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


    在平时的工作中经常遇到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 

    1. import com.alibaba.fastjson.JSON;
    2. import javafx.util.Pair;
    3. import org.apache.commons.lang.StringUtils;
    4. import java.text.ParseException;
    5. import java.text.SimpleDateFormat;
    6. import java.util.*;
    7. import java.util.regex.Pattern;
    8. public class ToStringUtils {
    9. /**
    10. * toString格式反序列化
    11. */
    12. /**
    13. * 数字类型匹配(包括整形和浮点型) & 日期类型匹配 & 对象类型匹配 & ...
    14. */
    15. 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})$");
    16. public static Pattern numPattern = Pattern.compile("^-?[0-9]+\\.?[0-9]*$");
    17. public static Pattern objectPattern = Pattern.compile("^[a-zA-Z0-9\\.]+\\(.+\\)$");
    18. public static Pattern listPattern = Pattern.compile("^\\[.*\\]$");
    19. public static Pattern mapPattern = Pattern.compile("^\\{.*\\}$");
    20. public static Pattern supperPattern = Pattern.compile("^super=[a-zA-Z0-9\\.]+\\(.+\\)$");
    21. public static final String NULL = "null";
    22. /**
    23. * toString -> json
    24. */
    25. public static String toJSONString(String toString) throws ParseException {
    26. return JSON.toJSONString(toMap(toString));
    27. }
    28. /**
    29. * toString -> object
    30. */
    31. public static <T> T toObject(String toString, Class<T> clazz) throws ParseException {
    32. return JSON.parseObject(toJSONString(toString), clazz);
    33. }
    34. /**
    35. * toString -> map
    36. */
    37. private static Map<String, Object> toMap(String toString) throws ParseException {
    38. if (StringUtils.isEmpty(toString = StringUtils.trim(toString))) {
    39. return toString == null ? null : new HashMap<>();
    40. }
    41. // 移除最外层"()"
    42. toString = StringUtils.substringAfter(toString, "(").trim();
    43. toString = StringUtils.substringBeforeLast(toString, ")").trim();
    44. String token;
    45. Map<String, Object> map = new HashMap<>();
    46. while (StringUtils.isNotEmpty(toString) && StringUtils.isNotEmpty(token =splitToken(toString))) {
    47. toString = StringUtils.removeStart(StringUtils.removeStart(toString, token).trim(), ",").trim();
    48. // 如果带"super="(lombok的@ToString(callSuper=true)引入),按照当前层继续处理
    49. if (supperPattern.matcher(token).matches()) {
    50. token = token.substring(token.indexOf("(") + 1, token.length() - 1);
    51. toString = String.format("%s,%s", token, toString);
    52. continue;
    53. }
    54. Pair<String, String> keyValue = parseToken(token);
    55. map.put(keyValue.getKey(), buildTypeValue(keyValue.getKey(), keyValue.getValue()));
    56. }
    57. return map;
    58. }
    59. static Pair<String, String> parseToken(String token) {
    60. assert Objects.nonNull(token) && token.contains("=");
    61. int pos = token.indexOf("=");
    62. return new javafx.util.Pair<>(token.substring(0, pos), token.substring(pos + 1));
    63. }
    64. /**
    65. * 单个token解析
    66. *
    67. * @param key 可根据key设置自定义序列化操作
    68. */
    69. private static Object buildTypeValue(String key, String value) throws ParseException {
    70. if (StringUtils.isEmpty(value)) {
    71. return null;
    72. } else if (value.equals(NULL)) {
    73. return null;
    74. }
    75. // 日期类型
    76. if (datePattern.matcher(value).matches()) {
    77. return new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", new Locale("us")).parse(value).getTime();
    78. }
    79. // 数字类型
    80. if (numPattern.matcher(value).matches()) {
    81. return value;
    82. }
    83. // 集合类型
    84. if (listPattern.matcher(value).matches()) {
    85. return buildListValue(value);
    86. }
    87. // map类型
    88. if (mapPattern.matcher(value).matches()) {
    89. return buildMapValue(value);
    90. }
    91. // 对象类型
    92. if (objectPattern.matcher(value).matches()) {
    93. return toMap(value);
    94. }
    95. // 其他都认为是string类型
    96. return value;
    97. }
    98. /**
    99. * 集合类型
    100. */
    101. private static Object buildListValue(String value) throws ParseException {
    102. List<Object> result = new ArrayList<>();
    103. value = value.substring(1, value.length() - 1).trim();
    104. if (StringUtils.isEmpty(value)) {
    105. return result;
    106. }
    107. String token = null;
    108. while (StringUtils.isNotBlank(value) && StringUtils.isNotBlank(token = splitToken(value))) {
    109. result.add(buildTypeValue(null, token));
    110. value = StringUtils.removeStart(StringUtils.removeStart(value, token).trim(), ",").trim();
    111. }
    112. return result;
    113. }
    114. static String splitToken(String toString) {
    115. if (StringUtils.isBlank(toString)) {
    116. return toString;
    117. }
    118. int bracketNum = 0;
    119. Stack<Character> stack = new Stack<>();
    120. for (int i = 0; i < toString.length(); i++) {
    121. Character c = toString.charAt(i);
    122. if (tokenMap.containsValue(c)) {
    123. stack.push(c);
    124. } else if (tokenMap.containsKey(c) && Objects.equals(stack.peek(), tokenMap.get(c))) {
    125. stack.pop();
    126. } else if ((c == ',') && stack.isEmpty()) {
    127. return toString.substring(0, i);
    128. }
    129. }
    130. if (stack.isEmpty()) {
    131. return toString;
    132. }
    133. throw new RuntimeException("splitFirstToken error, bracketNum=" + bracketNum + ", toString=" + toString);
    134. }
    135. /**
    136. * 获取第一个token,注意: toString不再包括最外层的()
    137. */
    138. private final static Map<Character, Character> tokenMap = new HashMap<>();
    139. static {
    140. tokenMap.put(')', '(');
    141. tokenMap.put('}', '{');
    142. tokenMap.put(']', '[');
    143. }
    144. /**
    145. * map类型
    146. */
    147. private static Map<Object, Object> buildMapValue(String value) throws ParseException {
    148. Map<Object, Object> result = new HashMap<>();
    149. value = value.substring(1, value.length() - 1).trim();
    150. if (StringUtils.isEmpty(value)) {
    151. return result;
    152. }
    153. String token = null;
    154. while (StringUtils.isNotEmpty(token =splitToken(value))) {
    155. Pair<String, String> keyValue =parseToken(token);
    156. result.put(buildTypeValue(keyValue.getKey(), keyValue.getKey()), buildTypeValue(keyValue.getKey(), keyValue.getValue()));
    157. value = StringUtils.removeStart(StringUtils.removeStart(value, token).trim(), ",").trim();
    158. }
    159. return result;
    160. }
    161. }

    最终测试结果

    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'

  • 相关阅读:
    企业应用选择租用云服务器还是租用物理服务器
    C++并发与多线程学习笔记--线程启动、结束,创建线程多法
    JVM及其垃圾回收机制(GC)
    类加载器及反射简单笔记
    Jmeter 使用BeanShell断言,实现自动获取文章列表,并判断文章是否为当天发布的
    【MySQL】深入理解MySQL分区表原理与企业级实战(MySQL专栏启动)
    配置windows限时登录
    Bootstrap的一些主要作用
    0成本低代码入门指南,国产化+私有化的开源低代码平台如何获取?
    Linux关闭进程
  • 原文地址:https://blog.csdn.net/mclongyi/article/details/125510789