JSON関係の仕様書を作成するため、クラス定義からJSONの文字列を出力するプログラムを作成した。
Mapには未対応のため、ご注意ください。
import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.math.BigDecimal; import java.sql.Timestamp; import java.util.Date; import java.util.List; import java.util.stream.IntStream; public class PrintJson { /** インデント用文字 */ private static final String INDENT = " "; /** JSONに出力する型で定義 */ static XXXXX dto; public static void main(String[] args) { try { System.out.println(getJson(PrintJson.class.getDeclaredField("dto"), 1, null)); } catch (NoSuchFieldException | SecurityException e) { e.printStackTrace(); } } /** * @param inputField * JSON出力用のField(ジェネリック対応のため、Classではなく、Field) * @param level * インデント用のレベル * @param parentField * Fieldの親Field(ジェネリックの型判定用) * @return Fieldに該当するJSON */ private static String getJson(Field inputField, int level, Field parentField) { StringBuilder sb = new StringBuilder(); Class<?> inputFieldType = inputField.getType(); Class<?> clazz = inputFieldType; if (inputFieldType.isArray() || isIterable(inputFieldType)) { sb.append("["); if (inputFieldType.isArray()) { clazz = inputFieldType.getComponentType(); } else { Type type = inputField.getGenericType(); if (type instanceof ParameterizedType) { Type actualType = ((ParameterizedType) type).getActualTypeArguments()[0]; if (actualType instanceof Class) { clazz = (Class<?>) actualType; } else { clazz = (Class<?>) ((ParameterizedType) parentField.getGenericType()) .getActualTypeArguments()[0]; } } } } if (clazz.isPrimitive() || (Integer.class == clazz) || (Double.class == clazz) || (Date.class == clazz) || (Timestamp.class == clazz) || (Long.class == clazz) || (BigDecimal.class == clazz) || (String.class == clazz)) { sb.append("\"\""); } else { sb.append("{").append("\n"); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { sb.append(getIndent(level)).append("\"").append(field.getName()).append("\":"); sb.append(getJson(field, level + 1, inputField)).append(",\n"); } if (fields.length > 0) { // 最後の「,」を削除 sb.delete(sb.length() - 2, sb.length() - 1); } sb.append(getIndent(level - 1)).append("}"); } if (inputFieldType.isArray() || isIterable(inputFieldType)) { sb.append("]"); } return sb.toString(); } /** * @param level * @return level分のインデント用のスペース */ private static String getIndent(int level) { StringBuilder sb = new StringBuilder(); IntStream.range(0, level).forEach(i -> sb.append(INDENT)); return sb.toString(); } /** * @param clazz * @return clazzがIterableかどうか */ private static boolean isIterable(Class<?> clazz) { if (clazz == Iterable.class) { return true; } else { for (Class<?> clazz1 : clazz.getInterfaces()) { if (isIterable(clazz1)) { return true; } } } return false; } }