Chapter 38

utilsクラス

kazpgm
kazpgm
2022.01.13に更新

自動作成されたutilsクラスを説明する。

AppProperties.java

utils.AppProperties.java

・当クラスにより、application.propertiesの値を参照できる。

package com.kaz01u.demo.utils;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;

・@Data:対象クラス内のインスタンス変数に対してgetter/setterでアクセスすることを可能とする。

@Data

・@Component:当クラスをSpringのDIコンテナにbeanとして登録するため使う。

@Component

・@ConfigurationProperties:application.propertiesの"app.xxxxxxxx"の設定値がインジェクションされる。★01

@ConfigurationProperties(prefix="app")
public class AppProperties {

    // application.propertiesの"app.xxxxxxxx"の設定値がインジェクションされる
    /**
     * UPLOADディレクトリ(画像などアップロード先)
     */
    private String dirUpload;

    /**
     * メールのfromを指定
     */
    public String mailFrom;

    /**
     * メールのtoを指定
     */
    public String mailTo;

}

CsvUtils.java

utils.CsvUtils.java
・当クラスにより、画面からの、CSVファイルを読み込んで、CsvMapperクラスでパーズし、テーブル登録用データリスト作成します。
・ShohinControllerクラスのshohinUpCsvDoメソッドで使用しています。
・readUtf8メソッドは読み込みCSVファイルが、UTF-8文字コードを対象にしています。参考にため作成しましたが、当システムでは未使用です。
・readSjisメソッドは読み込みCSVファイルが、SJIS文字コードを対象にしています。

package com.kaz01u.demo.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;

public class CsvUtils {
    
    /**
     * 画面からの、CSVファイル(UTF-8文字コード)読み込み
     * 画面から、CSVファイル(UTF-8文字コード)を
     * 読み込んでテーブル登録用データリスト作成する。
     * 
     * @param clazz テーブル登録用データ
     * @param stream CSVファイル読み込みstream
     * @return テーブル登録用データリスト
     * @throws IOException
     */
    public static <T> List<T> readUtf8(Class<T> clazz, InputStream stream) throws IOException {
        CsvMapper mapper = new CsvMapper(); 
        CsvSchema schema = mapper.schemaFor(clazz).withHeader().withColumnReordering(true);
        ObjectReader reader = mapper.readerFor(clazz).with(schema);
        return reader.<T>readValues(stream).readAll();
    }
    
    /**
     * 画面からの、CSVファイル(SJIS文字コード)読み込み
     * 画面から、CSVファイル(SJIS文字コード)を
     * 読み込んでテーブル登録用データリスト作成する。
     * 
     * @param clazz テーブル登録用データ
     * @param stream CSVファイル読み込みstream
     * @return テーブル登録用データリスト
     * @throws IOException
     */
    public static <T> List<T> readSjis(Class<T> clazz, InputStream stream) throws IOException {
        StringBuilder lines = new StringBuilder(); 
        String lineSeparator = System.getProperty("line.separator"); 
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "Shift-JIS"))) { 
            for (String r = reader.readLine(); r != null; r = reader.readLine()) { 
                lines.append(r).append(lineSeparator); 
            } 
        }
        CsvMapper mapper = new CsvMapper(); 
        CsvSchema schema = mapper 
          .schemaFor(clazz) 
          .withHeader().withColumnReordering(true); 
        ObjectReader reader = mapper.readerFor(clazz).with(schema);
        MappingIterator<T> out = reader.readValues(lines.toString()); 
        return out.readAll();
    }

}

Elements.java

utils.Elements.java

・当クラスは「コード一覧表」シートの固定値エレメントから自動作成されます。
・エレメントは、Collections.unmodifiableMapにより書き換えられないようにしています。
・「コード一覧表」シートに記述がないけど、削除区分、、可否フラグ、ソート順、「年」のプルダウン、「月」のプルダウン、「日」のプルダウンは自動作成されます。

package com.kaz01u.demo.utils;

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

public class Elements {
    /**
     * 削除区分
     */
    public static final String DELKBN = "1";

    /**
     * エレメント
     * このエレメントは、Collections.unmodifiableMapにより書き換えられないようにしている。
     * 補足:DBから作成する大中小分類エレメントは、動的に作成するので、ここには書かない。
     * 
     */
    public static final Map<String, Map<Object, String>> ELEMENTS = 
                (Map<String, Map<Object, String>>) Collections.unmodifiableMap(
                    new LinkedHashMap<String, Map<Object, String>>() {
        private static final long serialVersionUID = 1L;
        {
        // 可否フラグ
        put("ENABLE_FLG", (Map<Object, String>) Collections.unmodifiableMap(
               new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("true", "有効");
                put("false", "無効");
            }
        }));
        // ログイン権限
        put("LOGIN_TYPE", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("ROLE_USER", "ROLE_USER");
                put("ROLE_ADMIN", "ROLE_ADMIN");
            }
        }));
        // 有効フラグ
        put("YUKO_FLG", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("1", "無効");
                put("2", "有効");
            }
        }));
        // 有効/無効データ
        put("DELDT_FLG", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("1", "無効のみ");
                put("2", "有効のみ");
            }
        }));
        // 公開区分
        put("OPN_KBN", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("1", "公開");
                put("2", "非公開");
            }
        }));
        // 都道府県
        put("CITY", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("1", "北海道");
                put("2", "青森県");
                put("3", "岩手県");
                put("4", "宮城県");
                put("5", "秋田県");
                put("6", "山形県");
                put("7", "福島県");
                put("8", "茨城県");
                put("9", "栃木県");
                put("10", "群馬県");
                put("11", "埼玉県");
                put("12", "千葉県");
                put("13", "東京都");
                put("14", "神奈川県");
                put("15", "新潟県");
                put("16", "富山県");
                put("17", "石川県");
                put("18", "福井県");
                put("19", "山梨県");
                put("20", "長野県");
                put("21", "岐阜県");
                put("22", "静岡県");
                put("23", "愛知県");
                put("24", "三重県");
                put("25", "滋賀県");
                put("26", "京都府");
                put("27", "大阪府");
                put("28", "兵庫県");
                put("29", "奈良県");
                put("30", "和歌山県");
                put("31", "鳥取県");
                put("32", "島根県");
                put("33", "岡山県");
                put("34", "広島県");
                put("35", "山口県");
                put("36", "徳島県");
                put("37", "香川県");
                put("38", "愛媛県");
                put("39", "高知県");
                put("40", "福岡県");
                put("41", "佐賀県");
                put("42", "長崎県");
                put("43", "熊本県");
                put("44", "大分県");
                put("45", "宮崎県");
                put("46", "鹿児島県");
                put("47", "沖縄県");
            }
        }));

        // ソート順
        put("sort_order", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                put("ASC", "昇順");
                put("DESC", "降順");
            }
        }));
        // 「年」のプルダウン
        put("years", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                for (int i=2007; i > calendar.get(Calendar.YEAR); i++) {
                    put(Integer.toString(i), Integer.toString(i));
                }
            }
        }));
        // 「月」のプルダウン
        put("months", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                for (int i=1; i > 12; i++) {
                    put(String.format("%02d", i), String.format("%02d", i));
                }
            }
        }));
        // 「日」のプルダウン
        put("days", (Map<Object, String>) Collections.unmodifiableMap(
                new LinkedHashMap<Object, String>() {
            private static final long serialVersionUID = 1L;
            {
                for (int i=1; i > 31; i++) {
                    put(String.format("%02d", i), String.format("%02d", i));
                }
            }
        }));
        };
    });
}

Functions.java

utils.Functions.java
・当クラスは固定です。「javaSpringBootテーブル項目一覧などの定義」エクセルに影響されません。

package com.kaz01u.demo.utils;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.validation.ConstraintViolation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import com.kaz01u.demo.form.SrchOrderForm;

@Component
public class Functions {
    
    @Autowired
    AppProperties appProperties;

    /**
     * editSortItemNameOrderメソッド
     * SortItemNameとSortOrderの内容をチェック、編集する
     * 
     * @param srchOrderForm 昇順降順条件
     * @param sortItemNames ソート項目の項目名(Entityの項目名。テーブル項目名ではない)
     */
    public static  void editSortItemNameOrder(SrchOrderForm srchOrderForm, String[] sortItemNames) {
        //ソート項目の指定がないとき
        if (ObjectUtils.isEmpty(srchOrderForm.getSortItemName())) {
            srchOrderForm.setSortItemName(sortItemNames[0]);
        } else {
            List<String> sortItemNameList = Arrays.asList(sortItemNames);
            //ソート項目の項目名に存在しない場合
            if (!sortItemNameList.contains(srchOrderForm.getSortItemName())) {
                srchOrderForm.setSortItemName(sortItemNames[0]);
            }
        }
        //ソート昇順降順指定がないとき又は、AでもDでもないとき
        if (ObjectUtils.isEmpty(srchOrderForm.getSortOrder()) ||
                (!srchOrderForm.getSortOrder().equals("A") &&
                        !srchOrderForm.getSortOrder().equals("D"))) {
            srchOrderForm.setSortOrder("A");
        }
    }

    /**
     * @param str ELEMENTSのキー
     * @param dflt ”▼選択してください"や"未選択"を設定する。設定しない場合""を指定する。
     * @param elements Elements.javaのエレメント又は、DBから読み込んだElements
     * @return ELEMENTSキー毎のコード一覧(LinkedHashMap)
     */
    public static LinkedHashMap<Object, String> publicELEMENTS(String str, String dflt, 
                                            Map<String, Map<Object, String>> elements) {
        LinkedHashMap<Object, String> linkedHashMap = new LinkedHashMap<Object, String>();
        if (!ObjectUtils.isEmpty(dflt) ) {
            linkedHashMap.put("", dflt);
        }
        linkedHashMap.putAll(elements.get(str));
        return linkedHashMap;
    }

    /**
     * setAndDelUploadFileメソッド
     * アップロードデータを追加更新削除する
     * 注意:更新前実ファイルの削除は行っていません。
     *    呼び出しもとで、アプロード及び削除対象ファイルを"_BK"にリネームしておいて、
     *    DB更新正常終了後、リネームした"_BK"ファイルを、削除してください。
     * ファイルを登録したときはファイル名を戻す。
     * 削除は空白を戻す。
     * 
     * @param file アップロードファイル(nullでないこと。)
     * @param table 登録先のテーブル名
     * @param pkey 登録先のテーブル主キー
     * @param itemName 登録先の項目名
     * @param mode モード ins_do、upd_do、insList_do、updList_do
     * @param delKbn 削除区分 "1":削除
     * @return ファイルを登録したときはファイル名。
     *      削除は空白。
     */
    public String setAndDelUploadFile(MultipartFile file,String table, String pkey, 
            String itemName, String mode, String delKbn){
        String itemNameNew = "";
        if (!table.matches("^[0-9a-zA-Z_\\-]+$") || 
                !pkey.matches("^[0-9a-zA-Z_\\-]+$")) { // TABLE名キーであること。
            throw new RuntimeException("failed tableName = "  + table + " failed tableKey = " + pkey);
        }
        Path path = Paths.get(appProperties.getDirUpload() + "/"  
                                                    + table + "/" + pkey + "/");
        if ((mode.equals("ins_do") || mode.equals("upd_do") || 
                    mode.equals("insList_do") || mode.equals("updList_do")) && 
                                    (ObjectUtils.isEmpty(delKbn) ||
                                    !delKbn.equals(Elements.DELKBN))) {
            if (!Files.exists(path)) {
                try {
                    //Files.createDirectory(path);
                    Files.createDirectories(path); // 途中フォルダが存在しない場合作成する。
                } catch (NoSuchFileException ex) {
                    throw new RuntimeException("NoSuchFileExceptionエラーが発生しました");
                } catch (IOException ex) {
                    throw new RuntimeException("IOExceptionエラーが発生しました");
                }
            }
            //拡張子を抽出する
            int dot = file.getOriginalFilename().lastIndexOf(".");
            String extention = "";
            if (dot > 0) {
                extention = file.getOriginalFilename().substring(dot).toLowerCase();
            }
            String filename = itemName + extention;
            //ファイルUPLOAD先パス作成
            Path uploadfile = Paths.get(appProperties.getDirUpload() + "/"  
                                          + table + "/" + pkey + "/" + filename );
            //ファイルUPLOAD
            try (OutputStream os = Files.newOutputStream(uploadfile, StandardOpenOption.CREATE)) {
                byte[] bytes = file.getBytes();
                os.write(bytes);
                os.flush();
                os.close();
            } catch (IOException ex) {
                throw new RuntimeException("IOExceptionエラーが発生しました", ex);
            }
            itemNameNew = filename;
        } else { 
            itemNameNew = "";
        }
        return itemNameNew;
    }

    /**
     * renameBkFileメソッド
     * ファイルを”_BK”にリネームする
     * 
     * @param pkPlusFileName PKディレクトリを含めたファイル名
     * @return BKファイル名
     */
    public String renameBkFile(String pkPlusFileName){
        File fileFrom = new File(appProperties.getDirUpload() + "/"  
                                                + pkPlusFileName);
        File fileTo = new File(appProperties.getDirUpload() + "/"  
                                                + pkPlusFileName + "_BK");
        if (fileFrom.exists()) {
            //BKファイルはないはずなので、もしもあっても、考えずにリネームする
            fileFrom.renameTo(fileTo);
        } else {
            throw new RuntimeException("not found file = " + appProperties.getDirUpload() + "/"  
                                                + pkPlusFileName);
        }
        return pkPlusFileName + "_BK";
    }

    /**
     * renameBkFileListメソッド
     * リストの”_BK”ファイルを”_BK”なしにリネームする
     * 
     * @param list ファイル名リスト
     */
    public void renameBkFileList(List<String> list){
        //リネームは、逆順で行う
        for (int i = list.size() - 1 ; i > -1; i--) {
            File fileFrom = new File(appProperties.getDirUpload() + "/"  
                                + list.get(i));
            File fileTo = new File(appProperties.getDirUpload() + "/"  
                                + list.get(i).substring(0, list.get(i).length() - "_BK".length()));
            if (fileFrom.exists()) {
                fileFrom.renameTo(fileTo);
            } else {
                throw new RuntimeException("not found file = " + appProperties.getDirUpload() + "/"  
                                + list.get(i));
            }
        }
    }

    /**
     * delFileListメソッド
     * ファイルを削除する
     * 
     * @param list ファイル名リスト
     */
    public void delFileList(List<String> list){
        //削除は、逆順で行う
        for (int i = list.size() - 1; i > -1; i--) {
            File file = new File(appProperties.getDirUpload() + "/"  
                                                + list.get(i));
            if (file.exists()) {
                file.delete();
            } else {
                //削除は、存在しなくても例外にしない
            }
        }
    }    
    /**
     * createErrorMessageメソッド
     * ファイルアップロードの単体項目チェックエラーを
     * 行番号、項目昇順のエラーメッセージとして戻す。
     * 
     * @param constraintViolations ファイルアップロードの単体項目チェック時の例外から設定
     * @return 行番号、項目昇順のエラーメッセージリスト
     */
    public static List<String> createErrorMessage(
            Set<ConstraintViolation<?>> constraintViolations) {

        // 行番号、項目昇順のエラーメッセージ
        HashMap<Integer, ArrayList<String>> hashMap = new HashMap<>();
        // 項目昇順のエラーメッセージ
        ArrayList<String> list = null;

        for (ConstraintViolation<?> violation : constraintViolations) {
            //項目名を抽出する
            int dot = violation.getPropertyPath().toString().lastIndexOf(".");
            String item = "";
            if (dot > 0) {
                item = violation.getPropertyPath().toString().substring(dot+1).toLowerCase();
            }
            //行を抽出する
            int kagi = violation.getPropertyPath().toString().lastIndexOf("[");
            String lineStr = "";
            Integer line = 0;
            if (kagi > 0) {
                lineStr = violation.getPropertyPath().toString().substring(kagi+1,(dot-1));
                line = Integer.parseInt(lineStr) + 2;
            }
            if (!hashMap.containsKey(line)) {
                list = new ArrayList<String>();
                hashMap.put(line, list);
            } else {
                list = hashMap.get(line);
            }
            list.add(item + ":" + violation.getMessageTemplate());
        }
        List<String> MsgList = new ArrayList<String>();
        for (Map.Entry<Integer, ArrayList<String>> entry : hashMap.entrySet()) {
            // 項目昇順にする
            Collections.sort(entry.getValue());
            for (String msg :  entry.getValue()) {
                MsgList.add(entry.getKey() + "行目 " + msg);
            }
        }
        return MsgList;
    }

    /**
     * setErrorMsgメソッド
     * アップロードファイルの、複合チェックエラーを登録する
     * 
     * @param hashMap 行毎の項目エラーリストをマップ
     * @param index アップロードファイルの行番号
     * @param list 項目エラーリスト
     * @param errMsg 項目エラー内容
     */
    public static void setErrorMsg( HashMap<Integer, ArrayList<String>> hashMap,
                        Integer index,
                        ArrayList<String> list, String errMsg) {
        if (!hashMap.containsKey(index)) {
            list = new ArrayList<String>();
            hashMap.put(index, list);
        } else {
            list = hashMap.get(index);
        }
        list.add(errMsg);
    }

    /**
     * getErrorMsgListメソッド
     * 行毎の項目エラーリストマップからエラーメッセージリストを戻す
     * 
     * @param hashMap 行毎の項目エラーリストをマップ
     * @return エラーメッセージリスト
     */
    public static List<String> getErrorMsgList( HashMap<Integer, ArrayList<String>> hashMap) {
        List<String> msgList = new ArrayList<String>();
        for (Map.Entry<Integer, ArrayList<String>> entry : hashMap.entrySet()) {
            // 項目昇順にする
            Collections.sort(entry.getValue());
            for (String msg :  entry.getValue()) {
                msgList.add(entry.getKey() + "行目 " + msg);
            }
        }
        return msgList;
    }
    
    /**
     * nvlメソッド
     * null置換(置換文字列は空文字固定)
     * 
     * @param str    対象文字列
     * @return 結果文字
     */
    public static String nvl(Object obj){
        return (obj == null)?"":obj.toString();
    }    
    
    /**
     * lvnメソッド
     * 空文字null置換
     * 
     * @param str 対象文字列
     * @return 結果文字
     */
    public static String lvn(String str){
        return (str != null && str.equals(""))?null:str;
    }    

    /**
     * joinStrsメソッド
     *
     * @param strs 文字列の配列
     * @return カンマ区切りの文字列
     */
    public static String joinStrs(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }
        return Stream.of(strs)
                .map(String::trim)
                .map(String::toUpperCase)
                .collect(Collectors.joining(","));
    }

    /**
     * editStrsメソッド
     * strs中に重複データがある場合1つにする
     * 
     * @param strs カンマ区切りの文字列
     * @return 編集後の、カンマ区切りの文字列。補足:空文字の時はnullを戻す
     */
    public static String editStrs(String strs) {
        String[] strsArray = strs.split(",");
        Map<String,String> map = new TreeMap<String,String>();
        for (String role : strsArray) {
            map.put(role, role);
        }
        List<String> list = new ArrayList<String>(map.keySet());
        strsArray = new String[list.size()];
        list.toArray(strsArray);
        String joinedStrs = joinStrs(strsArray);
        return joinedStrs;
    }

    /**
     * editDateFromToメソッド
     * 検索用Date型FromToのSQLを作成する
     * 
     * @param sqlItem 項目のsql名。例:"s.insdt"
     * @param from 日付From。Dateオブジェクト
     * @param to 日付To。Dateオブジェクト
     * @param map リプレースメントのINDEXをKEY="i"で持つ
     * @return
     */
    public static String editDateFromTo(String sqlItem, Date from,Date to, Map<String,Integer> map) {
        String str= "";
        //リプレームメントのインデックスをマップで渡す。
        int i = map.get("i");
        if (!ObjectUtils.isEmpty(from) && !ObjectUtils.isEmpty(to)) {
            str = (i==0?" (":" and(") + sqlItem + " >= :p" + ++i + " and " + sqlItem + " < :p" + ++i + ") ";
        } else if (!ObjectUtils.isEmpty(from) ) {
            str = (i==0?"":" and ") + sqlItem + " >= :p" + ++i + " ";
        } else if (!ObjectUtils.isEmpty(to)) {
            str = (i==0?"":" and ") + sqlItem + " < :p" + ++i + " ";
        }
        //リプレームメントのインデックスをマップで渡す。
        map.put("i", i);
        return str;
    }

    /**
    * パスワードを返す。
    * @return パスワード
    */
    public static String makePassword(int keta) {
        String password  = "";
        String useMojis = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        Random r = new Random();
        for ( int i=0; i < keta; i++) {
            int j = r.nextInt(useMojis.length());
            password += useMojis.charAt(j);
        }
        return password;
    }

    /**
    * 項目値のチェック。
    * @param str 項目値
    * @param longKbn true:Long false:Long以外
    * @return true:NULLまたは空白または属性例外、false:NULL以外かつ空白以外かつ属性例外以外
    */
    public static boolean isItemEmptyOrNoGood(String str, boolean longKbn) {
        boolean flg  = true;
        if (!ObjectUtils.isEmpty(str)) {
            if (longKbn) {
                boolean isNumber = str.codePoints()
                          .allMatch(Character::isDigit);
                if (isNumber) {
                    flg  = false;
                }
            }else {
                flg  = false;
            }
        }
        return flg;
    }
}

utils.PageNavi.java
・当クラスは固定です。「javaSpringBootテーブル項目一覧などの定義」エクセルに影響されません。
・getHTMLメソッドで、画面ページングをHTMLを戻します。

package com.kaz01u.demo.utils;
import org.springframework.data.domain.Page;

public class PageNavi {

    /**
     * getHTMLメソッド
     * Spring Data JPAを使用して取得するPageオブジェクトの
     * ページングHTMLを戻す
     * 
     * @param maxPageSizes 1画面あたりのページ数
     * @param page Spring Data JPAを使用して取得するPageオブジェクト
     * @param pageable Spring Data JPAを使用するときのPageableオブジェクト
     * @param url 遷移先url
     * @return ページングHTML
     */
    public static String getHTML(int maxPageSizes, @SuppressWarnings("rawtypes") Page page, String url) {
        int totalPages = page.getTotalPages();
        int totalGroups = (int) Math.ceil(totalPages / (maxPageSizes + 0.0));
        int pageNumber = page.getContent().size() == 0 ? 0 : page.getNumber() + 1;
        
        int pageNumberGroup = (int) Math.ceil(pageNumber / (maxPageSizes + 0.0));
        int startPage = (pageNumberGroup - 1) * maxPageSizes + 1;
        int endPage = startPage + maxPageSizes - 1;
        if (endPage >= totalPages) {
            endPage = totalPages;
        }
        StringBuffer sb = new StringBuffer();
        int pageNumber0Org = pageNumber - 1;

        if (pageNumberGroup > 1) {
            sb.append("<a href=\"JavaScript:paging(" + ((pageNumberGroup - 1) * maxPageSizes - 1) + 
            ");\"></a>&nbsp;&nbsp;<a href = \"JavaScript:paging(0);\">[最初]</a>&nbsp;&nbsp;");
        } else {
            sb.append("[最初]&nbsp;&nbsp;");
        }
        if (pageNumber == 1) {
            sb.append("[前ページ]&nbsp;&nbsp;");
        } else {
            sb.append("<a href=\"JavaScript:paging(" + (pageNumber0Org - 1) +
            ");\">[前ページ]</a>&nbsp;&nbsp;");
        }
        for (int i = startPage; i <= endPage; i++) {
            if (pageNumber == i) {
                sb.append("<strong><font color=\"#FF6600\">[" + i + "]</font></strong>");
            } else {
                sb.append("<a href=\"JavaScript:paging(" + (i - 1) +
                ");\">[" + i + "]</a>");
            }
        }
        if (pageNumber == totalPages || totalPages == 1 || totalPages == 0) {
            if (totalPages == 0)
                sb.append("[1]&nbsp;&nbsp;[次ページ]");
            else
                sb.append("&nbsp;&nbsp;[次ページ]");
        } else {
            sb.append("&nbsp;&nbsp;<a href=\"JavaScript:paging(" + (pageNumber0Org + 1) +
            ");\">[次ページ]</a>");
        }
        if (pageNumberGroup < totalGroups) {
            sb.append("&nbsp;&nbsp;<a href=\"JavaScript:paging(" + (totalPages - 1) +
            ");\">[最後]</a>&nbsp;&nbsp;<a href=\"JavaScript:paging(" + (((pageNumberGroup * maxPageSizes) - 1) + 1) +
            ");\"></a>");
        } else {
            sb.append("&nbsp;&nbsp;[最後]");
        }
        return sb.toString();
    }
}

ValidCheck.java

utils.ValidCheck.java
・当クラスは固定です。「javaSpringBootテーブル項目一覧などの定義」エクセルに影響されません。
・validationクラス以外の、共通使用できるチェックメソッドを登録しています。
・Formクラス、uploadクラスで使用されています。

package com.kaz01u.demo.utils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;

import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

public class ValidCheck {
    
    /**
     * isCheckYearMonthDayメソッド
     * 年、月、日の項目を結合してチェック
     * ただし、空白の時はチェックしない。
     * 
     * @param year 年
     * @param month 月
     * @param day 日
     * @return true:OK、fale:NG
     */
    public static boolean isCheckYearMonthDay(String year,
                                                String month, String day) {
        if (ObjectUtils.isEmpty(year) || 
            ObjectUtils.isEmpty(month) ||
            ObjectUtils.isEmpty(day)) {
            return true;
        }
        try {
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
            String s1 = String.format("%4s", year).replace(" ", "0") + "/" + 
                        String.format("%2s", month).replace(" ", "0")  + "/" +  
                        String.format("%2s", day).replace(" ", "0")  ;
            //s2は使用していないが、dtf.formatで例外がでればチェックエラー、でなければチェックOK
            @SuppressWarnings("unused")
            String s2 = dtf.format(LocalDate.parse(s1, dtf)); 
        } catch (DateTimeParseException dtp) {
            return false;
        }
        return true;
     }
    
    /**
     * isCheckDateFromToメソッド
     * 日付Fromと日付Toが指定された場合、大小チェックを行う。
     * どちらかが空白の場合はチェックしない。
     * 
     * @param updtFrom 日付From
     * @param updtTo 日付To
     * @return true:OK、fale:NG
     */
    public static boolean isCheckDateFromTo(Date updtFrom,
            Date updtTo) {
        if ((!ObjectUtils.isEmpty(updtFrom) && 
                !ObjectUtils.isEmpty(updtTo) ) &&
                updtFrom.compareTo(updtTo) > 0) {
            return false;
        }
        return true;
     }
    
    /**
     * isCheckStrFromToメソッド
     * FromとToが指定された場合、文字列としての、大小チェックを行う。
     * どちらかが空白の場合はチェックしない。
     * 
     * @param from From
     * @param to To
     * @return true:OK、fale:NG
     */
    public static boolean isCheckStrFromTo(String from,
            String to) {
        if ((!ObjectUtils.isEmpty(from) && 
                !ObjectUtils.isEmpty(to) ) &&
                from.compareTo(to) > 0) {
            return false;
        }
        return true;
     }
    
    /**
     * isCheckNumFromToメソッド
     * FromとToが指定された場合、大小チェックを行う。
     * 
     * @param from From
     * @param to To
     * @return true:OK、fale:NG
     */
    public static boolean isCheckNumFromTo(Long from,
            Long to) {
        if ((!ObjectUtils.isEmpty(from) && 
                !ObjectUtils.isEmpty(to) ) &&
                from >= to) {
            return false;
        }
        return true;
     }
    
    /**
     * isCheckEqualsメソッド
     * 文字列1と文字列2が同じことをチェック
     * ただし、空白の時はチェックしない。
     * 
     * @param str1 文字列1
     * @param str2 文字列2
     * @return true:OK、fale:NG
     */
    public static boolean isCheckEquals(String str1,
                            String str2) {
        if (ObjectUtils.isEmpty(str1) || 
            ObjectUtils.isEmpty(str2) ) {
            return true;
        }
        if (str1.compareTo(str2) != 0) {
            return false;
        }
        return true;
     }

    /**
     * isCheckNumericCompareメソッド
     * 数字1<=数字2をチェック
     * ただし、NULLの時はチェックしない。
     * 
     * @param obj1 数字1
     * @param obj2 数字2
     * @return true:OK、fale:NG
     */
    public static boolean isCheckNumericCompare(Object obj1, Object obj2) {
        
        if (ObjectUtils.isEmpty(obj1) || 
                ObjectUtils.isEmpty(obj2) ) {
                return true;
        }
        try {
            BigDecimal big1 = new BigDecimal(obj1.toString());
            BigDecimal big2 = new BigDecimal(obj2.toString());
            if (big1.compareTo(big2) > 0) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }
    
    /**
     * isCheckElementsメソッド
     * ELEMENTSのelementKeyにあるマップにkeyが登録されているかチェックする。
     * ただし、NULLの時はチェックしない。
     * 
     * @param elementKey Elements.ELEMENTSのelementKey
     * @param key elementKeyでマップのキー
     * @return true:OK、fale:NG
     */
    public static boolean isCheckElements(String elementKey, String key) {
        
        if (ObjectUtils.isEmpty(elementKey) ||
                ObjectUtils.isEmpty(key)) {
                return true;
        }
        if ((Elements.ELEMENTS.get(elementKey)).containsKey(key)) {
            return true;
        }
        return false;
    }

    /**
     * isImageFileメソッド
     * アップロードファイルの拡張子が画像であることを確認
     * ただし、NULLの時はチェックしない。
     * 
     * @param file アップロードファイル
     * @return false:画像でない true:画像である(但し、アップロードファイルがない場合も含む)
     */
    public static boolean isImageFile(MultipartFile file) {
        if (!(file == null) && 
                !ObjectUtils.isEmpty(file.getOriginalFilename())) {
            String filenameLowered = file.getOriginalFilename().toLowerCase();
            if (filenameLowered.endsWith(".jpg")
                || filenameLowered.endsWith(".jepg")
                || filenameLowered.endsWith(".png")
                || filenameLowered.endsWith(".gif")
                || filenameLowered.endsWith(".bmp")
                || filenameLowered.endsWith(".tiff")
            ) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }    

    /**
     * isFileメソッド
     * アップロードファイルの拡張子がファイルであることを確認
     * ただし、NULLの時はチェックしない。
     * 
     * @param file アップロードファイル
     * @return false:ファイルでない true:ファイルである(但し、アップロードファイルがない場合も含む)
     */
    public static boolean isFile(MultipartFile file) {
        if (!(file == null) && 
                !ObjectUtils.isEmpty(file.getOriginalFilename())) {
            String filenameLowered = file.getOriginalFilename().toLowerCase();
            if (filenameLowered.endsWith(".txt")
                || filenameLowered.endsWith(".pdf")
            ) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }    
    
    /**
     * isFileHissuメソッド
     * アップロードファイルの必須チェック
     * @param file 画面上のアップロードファイル
     * @param orgFileName テーブル中のファイル名
     * @param del 画面上の削除フラグ
     * @return true:OK false:NG
     */
    public static boolean isFileHissu(MultipartFile file,
            String orgFileName, String del) {
        //削除指定の時
        if (!ObjectUtils.isEmpty(del) && del.equals(Elements.DELKBN)) {
            return true;
        }
        // テーブル中のファイル名が空の時
        if (ObjectUtils.isEmpty(orgFileName)) {
            //アップロードファイルの指定があるとき
            if (!(file == null) && 
                    !ObjectUtils.isEmpty(file.getOriginalFilename())) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }
}