かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その35 )( 貸出申請画面の作成6 )

概要

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その34 )( 貸出申請画面の作成5 ) の続きです。

参照したサイト・書籍

目次

  1. JPA の AutoConfiguration を無効にする
  2. Values クラスの実装を Reflection による実装から Generics による実装へ変更する
  3. LendingappForm.java の setLendingBookList の実装がラムダらしくないので修正する

手順

JPA の AutoConfiguration を無効にする

  1. feature/43-issue ブランチではなく別のブランチを作成して作業します。一旦 1.0.x ブランチをチェックアウトした後、feature/46-issue ブランチを作成します。

  2. src/main/java/ksbysample/webapp/lending の下の Application.javaリンク先の内容 に変更します。

  3. 全てのテストが成功するか確認します。Project View のルートでコンテキストメニューを表示して「Run 'Tests in 'ksbysample...' with Coverage」を選択します。

    テストが実行され、全て成功することが確認できます。

    f:id:ksby:20151202235711p:plain

  4. clean タスクの実行→「Rebuild Project」メニューの実行→build タスクの実行を行い、"BUILD SUCCESSFUL" のメッセージが出力されることも確認します。

    f:id:ksby:20151203000315p:plain

  5. commit、GitHub へ Push、feature/43-issue -> 1.0.x へ Pull Request、1.0.x でマージ、feature/43-issue ブランチを削除、をします。

  6. feature/43-issue をチェックアウトした後、コマンドラインから以下のコマンドを実行します。

    > git rebase 1.0.x

Values クラスの実装を Reflection による実装から Generics による実装へ変更する

  1. src/main/java/ksbysample/webapp/lending/values の下の ValuesHelper.javaリンク先の内容 に変更します。

  2. src/main/java/ksbysample/webapp/lending/values の下の LendingAppStatusValues.javaリンク先の内容 に変更します。

  3. src/main/java/ksbysample/webapp/lending/values の下の LendingBookLendingAppFlgValues.javaリンク先の内容 に変更します。

  4. 動作確認します。データは Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その31 )( 貸出申請画面の作成2 ) で作成した貸出申請ID = 105 のデータを使用します。

  5. Gradle projects View から bootRun タスクを実行して Tomcat を起動します。

  6. ブラウザを起動し http://localhost:8080/lendingapp?lendingAppId=105 へアクセスします。最初はログイン画面が表示されますので ID に "tanaka.taro@sample.com"、Password に "taro" を入力して、「次回から自動的にログインする」をチェックせずに「ログイン」ボタンをクリックします。貸出申請画面が表示されます。

    f:id:ksby:20151203015946p:plain

  7. 何件か「申請する」を選択して申請理由を記入した後、「申請」ボタンをクリックします。

    f:id:ksby:20151203020153p:plain

    ステータスが「申請中」に変わり、申請した書籍のみ「申請する/しない」「申請理由」欄にテキストが表示されることが確認できます。

    f:id:ksby:20151203020550p:plain

  8. Ctrl+F2 を押して Tomcat を停止します。

  9. 一旦 commit します。

LendingappForm クラスの setLendingBookList メソッドの実装がラムダらしくないので修正する

  1. src/main/java/ksbysample/webapp/lending/web/lendingapp の下の LendingappForm.javaリンク先の内容 に変更します。

  2. Gradle projects View から bootRun タスクを実行して Tomcat を起動します。

  3. 動作確認します。ブラウザを起動し http://localhost:8080/lendingapp?lendingAppId=105 へアクセスします。最初はログイン画面が表示されますので ID に "tanaka.taro@sample.com"、Password に "taro" を入力して、「次回から自動的にログインする」をチェックせずに「ログイン」ボタンをクリックします。

    貸出申請画面が表示されてデータも表示されることを確認します。

    f:id:ksby:20151203075429p:plain

  4. Ctrl+F2 を押して Tomcat を停止します。

  5. 一旦 commit します。

ソースコード

Application.java

package ksbysample.webapp.lending;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

import java.text.MessageFormat;

@ImportResource("classpath:applicationContext-${spring.profiles.active}.xml")
@SpringBootApplication(exclude = {JpaRepositoriesAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@ComponentScan("ksbysample")
@EnableRedisHttpSession
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class Application {

    public static void main(String[] args) {
        String springProfilesActive = System.getProperty("spring.profiles.active");
        if (!StringUtils.equals(springProfilesActive, "product")
                && !StringUtils.equals(springProfilesActive, "develop")
                && !StringUtils.equals(springProfilesActive, "unittest")) {
            throw new UnsupportedOperationException(MessageFormat.format("JVMの起動時引数 -Dspring.profiles.active で develop か unittest か product を指定して下さい ( -Dspring.profiles.active={0} )。", springProfilesActive));
        }

        SpringApplication.run(Application.class, args);
    }

}
  • @SpringBootApplication@SpringBootApplication(exclude = {JpaRepositoriesAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) を追加します。

ValuesHelper.java

package ksbysample.webapp.lending.values;

import com.google.common.reflect.ClassPath;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;

@Component("vh")
public class ValuesHelper<T extends Enum<T> & Values> {

    private final Map<String, String> valuesObjList;

    private ValuesHelper() throws IOException {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        valuesObjList = ClassPath.from(loader).getTopLevelClasses(this.getClass().getPackage().getName())
                .stream()
                .filter(classInfo -> !classInfo.getName().equals(this.getClass().getName()))
                .collect(Collectors.toMap(ClassPath.ClassInfo::getSimpleName, ClassPath.ClassInfo::getName));
    }

    @SuppressWarnings("unchecked")
    public String getValue(String classSimpleName, String valueName)
            throws ClassNotFoundException {
        Class<T> enumType = (Class<T>) Class.forName(this.valuesObjList.get(classSimpleName));
        T val = Enum.valueOf(enumType, valueName);
        return val.getValue();
    }

    @SuppressWarnings("unchecked")
    public String getText(String classSimpleName, String value)
            throws ClassNotFoundException {
        Class<T> enumType = (Class<T>) Class.forName(this.valuesObjList.get(classSimpleName));
        String result = "";
        for (T val : enumType.getEnumConstants()) {
            if (val.getValue().equals(value)) {
                result = val.getText();
                break;
            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    public T[] values(String classSimpleName)
            throws ClassNotFoundException {
        Class<T> enumType = (Class<T>) Class.forName(this.valuesObjList.get(classSimpleName));
        return enumType.getEnumConstants();
    }

}
  • Qiita の記事に書いてある ValuesHelper.java のソースを package の行を除き丸ごとコピーします。

LendingAppStatusValues.java

package ksbysample.webapp.lending.values;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum LendingAppStatusValues implements Values {

    TENPORARY_SAVE("1", "一時保存")
    , UNAPPLIED("2", "未申請")
    , PENDING("3", "申請中")
    , APPLOVED("4", "承認済");

    private final String value;
    private final String text;

}

LendingBookLendingAppFlgValues.java

package ksbysample.webapp.lending.values;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum LendingBookLendingAppFlgValues implements Values {

    NOT_APPLY("", "しない")
    , APPLY("1", "する");

    private final String value;
    private final String text;

}

LendingappForm.java

package ksbysample.webapp.lending.web.lendingapp;

import ksbysample.webapp.lending.entity.LendingApp;
import ksbysample.webapp.lending.entity.LendingBook;
import lombok.Data;

import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

@Data
public class LendingappForm {

    private LendingApp lendingApp;

    private String btn;

    @Valid
    private List<LendingBookDto> lendingBookDtoList;

    public void setLendingBookList(List<LendingBook> lendingBookList) {
        this.lendingBookDtoList = lendingBookList.stream()
                .map(LendingBookDto::new)
                .collect(Collectors.toList());
    }

}
  • setLendingBookList メソッド内の処理を上記のように変更します。

履歴

2015/12/03
初版発行。