0
0

JSON処理

Posted at

JSON処理

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

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

public class Main {
    public static void main(String[] args) throws Exception {
        // JSON文字列の定義
        String jsonString = "{\n" +
                "\"apiVer1\":\"$$(TEST_NO1)\",\n" +
                "\"apiver2\":\"$$(TEST_NO2 HEAD:11)\",\n" +
                "\"norma\":\"testValue\",\n" +
                "\"apiver\":\"14\",\n" +
                "\"normal2\":\"testValue2\",\n" +
                "\"apiPerson\":{\n" +
                "\"apiVer3\":\"$$(TEST_NO3 HEAD:13)\",\n" +
                "\"kokyaku\":\"$$(kokyakuNo)\",\n" +
                "\"apiVer4\":\"$$(TEST_NO4 HEAD:24)\"\n" +
                "},\n" +
                "\"apiFunds\":{\n" +
                "\"apiVer5\":\"$$(TEST_NO5 HEAD:26)\",\n" +
                "\"apiVer6\":\"$$(TEST_NO6 ERA:yymmdd)\",\n" +
                "\"apiVer7\":\"$$(TEST_NO7 ERA:yymm)\",\n" +
                "\"apiVer8\":\"$$(TEST_NO8 IFNA:3/*)\",\n" +
                "\"apiVer9\":\"$$(TEST_NO9 IFNA:4/*)\",\n" +
                "\"apiVer10\":\"$$(TEST_NO10 IFNA:5/6)\",\n" +
                "\"apiVer11\":\"$$(TEST_NO11 IFNA:7/8)\"\n" +
                "}\n" +
                "}";

        // テストデータのマップを定義
        Map<String, String> bindDateMap = new HashMap<>();
        bindDateMap.put("TEST_NO1", "test1Value");
        bindDateMap.put("TEST_NO2", "123456789012345");
        bindDateMap.put("TEST_NO3", "123456789012345");
        bindDateMap.put("TEST_NO4", "123456789012345678901234567");
        bindDateMap.put("TEST_NO5", "123456789012345678901234567");
        bindDateMap.put("TEST_NO6", "19261224");
        bindDateMap.put("TEST_NO7", "192701");
        bindDateMap.put("TEST_NO8", "");  // 空文字を設定
        bindDateMap.put("TEST_NO9", "");
        bindDateMap.put("TEST_NO10", null);
        bindDateMap.put("TEST_NO11", "200");
        bindDateMap.put("kokyakuNo", "kokyakuNoValue");

        // JSON文字列からキーと対応する値のパターンを抽出
        Map<String, String> extractedKeyPatternMap = extractKeyPatterns(jsonString);
        // 最終的な結果を格納するマップの定義
        Map<String, Object> req = new HashMap<>();

        // 抽出したキーを使って値を加工し、結果マップに格納
        for (Map.Entry<String, String> entry : extractedKeyPatternMap.entrySet()) {
            String jsonKey = entry.getKey();  // JSONのキー
            String patternOrValue = entry.getValue();  // $$()内のパターンまたはそのままの値

            if (patternOrValue.startsWith("$$(")) {
                String pattern = patternOrValue.substring(3, patternOrValue.length() - 1); // $$()を取り除く
                String bindKey = pattern.split(" ")[0];  // パターンからテスト番号を取得
                String value = bindDateMap.get(bindKey);  // テストデータマップから値を取得
                if (value == null || value.isEmpty() || "0".equals(value)) { // 空文字チェックの追加
                    value = "";  // 値がnullまたは"0"の場合には空文字を格納
                }
                String processedValue = processValue(pattern, value);  // 値を加工
                req.put(jsonKey, processedValue);  // 結果をreqマップに追加
            } else {
                req.put(jsonKey, patternOrValue);  // 値をそのままreqマップに追加
            }
        }

        // 結果マップを出力
        for (Map.Entry<String, Object> entry : req.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    // JSON文字列からキーとパターンを抽出するメソッド
    public static Map<String, String> extractKeyPatterns(String jsonString) throws Exception {
        Map<String, String> keyPatternMap = new HashMap<>();
        // JSON文字列をパース
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(jsonString);

        // 再帰的にJSONノードを処理してキーとパターンを抽出
        extractPatternsRecursive(rootNode, "", keyPatternMap);

        return keyPatternMap;
    }

    // 再帰的にJSONノードを処理してキーとパターンを抽出するメソッド
    private static void extractPatternsRecursive(JsonNode node, String parentKey, Map<String, String> keyPatternMap) {
        if (node.isObject()) {
            // JSONオブジェクトの場合、各フィールドを処理
            Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                String currentKey = parentKey.isEmpty() ? field.getKey() : parentKey + "." + field.getKey();
                extractPatternsRecursive(field.getValue(), currentKey, keyPatternMap);
            }
        } else if (node.isTextual()) {
            // テキストノードの場合、パターンを抽出
            String text = node.asText();
            Pattern pattern = Pattern.compile("\\$\\$\\((.*?)\\)");
            Matcher matcher = pattern.matcher(text);
            if (matcher.find()) {
                keyPatternMap.put(parentKey, matcher.group(0));  // $$()のパターンを含めて取得
            } else {
                keyPatternMap.put(parentKey, text);  // パターンが見つからない場合はそのまま取得
            }
        }
    }

    // キーに基づいて値を加工するメソッド
    public static String processValue(String key, String value) throws ParseException {
        if (key.contains("HEAD:")) {
            // HEAD:の場合、指定された文字数だけ切り出す
            int headLength = Integer.parseInt(key.split("HEAD:")[1]);
            if (value.length() <= headLength) {
                return value;  // valueがheadLength以下の場合はそのまま返す
            }
            return value.substring(0, headLength);
        } else if (key.contains("ERA:yymmdd")) {
            // ERA:yymmddの場合、和暦に変換
            return convertToJapaneseEra(value, "yyyyMMdd");
        } else if (key.contains("ERA:yymm")) {
            // ERA:yymmの場合、和暦に変換
            return convertToJapaneseEra(value, "yyyyMM");
        } else if (key.contains("IFNA:") && key.contains("/*")) {
            // IFNA:x/*の場合、値が空またはnullならxに置き換え
            int replacementValue = Integer.parseInt(key.split("IFNA:")[1].split("/")[0]);
            return (value == null || value.isEmpty()) ? String.valueOf(replacementValue) : value;
        } else if (key.contains("IFNA:") && key.split("IFNA:")[1].contains("/")) {
            // IFNA:x/yの場合、値が空またはnullならxに置き換え、値が空でない場合にはyに置き換え
            String[] parts = key.split("IFNA:")[1].split("/");
            int nullValueReplacement = Integer.parseInt(parts[0]);
            int nonNullValueReplacement = Integer.parseInt(parts[1]);
            return (value == null || value.isEmpty()) ? String.valueOf(nullValueReplacement) : String.valueOf(nonNullValueReplacement);
        }

        return value;
    }

    // 西暦を和暦に変換するメソッド
    public static String convertToJapaneseEra(String date, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date westernDate = sdf.parse(date);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(westernDate);

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // Calendarの月は0から始まるため+1
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        String eraYear;

        if (format.equals("yyyyMMdd")) {
            if (year > 2019 || (year == 2019 && (month > 5 || (month == 5 && day >= 1)))) {
                // 令和 (2019年5月1日から)
                eraYear = String.format("%02d", year - 2018); // 年が1桁の場合に先頭に0を付ける
                return "5" + eraYear + String.format("%02d%02d", month, day);
            } else if (year > 1989 || (year == 1989 && (month > 1 || (month == 1 && day >= 8)))) {
                // 平成 (1989年1月8日から)
                eraYear = String.format("%02d", year - 1988); // 年が1桁の場合に先頭に0を付ける
                return "4" + eraYear + String.format("%02d%02d", month, day);
            } else if (year > 1926 || (year == 1926 && (month > 12 || (month == 12 && day >= 25)))) {
                // 昭和 (1926年12月25日から)
                eraYear = String.format("%02d", year - 1925); // 年が1桁の場合に先頭に0を付ける
                return "3" + eraYear + String.format("%02d%02d", month, day);
            } else if (year > 1912 || (year == 1912 && (month > 7 || (month == 7 && day >= 30)))) {
                // 大正 (1912年7月30日から)
                eraYear = String.format("%02d", year - 1911); // 年が1桁の場合に先頭に0を付ける
                return "2" + eraYear + String.format("%02d%02d", month, day);
            } else if (year > 1868 || (year == 1868 && (month > 1 || (month == 1 && day >= 25)))) {
                // 明治 (1868年1月25日から)
                eraYear = String.format("%02d", year - 1867); // 年が1桁の場合に先頭に0を付ける
                return "1" + eraYear + String.format("%02d%02d", month, day);
            } else {
                // 上記以外の場合、未("0")
                eraYear = "00"; // 年が1桁の場合に先頭に0を付ける
                return "0" + eraYear + String.format("%02d%02d", month, day);
            }
        } else if (format.equals("yyyyMM")) {
            if (year > 2019 || (year == 2019 && month >= 5)) {
                // 令和 (2019年5月から)
                eraYear = String.format("%02d", year - 2018); // 年が1桁の場合に先頭に0を付ける
                return "5" + eraYear + String.format("%02d", month);
            } else if ((year > 1989) || (year == 1989 && month >= 2) || (year == 2019 && month < 5)) {
                // 平成 (1989年2月から2019年4月まで)
                eraYear = String.format("%02d", year - 1988); // 年が1桁の場合に先頭に0を付ける
                return "4" + eraYear + String.format("%02d", month);
            } else if ((year > 1926) || (year == 1927 && month >= 1) || (year == 1989 && month < 2)) {
                // 昭和 (1927年1月から1989年1月まで)
                if (year == 1927 && month == 1) {
                    eraYear = String.format("%02d", year - 1926); // 年が1桁の場合に先頭に0を付ける
                } else {
                    eraYear = String.format("%02d", year - 1926 + 1); // 1927年1月は昭和1年1月とする
                }
                return "3" + eraYear + String.format("%02d", month);
            } else if ((year > 1912) || (year == 1912 && month >= 8) || (year == 1926 && month < 12)) {
                // 大正 (1912年8月から1926年12月まで)
                eraYear = String.format("%02d", year - 1911); // 年が1桁の場合に先頭に0を付ける
                return "2" + eraYear + String.format("%02d", month);
            } else if ((year > 1868) || (year == 1868 && month >= 2) || (year == 1912 && month < 8)) {
                // 明治 (1868年2月から1912年7月まで)
                eraYear = String.format("%02d", year - 1867); // 年が1桁の場合に先頭に0を付ける
                return "1" + eraYear + String.format("%02d", month);
            } else {
                // 上記以外の場合、未("0")
                eraYear = "00"; // 年が1桁の場合に先頭に0を付ける
                return "0" + eraYear + String.format("%02d", month);
            }
        }

        return date;
    }
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0