基于字符串生成json转换的类型

该代码示例展示了如何在Java中处理复杂的Json字符串,通过Fastjson库解析具有多层嵌套的参数化类型。方法`getTypes2`和`getTypes3`用于分析和构建Json类型,使用栈数据结构处理类型定义中的层次关系。同时,`main`方法演示了如何将解析后的类型应用于Json字符串解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Json类型分析

场景: 基于用户配置的字符串,生成json装换的类型

package com.soul.base.test;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.ParameterizedTypeImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class TypeAnalysisTest {

    public static void main(String[] args) throws Exception {

        getTypes2("A");
        System.out.println();
        getTypes2("A<B>");
        System.out.println();

        getTypes2("A<B,C>");
        System.out.println();
        getTypes2("A<B,C,D>");
        System.out.println();
        getTypes2("A<B<B1,B2>,C>");
        System.out.println();
        getTypes2("A<B,C<C1,C2>>");
        System.out.println();

        getTypes2("A<B<B1,B2,B3>>");
        System.out.println();
        getTypes2("A<B,C<C1,C2,C3>>");
        System.out.println();
        getTypes2("A<B<B1,B2,B3>,C>");
        System.out.println();

        getTypes2("A<B,C<C1<C2<C3>>>,D<D1<D2<D3>>>>");
        System.out.println();
        getTypes2("A<B,C<C1,C2,C3>,D<D1<D2<D3>>>>");
        System.out.println();
        getTypes2("A<B<B1,B2,B3>,C<C1,C2,C3>,D<D1<D2<D3>>>>");
        System.out.println();
        getTypes2("A<B<B1,B2,B3>,C<C1<C2<C3>>>,D<D1<D2<D3>>>>");
        System.out.println();
        getTypes2("A<B<B1<B2<B3>>>,C<C1<C2<C3>>>,D<D1<D2<D3>>>>");
        System.out.println();
        getTypes2("A<B<B1<B2<B3>>>,C<C1<C2<C3>,C2<C3>>>,D<D1<D2<D3>>>>");
        System.out.println();
        getTypes2("A<B<B1<B2<B3>>>,C,D>");
        System.out.println();


        String responseStr = "{\"A\":{\"A1\":[\"A2\",\"A3\",\"A4\"]},\"B\":{\"B1\":null},\"C\":null}";
        String types = "java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.util.List<java.lang.String>>>";
        ParameterizedTypeImpl types3 = getTypes3(types);
        Map<String,Map<String,List<String>>> map = JSONObject.parseObject(responseStr, types3);
        System.out.println(map.get("A"));
        System.out.println(map.get("A").get("A1").get(0));
        System.out.println(map.get("B"));
        System.out.println(map.get("C"));

    }

    public static LinkedList<String> init(String className) {
        LinkedList<String> levelList = new LinkedList<>();
        levelList.add(className);
        return levelList;
    }

    public static void getTypes2(String types) {

        //截取类型的开始下标
        int startIndex = 0;
        //截取类型的结束下标
        int endIndex;
        //上一次遇到的操作符号
        char lastSymbol = '<';

        Stack<List<String>> clazzStack = new Stack<>();
        if (!types.contains("<")){
            clazzStack.push(init(types));
        }

        types = types.replaceAll("\\s+", "");
        for (int i = 0; i < types.length(); i++) {
            endIndex = i;
            char charAt = types.charAt(i);
            // 注意: 每一次处理的是操作符号左边的数据
            if (charAt == '<') {
                // <开始符号, 压入元素
                if (lastSymbol == '<'){
                    //<左侧为新层级且仅有一个元素,新建层并压入
                    clazzStack.push(init(types.substring(startIndex, endIndex)));
                } else if (lastSymbol == ',') {
                    //<左侧为,的同层级,取历史层级压入
                    List<String> preLevelList = clazzStack.pop();
                    preLevelList.add(types.substring(startIndex, endIndex));
                    clazzStack.push(preLevelList);
                } else if (lastSymbol == '>') {
                    //不存在 > < 中间没有,情况
                    //clazzStack.push(init(types.substring(startIndex, endIndex)));
                    System.out.println("unknown case > xxx <");
                }
                startIndex = endIndex + 1;
                lastSymbol = '<';
            } else if (charAt == ',') {
                // ,同层级符号, 压入元素
                if (lastSymbol == '<'){
                    //,左侧为新层级的第一个元素(,表示必定有多个元素),新建层并压入
                    clazzStack.push(init(types.substring(startIndex, endIndex)));
                } else if (lastSymbol == ',') {
                    //,左侧为历史同层级的第N个元素,取历史层级压入
                    List<String> preLevelList = clazzStack.pop();
                    preLevelList.add(types.substring(startIndex, endIndex));
                    clazzStack.push(preLevelList);
                } else if (lastSymbol == '>') {
                    // >, 必然连在一起, 直接跳过这个,开始下标修改即可
                }
                startIndex = endIndex + 1;
                lastSymbol = ',';
            } else if (charAt == '>') {
                // > 结束符号, 进行业务逻辑处理
                if (lastSymbol == '<'){
                    // <>表示当前层级仅一个元素
                    //业务处理, 当前层仅一个元素
                    String curLevelSingleName = '<' + types.substring(startIndex, endIndex) + '>';
                    List<String> preLevelList = clazzStack.pop();
                    //业务处理, 加入到父元素
                    String lastClassName = preLevelList.get(preLevelList.size() - 1) + curLevelSingleName;
                    preLevelList.remove(preLevelList.size() - 1);
                    preLevelList.add(lastClassName);
                    clazzStack.push(preLevelList);
                } else if (lastSymbol == ',') {
                    // ,>表示当前层级有多个元素并结束,获取当前层最后一个元素后,拼接后加到前父元素
                    String preName = types.substring(startIndex, endIndex);
                    List<String> preLevelList = clazzStack.pop();
                    preLevelList.add(preName);
                    //业务处理, 整个层级拼接
                    String preNameList = '<' + StringUtils.join(preLevelList,",") + '>';
                    //业务处理, 再向上交给这层父节点处理
                    List<String> pre2LevelList = clazzStack.pop();
                    String lastClassName = pre2LevelList.get(pre2LevelList.size() - 1) + preNameList;
                    pre2LevelList.remove(pre2LevelList.size() - 1);
                    pre2LevelList.add(lastClassName);
                    clazzStack.push(pre2LevelList);
                } else if (lastSymbol == '>') {
                    // >>表示当前层无元素,且上一层级结束(>>必然连接在一起, 不需要向前截取)
                    List<String> preLevelList = clazzStack.pop();
                    //业务处理, 整个层级拼接
                    String preNameList = '<' + StringUtils.join(preLevelList,",") + '>';
                    //业务处理, 再向上交给这层父节点处理
                    List<String> pre2LevelList = clazzStack.pop();
                    String lastClassName = pre2LevelList.get(pre2LevelList.size() - 1) + preNameList;
                    pre2LevelList.remove(pre2LevelList.size() - 1);
                    pre2LevelList.add(lastClassName);
                    clazzStack.push(pre2LevelList);
                }
                startIndex = endIndex + 1;
                lastSymbol = '>';
            }

        }
        System.out.println(clazzStack.pop().get(0));
        System.out.println(types);

    }

    public static ParameterizedTypeImpl getTypes3(String types) throws Exception {

        //截取类型的开始下标
        int startIndex = 0;
        //截取类型的结束下标
        int endIndex;
        //上一次遇到的操作符号
        char lastSymbol = '<';

        Stack<List<TypeNode>> clazzStack = new Stack<>();
        if (!types.contains("<")){
            clazzStack.push(initNode(types));
        }

        types = types.replaceAll("\\s+", "");
        for (int i = 0; i < types.length(); i++) {
            endIndex = i;
            char charAt = types.charAt(i);
            // 注意: 每一次处理的是操作符号左边的数据
            if (charAt == '<') {
                // <开始符号, 压入元素
                if (lastSymbol == '<'){
                    //<左侧为新层级且仅有一个元素,新建层并压入
                    clazzStack.push(initNode(types.substring(startIndex, endIndex)));
                } else if (lastSymbol == ',') {
                    //<左侧为,的同层级,取历史层级压入
                    List<TypeNode> preLevelList = clazzStack.pop();
                    preLevelList.add(new TypeNode(types.substring(startIndex, endIndex)));
                    clazzStack.push(preLevelList);
                } else if (lastSymbol == '>') {
                    //不存在 > < 中间没有,情况
                    //clazzStack.push(init(types.substring(startIndex, endIndex)));
                    System.out.println("unknown case > xxx <");
                }
                startIndex = endIndex + 1;
                lastSymbol = '<';
            } else if (charAt == ',') {
                // ,同层级符号, 压入元素
                if (lastSymbol == '<'){
                    //,左侧为新层级的第一个元素(,表示必定有多个元素),新建层并压入
                    clazzStack.push(initNode(types.substring(startIndex, endIndex)));
                } else if (lastSymbol == ',') {
                    //,左侧为历史同层级的第N个元素,取历史层级压入
                    List<TypeNode> preLevelList = clazzStack.pop();
                    preLevelList.add(new TypeNode(types.substring(startIndex, endIndex)));
                    clazzStack.push(preLevelList);
                } else if (lastSymbol == '>') {
                    // >, 必然连在一起, 直接跳过这个,开始下标修改即可
                }
                startIndex = endIndex + 1;
                lastSymbol = ',';
            } else if (charAt == '>') {
                // > 结束符号, 进行业务逻辑处理
                if (lastSymbol == '<'){
                    // <>表示当前层级仅一个元素
                    List<TypeNode> curLevelList = initNode(types.substring(startIndex, endIndex));

                    //业务处理, 当前层与上1层拼接
                    dealCurAndPreNode(clazzStack, curLevelList);
                }else if (lastSymbol == ',') {
                    // ,>表示当前层级有多个元素并结束,获取当前层最后一个元素后,拼接后加到前父元素
                    String preName = types.substring(startIndex, endIndex);
                    List<TypeNode> preLevelList = clazzStack.pop();
                    preLevelList.add(new TypeNode(preName));

                    //业务处理, 上1层与上2层拼接
                    dealCurAndPreNode(clazzStack, preLevelList);
                }else if (lastSymbol == '>') {
                    // >>表示当前层无元素,且上一层级结束(>>必然连接在一起, 不需要向前截取)
                    List<TypeNode> preLevelList = clazzStack.pop();

                    //业务处理, 上1层与上2层拼接
                    dealCurAndPreNode(clazzStack, preLevelList);
                }
                startIndex = endIndex + 1;
                lastSymbol = '>';
            }

        }
        return clazzStack.pop().get(0).type;
    }

    public static void dealCurAndPreNode(Stack<List<TypeNode>> clazzStack, List<TypeNode> curLevelList) throws ClassNotFoundException {
        //业务处理, 当前层仅一个元素
        List<Type> clazzList = curLevelList.stream().map(node -> {
            try {
                if (null != node.type) {
                    return node.type;
                }
                return Class.forName(node.name);
            } catch (ClassNotFoundException e) {
                log.error("类找不到,配置异常,clazz:{}", node.name, e);
            }
            return null;
        }).collect(Collectors.toList());

        //业务处理, 加入到父元素
        List<TypeNode> preLevelList = clazzStack.pop();
        TypeNode pre2Node = preLevelList.get(preLevelList.size() - 1);
        pre2Node.type = new ParameterizedTypeImpl(clazzList.toArray(new Type[]{}), null, Class.forName(pre2Node.name));
        clazzStack.push(preLevelList);
    }

    static class TypeNode {
        public String name;
        public ParameterizedTypeImpl type;

        public TypeNode() {
        }

        public TypeNode(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "TypeNode{" +
                    "name='" + name + '\'' +
                    ", type=" + type +
                    '}';
        }
    }

    public static LinkedList<TypeNode> initNode(String className) {
        LinkedList<TypeNode> levelList = new LinkedList<>();
        levelList.add(new TypeNode(className));
        return levelList;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值