Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その52 )( 貸出申請結果確認画面の作成4 )
概要
Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その51 )( 貸出申請結果確認画面の作成3 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- 貸出申請結果確認画面の作成
- 貸出申請したユーザでなければ、共通エラー画面を表示し HTTPステータスコードの 403 を返す処理の実装
- 貸出申請結果確認画面の作成
参照したサイト・書籍
目次
- messages_ja_JP.properties にエラーメッセージを定義する
- ConfirmresultForm, ConfirmresultService クラスの変更
- ConfirmresultController クラスの変更
- 動作確認
- 次回は。。。
手順
messages_ja_JP.properties にエラーメッセージを定義する
- src/main/resources の下の messages_ja_JP.properties を リンク先の内容 に変更します。
ConfirmresultForm, ConfirmresultService クラスの変更
ログインユーザが貸出申請したユーザか否かを判断するのにユーザID を使用したいので、ユーザID を Controller クラスまで返すようにします。
src/main/java/ksbysample/webapp/lending/web/confirmresult の下の ConfirmresultForm.java を リンク先の内容 に変更します。
src/main/java/ksbysample/webapp/lending/web/confirmresult の下の ConfirmresultService.java を リンク先の内容 に変更します。
ConfirmresultController クラスの変更
- src/main/java/ksbysample/webapp/lending/web/confirmresult の下の ConfirmresultController.java を リンク先の内容 に変更します。
動作確認
動作確認します。Gradle projects View から bootRun タスクを実行して Tomcat を起動します。
http://localhost:8080/confirmresult?lendingAppId=105 にアクセスします。最初はログイン画面が表示されますので ID に "tanaka.taro@sample.com"、Password に "taro" を入力して、「次回から自動的にログインする」をチェックせずに「ログイン」ボタンをクリックします。
"tanaka taro" は貸出申請したユーザなので貸出申請結果確認画面が表示されます。
一旦ログアウトした後、再度 http://localhost:8080/confirmresult?lendingAppId=105 にアクセスします。ログイン画面が表示されますので今度は ID に "suzuki.hanako@test.co.jp"、Password に "hanako" を入力して、「次回から自動的にログインする」をチェックせずに「ログイン」ボタンをクリックします。
"suzuki.hanako" は貸出申請したユーザではないので共通エラー画面が表示されます。
Fiddler で確認すると HTTPステータスコードで 403 が返っていることが確認できます。
Ctrl+F2 を押して Tomcat を停止します。
一旦 commit します。
次回は。。。
テストを作成します。
ソースコード
messages_ja_JP.properties
ConfirmresultParamForm.lendingAppId.emptyerr=貸出申請IDが指定されていません。 ConfirmresultForm.lendingApp.nodataerr=指定された貸出申請IDでは貸出承認されておりません。 Confirmresult.lendingUserId.notequalerr=申請者以外のユーザのため閲覧できません。
Confirmresult.lendingUserId.notequalerr
を追加します。
ConfirmresultForm.java
package ksbysample.webapp.lending.web.confirmresult; import ksbysample.webapp.lending.entity.LendingApp; import ksbysample.webapp.lending.entity.LendingBook; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; import java.util.stream.Collectors; @Data @NoArgsConstructor public class ConfirmresultForm { private LendingApp lendingApp; private Long lendingUserId; private String lendingUserName; private String approvalUserName; private List<ApprovedBookForm> approvedBookFormList; public void setApprovedBookFormListFromLendingBookList(List<LendingBook> lendingBookList) { this.approvedBookFormList = null; if (lendingBookList != null) { this.approvedBookFormList = lendingBookList.stream() .map(ApprovedBookForm::new) .collect(Collectors.toList()); } } }
private Long lendingUserId;
を追加します。
ConfirmresultService.java
package ksbysample.webapp.lending.web.confirmresult; import ksbysample.webapp.lending.dao.LendingAppDao; import ksbysample.webapp.lending.dao.LendingBookDao; import ksbysample.webapp.lending.dao.UserInfoDao; import ksbysample.webapp.lending.entity.LendingApp; import ksbysample.webapp.lending.entity.LendingBook; import ksbysample.webapp.lending.entity.UserInfo; import ksbysample.webapp.lending.helper.download.booklistcsv.BookListCsvData; import ksbysample.webapp.lending.helper.download.booklistcsv.BookListCsvDataConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; import static ksbysample.webapp.lending.values.LendingAppStatusValues.APPLOVED; import static ksbysample.webapp.lending.values.LendingBookLendingAppFlgValues.APPLY; @Service public class ConfirmresultService { @Autowired private LendingAppDao lendingAppDao; @Autowired private UserInfoDao userInfoDao; @Autowired private LendingBookDao lendingBookDao; @Autowired private BookListCsvDataConverter bookListCsvDataConverter; public void setDispData(Long lendingAppId, ConfirmresultForm confirmresultForm) { LendingApp lendingApp = lendingAppDao.selectByIdAndStatus(lendingAppId, Arrays.asList(APPLOVED.getValue())); UserInfo lendingUserInfo = null; UserInfo approvalUserInfo = null; if (lendingApp != null) { lendingUserInfo = userInfoDao.selectById(lendingApp.getLendingUserId()); approvalUserInfo = userInfoDao.selectById(lendingApp.getApprovalUserId()); } List<LendingBook> lendingBookList = lendingBookDao.selectByLendingAppIdAndLendingAppFlg(lendingAppId, APPLY.getValue()); confirmresultForm.setLendingApp(lendingApp); if (lendingUserInfo != null) { confirmresultForm.setLendingUserId(lendingUserInfo.getUserId()); confirmresultForm.setLendingUserName(lendingUserInfo.getUsername()); } if (approvalUserInfo != null) { confirmresultForm.setApprovalUserName(approvalUserInfo.getUsername()); } confirmresultForm.setApprovedBookFormListFromLendingBookList(lendingBookList); } public List<BookListCsvData> getDownloadData(Long lendingAppId) { List<LendingBook> lendingBookList = lendingBookDao.selectByLendingAppIdAndLendingAppFlg(lendingAppId, APPLY.getValue()); List<BookListCsvData> bookListCsvDataList = bookListCsvDataConverter.convertFrom(lendingBookList); return bookListCsvDataList; } }
- setDispData メソッド内で String の lendingUserName, approvalUserName にユーザ名を取得していたのを UserInfo クラスの lendingUserInfo, approvalUserInfo にデータを取得して、そこからユーザID、ユーザ名をコピーするようにします。
ConfirmresultController.java
package ksbysample.webapp.lending.web.confirmresult; import ksbysample.webapp.lending.exception.WebApplicationRuntimeException; import ksbysample.webapp.lending.helper.download.DataDownloadHelper; import ksbysample.webapp.lending.helper.download.booklistcsv.BookListCsvData; import ksbysample.webapp.lending.helper.download.booklistcsv.BookListCsvDownloadHelper; import ksbysample.webapp.lending.helper.message.MessagesPropertiesHelper; import ksbysample.webapp.lending.security.LendingUserDetailsHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @Controller @RequestMapping("/confirmresult") public class ConfirmresultController { @Autowired private MessagesPropertiesHelper messagesPropertiesHelper; @Autowired private ConfirmresultService confirmresultService; @RequestMapping public String index(@Validated ConfirmresultParamForm confirmresultParamForm , BindingResult bindingResult , ConfirmresultForm confirmresultForm , BindingResult bindingResultOfConfirmresultForm , HttpServletResponse response) { if (bindingResult.hasErrors()) { throw new WebApplicationRuntimeException( messagesPropertiesHelper.getMessage("ConfirmresultParamForm.lendingAppId.emptyerr", null)); } // 画面に表示するデータを取得する confirmresultService.setDispData(confirmresultParamForm.getLendingAppId(), confirmresultForm); // 指定された貸出申請IDで承認済のデータがない場合には、貸出申請結果確認画面上にエラーメッセージを表示する if (confirmresultForm.getLendingApp() == null) { bindingResultOfConfirmresultForm.reject("ConfirmresultForm.lendingApp.nodataerr"); } else { // 指定された貸出申請IDの申請者とログインしているユーザが一致しない場合にはエラーメッセージを表示し、 // HTTP ステータスコードも 403 を返す if (!Objects.equals(confirmresultForm.getLendingUserId(), LendingUserDetailsHelper.getLoginUserId())) { response.setStatus(HttpStatus.FORBIDDEN.value()); throw new WebApplicationRuntimeException( messagesPropertiesHelper.getMessage("Confirmresult.lendingUserId.notequalerr", null)); } } return "confirmresult/confirmresult"; } @RequestMapping(value = "/filedownloadByResponse", method = RequestMethod.POST) public void filedownloadByResponse(ConfirmresultForm confirmresultForm , BindingResult bindingResult , HttpServletResponse response) throws IOException { .......... } .......... }
- index メソッドの以下の点を変更します。
- 引数に
HttpServletResponse response
を追加します。 if (!Objects.equals(confirmresultForm.getLendingUserId(), LendingUserDetailsHelper.getLoginUserId())) { ... }
の処理を追加します。403 を返すために response.setStatus を呼び出し、WebApplicationRuntimeException を throw して共通エラー画面が表示されるようにします。
- 引数に
- 今回の主題とは直接関係ありませんが、filedownloadByResponse メソッドの引数
@Validated ConfirmresultForm confirmresultForm
から@Validated
を削除します。ConfirmresultForm クラス内には Bean Validation のアノテーションを付加していないので不要なためです。
履歴
2016/02/07
初版発行。