代码之家  ›  专栏  ›  技术社区  ›  gil.fernandes

从Java类生成JSON示例

  •  4
  • gil.fernandes  · 技术社区  · 6 年前

    如何使用Java类定义中的伪数据生成JSON示例?(注意:我不是在问如何从POJO生成JSON。这是之前在stackoverflow上问过的问题)。

    我想要的是直接从Java类生成一些示例虚拟数据。例如,你有这样一个类:

    public class Reservation  {
    
      @ApiModelProperty(value = "")
      private Traveller leadTraveller = null;
    
      @ApiModelProperty(example = "2", value = "")
      private Integer sourceSystemID = null;
    
      @ApiModelProperty(value = "")
      private String recordLocation = null;
    
      @ApiModelProperty(example = "2010", value = "")
      private Integer recordLocatorYear = null;
    
    }
    

    然后你有一个函数,它不需要创建POJO就可以生成一个JSON字符串,其中包含伪值,比如:

    {
        "leadTraveller": {
            "firstNames": "firstNames",
            "lastName": "lastName",
            "email": "email",
            "travellerGUID": "travellerGUID",
            "travellerRefs": [{
                "customerReportingRank": 37,
                "value": "value",
                "description": "description"
            }]
        },
        "sourceSystemID": 38,
        "recordLocation": "recordLocation",
        "recordLocatorYear": 9
    }
    

    是否有默认情况下可以执行此操作的库?

    我曾尝试使用Java代码和以下Maven依赖项来解决这个问题:

    <dependency>
        <groupId>fctg-ngrp</groupId>
        <artifactId>model-core</artifactId>
        <version>1.0.4-SNAPSHOT-MODEL-CORE</version>
    </dependency>
    <dependency>
        <groupId>io.vavr</groupId>
        <artifactId>vavr</artifactId>
        <version>0.9.2</version>
        <scope>test</scope>
    </dependency>
    

    Jackson主要用于验证和格式化输出JSON。

    下面是我使用的Java代码:

    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.io.Files;
    import io.vavr.API;
    import io.vavr.collection.Array;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.lang.reflect.Field;
    import java.lang.reflect.ParameterizedType;
    import java.math.BigDecimal;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.OffsetDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.*;
    import java.util.stream.Collectors;
    
    /**
     * Sample utility for generating dummy JSON sample code from a JAva class directly.
     */
    public class GenerateJSONFromClasses {
    
        private static final Random R = new Random();
    
        /**
         * Used to avoid infinite loops.
         */
        private static final Map<Class<?>, Integer> visited = new HashMap<>();
    
        private static final ObjectMapper mapper = new ObjectMapper();
    
        public static void main(String[] args) throws IOException {
            Class<Reservation> clazz = Reservation.class;
            generateDummyJSON(clazz, args);
        }
    
        public static void generateDummyJSON(Class<Reservation> clazz, String... paths) throws IOException {
            StringWriter out = new StringWriter();
            try (PrintWriter writer = new PrintWriter(out)) {
                writer.println(printObj(clazz));
                JsonNode jsonNode = mapper.readTree(out.toString());
                String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
                if (paths == null || paths.length == 0) {
                    System.out.println(prettyJson);
                } else {
                    Array.of(paths).map(sPath -> Paths.get(sPath))
                            .map(Path::toFile)
                            .map(API.unchecked(file -> {
                                Files.write(prettyJson, file, StandardCharsets.UTF_8);
                                return file;
                            }));
                }
            }
        }
    
        private static String printObj(Class<?> clazz) {
            if (!visited.containsKey(clazz) || visited.get(clazz) <= 1) {
                visited.merge(clazz, 1, (integer, integer2) -> integer + integer2);
                Field[] declaredFields = clazz.getDeclaredFields();
                return "{" +
                        Array.of(declaredFields).map(field -> String.format("  \"%s\" : %s%n", field.getName(), printFieldValue(field)))
                                .collect(Collectors.joining(String.format(",%n"))) +
                        "}";
            }
            return "";
        }
    
        private static Object printFieldValue(Field field) {
            Class<?> fieldType = field.getType();
            if (String.class.equals(fieldType)) {
                return String.format("\"%s\"", field.getName());
            } else if (Integer.class.equals(fieldType)) {
                return R.nextInt(99) + 1;
            } else if (LocalDate.class.equals(fieldType)) {
                return String.format("\"%s\"", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            } else if (LocalDateTime.class.equals(fieldType)) {
                return String.format("\"%s\"", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")));
            } else if (OffsetDateTime.class.equals(fieldType)) {
                return String.format("\"%s\"", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")));
            } else if (Date.class.equals(fieldType)) {
                return System.currentTimeMillis();
            } else if (List.class.equals(fieldType)) {
                ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
                Class<?> clazz = (Class<?>) parameterizedType.getActualTypeArguments()[0];
                return String.format("[%s]", printObj(clazz));
            } else if (fieldType.isAssignableFrom(Number.class)) {
                return R.nextDouble() * 10.0;
            } else if (BigDecimal.class.equals(fieldType)) {
                return new BigDecimal(R.nextDouble() * 10.0);
            } else if (Boolean.class.equals(fieldType)) {
                return R.nextBoolean();
            } else {
                return printObj(fieldType);
            }
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   zdary    5 年前

    谢谢@gil。费尔南德斯, 我对你的代码做了一些小的修改。

    1) 允许同一类型多次访问,但将访问次数保持在100,以防止无限循环。我以为你的用例不一样。

    2) 添加了java。util。日期和枚举。

    3) 打印伪值作为类的简单名称。对于enum,打印“字符串”及其值列表。

        import com.fasterxml.jackson.databind.JsonNode;
        import com.fasterxml.jackson.databind.ObjectMapper;
        import com.google.common.io.Files;
        import com.jnj.na.webmethods.core.dto.MaterialWsDTO;
        import io.vavr.API;
        import io.vavr.collection.Array;
    
        import java.io.IOException;
        import java.io.PrintWriter;
        import java.io.StringWriter;
        import java.lang.reflect.Field;
        import java.lang.reflect.Modifier;
        import java.lang.reflect.ParameterizedType;
        import java.math.BigDecimal;
        import java.nio.charset.StandardCharsets;
        import java.nio.file.Path;
        import java.nio.file.Paths;
        import java.time.LocalDate;
        import java.time.LocalDateTime;
        import java.time.OffsetDateTime;
        import java.util.*;
        import java.util.stream.Collectors;
    
        /**
         * Sample utility for generating dummy JSON sample code from a JAva class directly.
         */
        public class GenerateJSONFromClasses {
    
            /**
             * Used to avoid infinite loops.
             */
            private static final Map<Class<?>, Integer> visited = new HashMap<>();
    
            private static final ObjectMapper mapper = new ObjectMapper();
    
            public static void main(String[] args) throws IOException {
                Class<MaterialWsDTO> clazz = MaterialWsDTO.class;
                generateDummyJSON(clazz, args);
            }
    
            public static void generateDummyJSON(Class<MaterialWsDTO> clazz, String... paths) throws IOException {
                StringWriter out = new StringWriter();
                try (PrintWriter writer = new PrintWriter(out)) {
                    writer.println(printObj(clazz));
                    JsonNode jsonNode = mapper.readTree(out.toString());
                    String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
                    if (paths == null || paths.length == 0) {
                        System.out.println(prettyJson);
                    } else {
                        Array.of(paths).map(sPath -> Paths.get(sPath))
                                .map(Path::toFile)
                                .map(API.unchecked(file -> {
                                    Files.write(prettyJson, file, StandardCharsets.UTF_8);
                                    return file;
                                }));
                    }
                }
            }
    
            private static String printObj(Class<?> clazz) {
                if (!visited.containsKey(clazz) || visited.get(clazz) <= 100) {
                    visited.merge(clazz, 1, (integer, integer2) -> integer + integer2);
                    Field[] declaredFields = clazz.getDeclaredFields();
                    return "{" +
                            Array.of(declaredFields)
                                    .filterNot(e->Modifier.isStatic(e.getModifiers()))
                                    .map(field -> String.format("  \"%s\" : %s%n", field.getName(), printFieldValue(field)))
                                    .collect(Collectors.joining(String.format(",%n"))) +
                            "}";
                }
                return "";
            }
    
            private static Object printFieldValue(Field field) {
                Class<?> fieldType = field.getType();
                if (String.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (Integer.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (Enum.class.isAssignableFrom(fieldType)) {
                    return printEnum(fieldType);
                } else if (Double.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (LocalDate.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (LocalDateTime.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (OffsetDateTime.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (Date.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (List.class.equals(fieldType)) {
                    ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
                    Class<?> clazz = (Class<?>) parameterizedType.getActualTypeArguments()[0];
                    return String.format("[%s]", printObj(clazz));
                } else if (fieldType.isAssignableFrom(Number.class)) {
                    return name(fieldType);
                } else if (BigDecimal.class.equals(fieldType)) {
                    return name(fieldType);
                } else if (Boolean.class.equals(fieldType)) {
                    return name(fieldType);
                } else {
                    return printObj(fieldType);
                }
            }
    
            private static String printEnum(Class<?> fieldType) {
                Field[] declaredFields = fieldType.getDeclaredFields();
                return "\"String of " + Arrays.stream(declaredFields)
                        .filter(field -> field.getType()==fieldType)
                        .map(Field::getName)
                        .collect(Collectors.joining(",")) +
                       "\"";
            }
    
            private static Object name(Class<?> fieldType) {
                return "\""+fieldType.getSimpleName()+"\"";
            }
        }
    
        2
  •  -1
  •   Willian Yamashita    6 年前

    您可以尝试以下代码: 这将使用 gson lib将对象转换为json字符串

    public static <T> String convertObjectToJSONString(Object obj) {
        Gson gson = new GsonBuilder().serializeNulls().create();
        if (obj == null) {         
            return null;
        }
        return gson.toJson(obj);
    }