ELBOOKS
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[FrontPage]]
&size(20){目次};
#contents(level=1)
*スケジュール作成サンプル [#i6862607]
#ref(./EL-BOOK ワークフロー サンプル.xlsx,80%);
*コーディング作業が楽になるショートカットの一覧 [#i6862607]
[[Windows:https://dekiru.net/article/18619/]]
[[Eclipse:https://www.casleyconsulting.co.jp/blog/enginee...
覚えておくと良いこと
&br;ファイル保存 [Ctrl + S]
&br;全てを保存 [Ctrl + Shift + S]
&br;文字列検索 [Ctrl + F]
&br;コピー[Ctrl + C] ペースト [Ctrl + V]
&br;候補[Ctrl + Space]
*設計書作成 [#x48eecb0]
**機能一覧表 [#l9240598]
#ref(./function_list.png,80%);
**画面構成 [#c3141316]
#ref(./view.png,80%);
**テーブル定義書 [#t0ef638c]
テーブル定義書とはテーブルを作成するための設計書です。デ...
&br;
&ref(./table.png,80%);
**テスト仕様書 [#wc39b0f7]
|画面|区分1|区分2|確認項目|結果|h
|ログイン|テキストボックス|メールアドレス|文字が入力でき...
|~|~|パスワード|文字が入力できること&br();必須項目になっ...
**ER図 [#f1d67711]
[[ER図とは:https://it-koala.com/entity-relationship-diagr...
#ref(./er.png,80%);
**クラス図 [#feca588a]
#ref(./uml_line.png,80%);
&br;多重度はそのクラスのインスタンスが何個関連を持つかを...
#ref(class.png);
**シーケンス図 [#l0ee201a]
Visual Studio Codeを開きます。
左側のメニューに拡張機能があるので
PlantUMLと入力してください
&br;検索すると一番上に出てくると思うのでクリックしてイン...
インストールが終えたら
&br;左上のメニューにあるファイルから新規作成を選択してく...
Untitled-1が作成されるのでCTRL + SHIFT + S を押します。
&br;任意のファイル名を入力し、ファイルの種類をPlantUMLに...
.wsdという形式のファイルができればOKです。
下記がUMLのサンプルになります。
@startuml Update
mainframe ユーザー編集
actor User
participant "ユーザー一覧画面" as View
participant "編集モーダル" as Modal
participant "エンコード" as encode
participant "更新処理" as Update
database "データベース" as DB
alt 権限あり
User -> View : 編集したい
activate View
else 権限なし
User <-- View : エラー
end
View -> Modal : 一覧から選択する
activate Modal
Modal <-- DB : ユーザーID,変更前の名前,メールアドレス...
activate DB
Modal -> Update : 入力(名前,メールアドレス)
activate Update
Modal -> encode : 入力(パスワード)
deactivate Modal
activate encode
encode -> Update : 暗号化したパスワード
deactivate encode
Update -> DB :更新
deactivate Update
View <-- DB : 更新したユーザー情報を反映
deactivate DB
deactivate View
@enduml
&br;ALT+Dを押すとプレビューに図が表示されます。
&br;図を画像ファイルとして保存したい場合は
ファイル内で右クリックすると
ファイル内のダイアグラムをエクスポートとあるのでクリック...
&br;pngを選択するとのファイルを作成した場所にフォルダが作...
*github[#q8a7110e]
Git Hubのアカウント作成
以下のリンクから作成してください
&br;[[アカウント作成:https://github.com/]]
&br;ユーザー名とメールアドレスとパスワードを入力して登録...
無料版であるfreeを選択してContinue押して作成されます。
Git Bashのダウンロード~インストールまで
下記からサイトへ移動してDownloadボタンを押します。
Git Bashの[[ダウンロード:https://gitforwindows.org/]]
インストーラーを起動してセットアップをおこないます。
最初のウィンドウからNextを押して進みます。
&br;Git Bash Hereにチェックが付いていることを確認して
Next
&br;Use Git from the Windows Command Promptを選択して
Next
&br;Use the OpenSSL libraryを選択して
Next
&br;Checkout Windows-style,commit Unix-style line endings...
Next
&br;Use MinTTY(the default terminal of MSYS2)を選択して
Next
&br;Enable file system cachingとEnable Git Credential Man...
Next
&br;いくつかチェックボックスがありますが入れずにNextを押...
Git Bashを開いて以下のコマンドを入力してユーザーの設定を...
&br;
git config --global user.name
git config --global user.email
[[だいたい使うコマンド一覧:https://qiita.com/myalpine/ite...
*フレームワーク [#f45892c1]
**mybatis[#ea99b799]
<?xml version="1.0" encoding="UTF-8"?>
作成したxmlファイルにmybatisを使うための設定をし...
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapp...
Mapperを指定します。
<mapper namespace="com.example.demo.mapper.UserMa...
検索結果をデータ型に変換するためクラスをresul...
<select id="findUser" resultType="com.example...
select user_id,user_name from m_user;
</select>
</mapper>
parameterTypeはinsert文でvalueの値やupdateでsetする値を指...
**Spring [#b68c10c5]
[[こちらのサイト参考に:https://learning-collection.com/sp...
***アノテーション [#e5a17a0a]
&br;@RequestParam URLに含まれるクエリパラメータを受け取る...
&br;@Autowired 外部から呼び出して自動的に初期化してくれる。
&br;@PathVariable @GetMappingで指定したメソッドの引数につ...
&br;@ModelAttribute コントローラーの引数につけて使う HTM...
&br;@Data クラスに@Getter、@Setter、@RequiredArgsConstru...
&br;@Mapper Mapperを定義するために必要なアノテーション ...
&br;@Controller MVCパターンのCの役割を担うコンポーネント...
&br;@Service ビジネスロジックを実装するコンポーネントであ...
&br;@Repository データの永続化に関わる処理を提供するコン...
&br;@Component 上記3つに当てはまらないコンポーネント。ユ...
&br;@Configuration クラス宣言の前に記述します。このアノテ...
Controllerクラスに書かれている@〇〇Mappingとは
簡単に言うとSpringBootの外部からのアクションに対するプロ...
@RequestMappingは全体の処理
使い方はクラスの頭に付ける
※クラス内での@RequestMappingは避けたい@GetMappingも@PostM...
@GetMappingは取得の処理
登録しているデータを取得したりします。
@PostMappingは投稿の処理
新しいデータを登録したりします。
***画像 [#t24ee141]
base64形式のメリット
&br;base64処理を用いるメリットとしては、画像ファイルをbas...
&br;また、base64エンコードされた画像はウェブページに直接...
application.propertiesの設定
max-file-size...................................1ファイル...
&br;max-request-size ...............................(複数...
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=30MB
「org.springframework.web.multipart.multipartfile」というイ...
import org.springframework.web.multipart.MultipartFile;
import lombok.Data;
@Data
public class File {
private byte[] fileName;
private MultipartFile uploadFile;
}
HTML フォームの設定
「enctype="multipart/form-data"」を忘れないようにする。これ...
<form th:action="@{/upload}" method="post" enctype="m...
HTMLから受け取ったファイルの処理 controller
データベースに追加するときはbyte[]の変数からBLOB型のカラ...
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
// htmlからファイル名を受け取る 今回はjava.png
String fileName = uploadFile.getImage().getOriginalFi...
// 受け取ったファイル名(String)からbute[]に変換し、フ...
Charset charset = StandardCharsets.UTF_8;
byte[] encode = Base64.getEncoder().encode(fileName.g...
// フォルダを作成する場所を指定 ※パスは各自変更
Path path = Paths.get("");
// ファイルの転送先 + ファイル
Path transferTarget = Paths.get("" + addFileName);
try{
// 転送するフォルダの作成
Files.createDirectory(path);
// メソッドを呼び出して転送する
uploadFile.getImage().transferTo(transferTarget);
}catch(IOException e){
System.out.println(e);
}
画面に出力させる処理 controller
// データベースからファイルを受け取る
byte[] b = encodeFile.getFile_name();
// Base64形式から元の形式に(.png)に戻す
byte[] decode = Base64.getDecoder().decode(b);
// byte[]から元の文字に戻す(java.png)
Charset charset = StandardCharsets.UTF_8;
String strDecode = new String(decode,charset);
HTMLで保存してあるフォルダを指定して画像を表示させる
<img th:src = "'/images/'+${decodefile}">
*Thymeleaf [#v61b6007]
HTML5などのテンプレートエンジン
メリットとしては変数の部分を属性値で記述しているため、ブ...
&br;[[使い方はこちらを参考に:https://qiita.com/opengl-808...
*返却期限の表示 [#e02985d7]
この機能はJava Scriptを使って実現させます。
/**
* 返却期限の表示処理の内容
* 期限が過ぎた書籍の返却期限は赤色で表示します。
* 期限が過ぎていない書籍は黄色で表示します。
*/
// ページ読み込み時に実行処理
window.onload = function()
{
const elements = document.getElementsByClassName('cl...
//現在の日付を取得します
let now_date = new Date();
let comparison_date = now_date.getFullYear() + "/" +...
/* 関数の引数に書籍の返却予定日と書籍ID
HTMLのname属性には返却予定日を格納してid属性には...
function comparison(name, id)
{
// 返却期限が過ぎている時
if (new Date(comparison_date) > new Date(name))
{
let book_object = document.getElementById(id);
book_object.style.backgroundColor = '#ff2020';
}
// 返却期限が過ぎていない時
else
{
let book_object = document.getElementById(id);
book_object.style.backgroundColor = '#fff450';
}
}
// 借りている書籍の数だけ処理をする
for (let step = 0; step < elements.length; step++)
{
comparison(elements[step].name, elements[step].id);
}
}
*モーダルウィンドウ [#u84b8a83]
jQueryを使った作成方法
HTMLはこんな感じです。
<link rel="stylesheet" href="/css/****.css">
<script src="https://ajax.googleapis.com/ajax/libs/jq...
<script src="/js/****.js"></script>
<button type = "button" class = "modal-button"></butt...
<div id="modal-content">
<p>モーダルウィンドウに表示されます。</p>
</div>
CSSにはオーバーレイとモーダルの設定を書きます。
#modal-content {
width: 50% ;
height: 50% ;
margin: 0 ;
padding: 10px 20px ;
border: 2px solid #aaa ;
background: #fff ;
position: fixed ;
display: none ;
z-index: 2 ;
}
#modal-overlay {
z-index: 1 ;
display: none ;
position: fixed ;
top: 0 ;
left: 0 ;
width: 100% ;
height: 120% ;
background-color: rgba( 0,0,0, 0.75 ) ;
}
jQueryにはオーバレイとモーダルの操作を書きます。
$(function() {
$('.modal-button').click(function() {
/*キーボード操作などにより、オーバーレイが多重起動す...
ボタンからフォーカスを外す*/
$(this).blur();
//新しくモーダルウィンドウを起動しない
if ($("#modal-overlay")[0]) return false;
//オーバーレイを出現させる
$("body").append('<div id="modal-overlay"></div>');
$("#modal-overlay").fadeIn("slow");
//モーダルウィンドウをセンタリングする
centeringModalSyncer();
//モーダルウィンドウをフェードインする
$("#modal-content").fadeIn("slow");
//[#modal-overlay]をクリック
$("#modal-overlay).unbind().click(function() {
//[#modal-content]と[#modal-overlay]をフェードア...
$("#modal-content,#modal-overlay").fadeOut("slow"...
//[#modal-overlay]を削除する
$('#modal-overlay').remove();
});
});
});
//リサイズされたら、センタリングをする関数[centeringM...
$(window).resize(centeringModalSyncer);
//画面(ウィンドウ)の幅、高さを取得
const w = $(window).width();
const h = $(window).height();
//センタリングを実行する関数
function centeringModalSyncer() {
// モーダルウィンドウ(#modal-content)の幅、高...
const cw = $("#modal-content").outerWidth();
const ch = $("#modal-content").outerHeight();
//センタリングを実行する
$("#modal-content").css({ "left": ((w - cw) /...
}
});
ボタンを押してモーダルウィンドウを表示し、画面外を押して...
*Spring Security [#dc361df8]
**ログインページの作成 [#x82f74e9]
Spring Securityの依存性を注入するとアプリケーションを起動...
&br;まずは、自前で作成したログイン画面を表示させたいので
適当に作成したHTMLをcontrollerクラスのgetmappingで呼びま...
&br;次に、javaconfigで設定を行います。
設定を行うためのwebsecurityconfigクラスを作成します。この...
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configu...
import org.springframework.security.config.annotation...
import org.springframework.security.config.annotation...
import org.springframework.security.config.annotation...
import org.springframework.security.config.annotation...
import org.springframework.security.crypto.bcrypt.BCr...
import org.springframework.security.crypto.password.P...
import org.springframework.security.web.util.matcher....
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityCon...
@Override
public void configure(WebSecurity web) throws Except...
// spring securityで無視するリクエストパスを設定 / ...
web.ignoring().antMatchers("/css/**", "/images/**",...
}
@Override
protected void configure(HttpSecurity http) throw...
/*ログインページ
ログインのアクション
認証するときのパラメーター
認証成功時の遷移先
ログアウトのアクション
ログアウト成功時のURL
cookieの削除
セッションを無効にする*/
http.formLogin()
.loginPage("/login/form")
.loginProcessingUrl("/signin")
.usernameParameter("mailaddress")
.passwordParameter("password")
.defaultSuccessUrl("/mypage")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestM...
.logoutSuccessUrl("/login/form")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll();
//ログイン前に許可する処理
http.authorizeRequests()
.antMatchers("/user/add").permitAll()
.antMatchers("/login/change/password").permi...
.anyRequest().authenticated();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
ハッシュ化の方式はbcryptpasswordencoderを用いたいのでbcry...
ここまで完了すると自作したログインページが表示されるよう...
**ハッシュ化 [#yed31014]
新規ユーザー作成画面からパスワードの入力フォームに入力さ...
serviceクラスにパスワードをハッシュ化するメソッドを作成し...
import org.springframework.beans.factory.annotation.A...
import org.springframework.security.crypto.password.P...
@Autowired
PasswordEncoder passwordEncoder;
public void hashPassword(String password) {
passwordEncoder.encode(password);
}
controllerにserviceで作成したメソッド呼び出し取得した文字...
&br;データベースに登録したユーザーのパスワードがハッシュ...
**ユーザー認証 [#yf911960]
userテーブルからユーザーを取得するmapperを書きます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3...
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="findUser" resultType="com.example.dem...
select user_id,user_name,mailaddress,password...
</select>
</mapper>
@Mapper
public interface UserMapper {
public Optional<User>findUser(String mailaddress);
}
ユーザーを照合するクラスを書きます。
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAutho...
import org.springframework.security.core.authority.Si...
import org.springframework.security.core.userdetails....
import lombok.Data;
@Data
public class LoginUserDetailsImpl implements UserDeta...
private User loginUser;
private Collection<GrantedAuthority>authorities;
public LoginUserDetailsImpl(User loginUser) {
this.loginUser = loginUser;
String role = null;
if(loginUser.getAdmin_flg() == 1) {
role = "ADMIN";
}else if(loginUser.getAdmin_flg() == 0) {
role = "USER";
}
this.authorities = new ArrayList<>();
this.authorities.add(new SimpleGrantedAuthority("RO...
}
@Override
public Collection<? extends GrantedAuthority> getAut...
return authorities;
}
@Override
public String getPassword() {
return loginUser.getPass();
}
@Override
public String getUsername() {
return loginUser.getUser_name();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
if(loginUser.getIsdeleted() == 1) {
return false;
}
return true;
}
}
ログイン画面から直接URL書き換えて遷移しないようにlogincon...
import org.springframework.context.annotation.Configu...
import org.springframework.web.servlet.config.annotat...
import org.springframework.web.servlet.config.annotat...
@Configuration
public class LoginConfig implements WebMvcConfigurer{
public void addViewContorllers(ViewControllerRegistr...
registry.addViewController("/login/form").setViewNa...
}
}
*junit [#u16feb79]
今回はjunit5を使ってテストしました。
調べてみるとjunit4でテストを書いているのを多く見かけるの...
[[junit5のメリット:https://parasoft.techmatrix.jp/repeati...
[[junit5のアノテーション:https://blogs.oracle.com/otnjp/m...
アノテーション
@Testはテストケースを宣言するために使用します。
@AutoConfigureMockMvcコントローラ層のモック(MockMvc)を作...
モックとは、クラスの動作を意図的に設定し、擬似的シミュレ...
@WithUserDetailsはUserDetailsServiceからユーザー情報を取...
画面テスト
//コントローラクラスのメソッド
@GetMapping("/home")
public ModelAndView index(ModelAndView mav) {
mav.setViewName("index");
return mav;
}
※コントローラクラスに画面を呼び出すメソッドをString型で作...
戻り値が文字列として認識してエラーになります。動作自体は...
テストする際はModelAndViewを使ってテストします。
//テストクラスのメソッド
@Test
public void getIndexTest() throws Exception {
mockMvc.perform(get("/home"))
.andExpect(status().isOk())
.andExpect(view().name("index"));
}
ログインとmapperのテスト
package com.example.demo;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.re...
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.A...
import org.springframework.boot.test.autoconfigure.we...
import org.springframework.boot.test.context.SpringBo...
import org.springframework.security.core.Authenticati...
import org.springframework.security.core.context.Secu...
import org.springframework.security.test.context.supp...
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import com.example.demo.mapper.EmployeeMapper;
import com.example.demo.model.Employee;
@SpringBootTest
@AutoConfigureMockMvc
class ApplicationTests {
@Autowired
MockMvc mockMvc;
@Autowired
EmployeeMapper employeeMapper;
// データベースアクセス処理テスト
@Test
public void findOneTest() {
Employee e = new Employee();
e = employeeMapper.findOne("testemail@gmail.com");
assertEquals("testname", e.getName());
}
// 認証テスト
@Test
@WithUserDetails(value = "testemail@gmail.com")
public void certificationTest() throws Exception {
// 認証情報を取得
Authentication auth = SecurityContextHolder
.getContext().getAuthentication();
String message = "class = " + auth.getClass() + "\n...
"name = " + auth.getName() + "\n" +
"credentials = " + auth.getCredentials() + "\n" +
"authorities = " + auth.getAuthorities() + "\n" +
"principal = " + auth.getPrincipal() + "\n" +
"details = " + auth.getDetails();
// 今回は確認のために標準出力しているだけ(ここまで...
System.out.println(message);
// モックを使用してテスト対象のURL(ログイン成功画面...
MvcResult mvcResult = mockMvc.perform(get("/home/vi...
// ユーザ認証許可する設定のためアクセス可能であるこ...
assertEquals("homepage", mvcResult.getModelAndView(...
}
}
終了行:
[[FrontPage]]
&size(20){目次};
#contents(level=1)
*スケジュール作成サンプル [#i6862607]
#ref(./EL-BOOK ワークフロー サンプル.xlsx,80%);
*コーディング作業が楽になるショートカットの一覧 [#i6862607]
[[Windows:https://dekiru.net/article/18619/]]
[[Eclipse:https://www.casleyconsulting.co.jp/blog/enginee...
覚えておくと良いこと
&br;ファイル保存 [Ctrl + S]
&br;全てを保存 [Ctrl + Shift + S]
&br;文字列検索 [Ctrl + F]
&br;コピー[Ctrl + C] ペースト [Ctrl + V]
&br;候補[Ctrl + Space]
*設計書作成 [#x48eecb0]
**機能一覧表 [#l9240598]
#ref(./function_list.png,80%);
**画面構成 [#c3141316]
#ref(./view.png,80%);
**テーブル定義書 [#t0ef638c]
テーブル定義書とはテーブルを作成するための設計書です。デ...
&br;
&ref(./table.png,80%);
**テスト仕様書 [#wc39b0f7]
|画面|区分1|区分2|確認項目|結果|h
|ログイン|テキストボックス|メールアドレス|文字が入力でき...
|~|~|パスワード|文字が入力できること&br();必須項目になっ...
**ER図 [#f1d67711]
[[ER図とは:https://it-koala.com/entity-relationship-diagr...
#ref(./er.png,80%);
**クラス図 [#feca588a]
#ref(./uml_line.png,80%);
&br;多重度はそのクラスのインスタンスが何個関連を持つかを...
#ref(class.png);
**シーケンス図 [#l0ee201a]
Visual Studio Codeを開きます。
左側のメニューに拡張機能があるので
PlantUMLと入力してください
&br;検索すると一番上に出てくると思うのでクリックしてイン...
インストールが終えたら
&br;左上のメニューにあるファイルから新規作成を選択してく...
Untitled-1が作成されるのでCTRL + SHIFT + S を押します。
&br;任意のファイル名を入力し、ファイルの種類をPlantUMLに...
.wsdという形式のファイルができればOKです。
下記がUMLのサンプルになります。
@startuml Update
mainframe ユーザー編集
actor User
participant "ユーザー一覧画面" as View
participant "編集モーダル" as Modal
participant "エンコード" as encode
participant "更新処理" as Update
database "データベース" as DB
alt 権限あり
User -> View : 編集したい
activate View
else 権限なし
User <-- View : エラー
end
View -> Modal : 一覧から選択する
activate Modal
Modal <-- DB : ユーザーID,変更前の名前,メールアドレス...
activate DB
Modal -> Update : 入力(名前,メールアドレス)
activate Update
Modal -> encode : 入力(パスワード)
deactivate Modal
activate encode
encode -> Update : 暗号化したパスワード
deactivate encode
Update -> DB :更新
deactivate Update
View <-- DB : 更新したユーザー情報を反映
deactivate DB
deactivate View
@enduml
&br;ALT+Dを押すとプレビューに図が表示されます。
&br;図を画像ファイルとして保存したい場合は
ファイル内で右クリックすると
ファイル内のダイアグラムをエクスポートとあるのでクリック...
&br;pngを選択するとのファイルを作成した場所にフォルダが作...
*github[#q8a7110e]
Git Hubのアカウント作成
以下のリンクから作成してください
&br;[[アカウント作成:https://github.com/]]
&br;ユーザー名とメールアドレスとパスワードを入力して登録...
無料版であるfreeを選択してContinue押して作成されます。
Git Bashのダウンロード~インストールまで
下記からサイトへ移動してDownloadボタンを押します。
Git Bashの[[ダウンロード:https://gitforwindows.org/]]
インストーラーを起動してセットアップをおこないます。
最初のウィンドウからNextを押して進みます。
&br;Git Bash Hereにチェックが付いていることを確認して
Next
&br;Use Git from the Windows Command Promptを選択して
Next
&br;Use the OpenSSL libraryを選択して
Next
&br;Checkout Windows-style,commit Unix-style line endings...
Next
&br;Use MinTTY(the default terminal of MSYS2)を選択して
Next
&br;Enable file system cachingとEnable Git Credential Man...
Next
&br;いくつかチェックボックスがありますが入れずにNextを押...
Git Bashを開いて以下のコマンドを入力してユーザーの設定を...
&br;
git config --global user.name
git config --global user.email
[[だいたい使うコマンド一覧:https://qiita.com/myalpine/ite...
*フレームワーク [#f45892c1]
**mybatis[#ea99b799]
<?xml version="1.0" encoding="UTF-8"?>
作成したxmlファイルにmybatisを使うための設定をし...
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapp...
Mapperを指定します。
<mapper namespace="com.example.demo.mapper.UserMa...
検索結果をデータ型に変換するためクラスをresul...
<select id="findUser" resultType="com.example...
select user_id,user_name from m_user;
</select>
</mapper>
parameterTypeはinsert文でvalueの値やupdateでsetする値を指...
**Spring [#b68c10c5]
[[こちらのサイト参考に:https://learning-collection.com/sp...
***アノテーション [#e5a17a0a]
&br;@RequestParam URLに含まれるクエリパラメータを受け取る...
&br;@Autowired 外部から呼び出して自動的に初期化してくれる。
&br;@PathVariable @GetMappingで指定したメソッドの引数につ...
&br;@ModelAttribute コントローラーの引数につけて使う HTM...
&br;@Data クラスに@Getter、@Setter、@RequiredArgsConstru...
&br;@Mapper Mapperを定義するために必要なアノテーション ...
&br;@Controller MVCパターンのCの役割を担うコンポーネント...
&br;@Service ビジネスロジックを実装するコンポーネントであ...
&br;@Repository データの永続化に関わる処理を提供するコン...
&br;@Component 上記3つに当てはまらないコンポーネント。ユ...
&br;@Configuration クラス宣言の前に記述します。このアノテ...
Controllerクラスに書かれている@〇〇Mappingとは
簡単に言うとSpringBootの外部からのアクションに対するプロ...
@RequestMappingは全体の処理
使い方はクラスの頭に付ける
※クラス内での@RequestMappingは避けたい@GetMappingも@PostM...
@GetMappingは取得の処理
登録しているデータを取得したりします。
@PostMappingは投稿の処理
新しいデータを登録したりします。
***画像 [#t24ee141]
base64形式のメリット
&br;base64処理を用いるメリットとしては、画像ファイルをbas...
&br;また、base64エンコードされた画像はウェブページに直接...
application.propertiesの設定
max-file-size...................................1ファイル...
&br;max-request-size ...............................(複数...
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=30MB
「org.springframework.web.multipart.multipartfile」というイ...
import org.springframework.web.multipart.MultipartFile;
import lombok.Data;
@Data
public class File {
private byte[] fileName;
private MultipartFile uploadFile;
}
HTML フォームの設定
「enctype="multipart/form-data"」を忘れないようにする。これ...
<form th:action="@{/upload}" method="post" enctype="m...
HTMLから受け取ったファイルの処理 controller
データベースに追加するときはbyte[]の変数からBLOB型のカラ...
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
// htmlからファイル名を受け取る 今回はjava.png
String fileName = uploadFile.getImage().getOriginalFi...
// 受け取ったファイル名(String)からbute[]に変換し、フ...
Charset charset = StandardCharsets.UTF_8;
byte[] encode = Base64.getEncoder().encode(fileName.g...
// フォルダを作成する場所を指定 ※パスは各自変更
Path path = Paths.get("");
// ファイルの転送先 + ファイル
Path transferTarget = Paths.get("" + addFileName);
try{
// 転送するフォルダの作成
Files.createDirectory(path);
// メソッドを呼び出して転送する
uploadFile.getImage().transferTo(transferTarget);
}catch(IOException e){
System.out.println(e);
}
画面に出力させる処理 controller
// データベースからファイルを受け取る
byte[] b = encodeFile.getFile_name();
// Base64形式から元の形式に(.png)に戻す
byte[] decode = Base64.getDecoder().decode(b);
// byte[]から元の文字に戻す(java.png)
Charset charset = StandardCharsets.UTF_8;
String strDecode = new String(decode,charset);
HTMLで保存してあるフォルダを指定して画像を表示させる
<img th:src = "'/images/'+${decodefile}">
*Thymeleaf [#v61b6007]
HTML5などのテンプレートエンジン
メリットとしては変数の部分を属性値で記述しているため、ブ...
&br;[[使い方はこちらを参考に:https://qiita.com/opengl-808...
*返却期限の表示 [#e02985d7]
この機能はJava Scriptを使って実現させます。
/**
* 返却期限の表示処理の内容
* 期限が過ぎた書籍の返却期限は赤色で表示します。
* 期限が過ぎていない書籍は黄色で表示します。
*/
// ページ読み込み時に実行処理
window.onload = function()
{
const elements = document.getElementsByClassName('cl...
//現在の日付を取得します
let now_date = new Date();
let comparison_date = now_date.getFullYear() + "/" +...
/* 関数の引数に書籍の返却予定日と書籍ID
HTMLのname属性には返却予定日を格納してid属性には...
function comparison(name, id)
{
// 返却期限が過ぎている時
if (new Date(comparison_date) > new Date(name))
{
let book_object = document.getElementById(id);
book_object.style.backgroundColor = '#ff2020';
}
// 返却期限が過ぎていない時
else
{
let book_object = document.getElementById(id);
book_object.style.backgroundColor = '#fff450';
}
}
// 借りている書籍の数だけ処理をする
for (let step = 0; step < elements.length; step++)
{
comparison(elements[step].name, elements[step].id);
}
}
*モーダルウィンドウ [#u84b8a83]
jQueryを使った作成方法
HTMLはこんな感じです。
<link rel="stylesheet" href="/css/****.css">
<script src="https://ajax.googleapis.com/ajax/libs/jq...
<script src="/js/****.js"></script>
<button type = "button" class = "modal-button"></butt...
<div id="modal-content">
<p>モーダルウィンドウに表示されます。</p>
</div>
CSSにはオーバーレイとモーダルの設定を書きます。
#modal-content {
width: 50% ;
height: 50% ;
margin: 0 ;
padding: 10px 20px ;
border: 2px solid #aaa ;
background: #fff ;
position: fixed ;
display: none ;
z-index: 2 ;
}
#modal-overlay {
z-index: 1 ;
display: none ;
position: fixed ;
top: 0 ;
left: 0 ;
width: 100% ;
height: 120% ;
background-color: rgba( 0,0,0, 0.75 ) ;
}
jQueryにはオーバレイとモーダルの操作を書きます。
$(function() {
$('.modal-button').click(function() {
/*キーボード操作などにより、オーバーレイが多重起動す...
ボタンからフォーカスを外す*/
$(this).blur();
//新しくモーダルウィンドウを起動しない
if ($("#modal-overlay")[0]) return false;
//オーバーレイを出現させる
$("body").append('<div id="modal-overlay"></div>');
$("#modal-overlay").fadeIn("slow");
//モーダルウィンドウをセンタリングする
centeringModalSyncer();
//モーダルウィンドウをフェードインする
$("#modal-content").fadeIn("slow");
//[#modal-overlay]をクリック
$("#modal-overlay).unbind().click(function() {
//[#modal-content]と[#modal-overlay]をフェードア...
$("#modal-content,#modal-overlay").fadeOut("slow"...
//[#modal-overlay]を削除する
$('#modal-overlay').remove();
});
});
});
//リサイズされたら、センタリングをする関数[centeringM...
$(window).resize(centeringModalSyncer);
//画面(ウィンドウ)の幅、高さを取得
const w = $(window).width();
const h = $(window).height();
//センタリングを実行する関数
function centeringModalSyncer() {
// モーダルウィンドウ(#modal-content)の幅、高...
const cw = $("#modal-content").outerWidth();
const ch = $("#modal-content").outerHeight();
//センタリングを実行する
$("#modal-content").css({ "left": ((w - cw) /...
}
});
ボタンを押してモーダルウィンドウを表示し、画面外を押して...
*Spring Security [#dc361df8]
**ログインページの作成 [#x82f74e9]
Spring Securityの依存性を注入するとアプリケーションを起動...
&br;まずは、自前で作成したログイン画面を表示させたいので
適当に作成したHTMLをcontrollerクラスのgetmappingで呼びま...
&br;次に、javaconfigで設定を行います。
設定を行うためのwebsecurityconfigクラスを作成します。この...
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configu...
import org.springframework.security.config.annotation...
import org.springframework.security.config.annotation...
import org.springframework.security.config.annotation...
import org.springframework.security.config.annotation...
import org.springframework.security.crypto.bcrypt.BCr...
import org.springframework.security.crypto.password.P...
import org.springframework.security.web.util.matcher....
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityCon...
@Override
public void configure(WebSecurity web) throws Except...
// spring securityで無視するリクエストパスを設定 / ...
web.ignoring().antMatchers("/css/**", "/images/**",...
}
@Override
protected void configure(HttpSecurity http) throw...
/*ログインページ
ログインのアクション
認証するときのパラメーター
認証成功時の遷移先
ログアウトのアクション
ログアウト成功時のURL
cookieの削除
セッションを無効にする*/
http.formLogin()
.loginPage("/login/form")
.loginProcessingUrl("/signin")
.usernameParameter("mailaddress")
.passwordParameter("password")
.defaultSuccessUrl("/mypage")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestM...
.logoutSuccessUrl("/login/form")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll();
//ログイン前に許可する処理
http.authorizeRequests()
.antMatchers("/user/add").permitAll()
.antMatchers("/login/change/password").permi...
.anyRequest().authenticated();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
ハッシュ化の方式はbcryptpasswordencoderを用いたいのでbcry...
ここまで完了すると自作したログインページが表示されるよう...
**ハッシュ化 [#yed31014]
新規ユーザー作成画面からパスワードの入力フォームに入力さ...
serviceクラスにパスワードをハッシュ化するメソッドを作成し...
import org.springframework.beans.factory.annotation.A...
import org.springframework.security.crypto.password.P...
@Autowired
PasswordEncoder passwordEncoder;
public void hashPassword(String password) {
passwordEncoder.encode(password);
}
controllerにserviceで作成したメソッド呼び出し取得した文字...
&br;データベースに登録したユーザーのパスワードがハッシュ...
**ユーザー認証 [#yf911960]
userテーブルからユーザーを取得するmapperを書きます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3...
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="findUser" resultType="com.example.dem...
select user_id,user_name,mailaddress,password...
</select>
</mapper>
@Mapper
public interface UserMapper {
public Optional<User>findUser(String mailaddress);
}
ユーザーを照合するクラスを書きます。
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAutho...
import org.springframework.security.core.authority.Si...
import org.springframework.security.core.userdetails....
import lombok.Data;
@Data
public class LoginUserDetailsImpl implements UserDeta...
private User loginUser;
private Collection<GrantedAuthority>authorities;
public LoginUserDetailsImpl(User loginUser) {
this.loginUser = loginUser;
String role = null;
if(loginUser.getAdmin_flg() == 1) {
role = "ADMIN";
}else if(loginUser.getAdmin_flg() == 0) {
role = "USER";
}
this.authorities = new ArrayList<>();
this.authorities.add(new SimpleGrantedAuthority("RO...
}
@Override
public Collection<? extends GrantedAuthority> getAut...
return authorities;
}
@Override
public String getPassword() {
return loginUser.getPass();
}
@Override
public String getUsername() {
return loginUser.getUser_name();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
if(loginUser.getIsdeleted() == 1) {
return false;
}
return true;
}
}
ログイン画面から直接URL書き換えて遷移しないようにlogincon...
import org.springframework.context.annotation.Configu...
import org.springframework.web.servlet.config.annotat...
import org.springframework.web.servlet.config.annotat...
@Configuration
public class LoginConfig implements WebMvcConfigurer{
public void addViewContorllers(ViewControllerRegistr...
registry.addViewController("/login/form").setViewNa...
}
}
*junit [#u16feb79]
今回はjunit5を使ってテストしました。
調べてみるとjunit4でテストを書いているのを多く見かけるの...
[[junit5のメリット:https://parasoft.techmatrix.jp/repeati...
[[junit5のアノテーション:https://blogs.oracle.com/otnjp/m...
アノテーション
@Testはテストケースを宣言するために使用します。
@AutoConfigureMockMvcコントローラ層のモック(MockMvc)を作...
モックとは、クラスの動作を意図的に設定し、擬似的シミュレ...
@WithUserDetailsはUserDetailsServiceからユーザー情報を取...
画面テスト
//コントローラクラスのメソッド
@GetMapping("/home")
public ModelAndView index(ModelAndView mav) {
mav.setViewName("index");
return mav;
}
※コントローラクラスに画面を呼び出すメソッドをString型で作...
戻り値が文字列として認識してエラーになります。動作自体は...
テストする際はModelAndViewを使ってテストします。
//テストクラスのメソッド
@Test
public void getIndexTest() throws Exception {
mockMvc.perform(get("/home"))
.andExpect(status().isOk())
.andExpect(view().name("index"));
}
ログインとmapperのテスト
package com.example.demo;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.re...
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.A...
import org.springframework.boot.test.autoconfigure.we...
import org.springframework.boot.test.context.SpringBo...
import org.springframework.security.core.Authenticati...
import org.springframework.security.core.context.Secu...
import org.springframework.security.test.context.supp...
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import com.example.demo.mapper.EmployeeMapper;
import com.example.demo.model.Employee;
@SpringBootTest
@AutoConfigureMockMvc
class ApplicationTests {
@Autowired
MockMvc mockMvc;
@Autowired
EmployeeMapper employeeMapper;
// データベースアクセス処理テスト
@Test
public void findOneTest() {
Employee e = new Employee();
e = employeeMapper.findOne("testemail@gmail.com");
assertEquals("testname", e.getName());
}
// 認証テスト
@Test
@WithUserDetails(value = "testemail@gmail.com")
public void certificationTest() throws Exception {
// 認証情報を取得
Authentication auth = SecurityContextHolder
.getContext().getAuthentication();
String message = "class = " + auth.getClass() + "\n...
"name = " + auth.getName() + "\n" +
"credentials = " + auth.getCredentials() + "\n" +
"authorities = " + auth.getAuthorities() + "\n" +
"principal = " + auth.getPrincipal() + "\n" +
"details = " + auth.getDetails();
// 今回は確認のために標準出力しているだけ(ここまで...
System.out.println(message);
// モックを使用してテスト対象のURL(ログイン成功画面...
MvcResult mvcResult = mockMvc.perform(get("/home/vi...
// ユーザ認証許可する設定のためアクセス可能であるこ...
assertEquals("homepage", mvcResult.getModelAndView(...
}
}
ページ名: