#Javaの基本ルール
①エディタとコンパイラ、または統合開発環境を使用する
②ソースファイルを〇〇.javaとして保存する
③コンパイルして実行ファイル(exe)を作成する
Javaのプログラムは、プロジェクトと呼ばれる単位でワンセットで管理する
■プロジェクト
○src(ソースファイル)
・〇〇.java
・〇〇.java
○ライブラリ
・〇〇.jar
・〇〇.jar
・〇〇.jar
型・変数
文字列にはcharというプリミティブ型があるが、文字列を格納できる型はない。
String(API)クラスライブラリ
割り算の注意点
代入先の変数が浮動小数点型(float,double)でも、
計算式自体が整数の場合は、小数点以下を求めることはできない。
例)
float A = 10 / 3;
System.out.printon(A);
↓
3 と表示される
計算式の前に(float)や、(double)を指定することにより、小数点以下を求めることができる。
例)
float A = (float)10 / 3;
System.out.printon(A);
↓
3.3333333 と表示される
equalメソッド
String型で定義した文字列には比較演算子が使用できないため、equalメソッドを使用する。
例)
String b = "文字列";
if(b.equals("文字列")){
System.out.println(b + "です。");
}
↓
文字列です。 と表示される
条件演算子(三項演算子)
条件によって処理内容を分けることができる演算子。
「条件式がtrueの場合、式1を実行する。
fasleの場合、式2を実行する。」
条件式 ? 式1 : 式2;
コレクションフレームワーク(List、Map、Set)
■コレクション→複数の要素の集まり。
■コレクションフレームワーク→コレクション(要素の集まり)を扱う機能
→配列みたいなものを操作できるもの
List
複数の要素の順番を保持する。配列の代わりとして利用可能。
インデックスを利用して要素にアクセスする インデックスは012345...〜
配列は宣言時に必要な個数を指定する必要があったが、Listでは後から要素数を変更することができるのが特徴。
Listを使う場合は下記のいずれかを使いインスタンス化する。
クラス | 任意の要素へのアクセス | 要素の途中追加、削除 |
---|---|---|
ArrayList | 高速 | 低速 |
LinkedList | 低速 | 高速 |
※ArrayListとLinkedListはクラスだが、Listはインターフェース
なので、
宣言の型に使用することはできるが、インスタンスの生成はできない。
あとから要素の型を変更する場合はインターフェースであるListで宣言しておいたほうが便利かもしれないが、それ以外には基本的に
ArrayList<[要素の型]> 変数名 = new ArrayList<[要素の型]>();
LinkedList<[要素の型]> 変数名 = new LinkedList<[要素の型]>();
■要素の記憶方法
変数名.add("記憶させる要素");
■要素の取得方法
変数名.get(インデックス番号)
●<[要素の型]>の書き方
<[要素の型]>をジェネリクスという(JDK1.5〜)
型を予め決めることができ、拡張For文を利用することもできる。
Map
キーと要素とのマッピングを表すデータ構造。
Listのようなインデックスの代わりに、キーで要素を識別する。
putメソッドで要素を記憶できる。
変数名.put("キー","記憶させる要素");
getメソッドで要素取得できる。(キーを引数とする)
変数名.get("キー");
containsKey 指定したキーが存在するか確認(存在する場合はtrue)
Map.containsKey(検索するキー)
Mapを使う場合は下記のいずれかを使いインスタンス化する。
クラス | nullの可否 | 順番 |
---|---|---|
HashMap | 可能 | 登録順は意識されず記憶される |
TreeMap | 可能 | 登録したキーが昇順で記憶される |
LinkedHashMap | 可能 | 登録した順番で記憶される |
Set
重複要素を持たない要素の集合。
※追加しようとする値がすでに存在する場合は取り込まれない。
重複を削除したい場合に、一旦Setにデータを入れて、すべて取り出すといった使い方が多いらしい
Setを使う場合は下記のいずれかを使いインスタンス化する。
クラス | 重複の有無 | 順番 |
---|---|---|
HashSet | 無し | 登録順は意識されず記憶される |
TreeSet | 無し | 登録したキーが昇順で記憶される |
LinkedHashSet | 無し | 登録した順番で記憶される |
Javaのデータベース接続(MySQL)
JavaとMySQLは開発者が異なり、直接接続不可のため、双方接続のためのドライバーが必要。
①JDBCドライバー(Javaとデータベースを接続するためのプログラムの集まり)
②DBConnector(Javaとデータベースを接続するために自分で作成するファイル)
java.sql.DriverManager
一連のJCBCドライバを管理するためのクラス
java.sql.Connection
データベースとの接続をするためのパッケージ
java.sql.SQLException
データベースアクセスエラー等の情報を提供するための例外
java.sql.ResultSet
データベースの結果を表すデータの表に関するインターフェース
import java.sql.Connection; //データベースとの接続をするためのパッケージ
import java.sql.DriverManager; //JDBCドライバを管理するためのクラス
import java.sql.SQLException; //データベースアクセスエラー等の情報を提供するための例外
public class DBConnector{
private static String driverName = "com.mysql.jdbc.Driver"; //driverNameにJDBCドライバーを代入
private static String url =
"jdbc:mysql://localhost/testdb?autoReconnect=true&useSSL=false"; //url指定 ?以降はオプション lodalhost=サーバー名 testdb=データベース名
private static String user = "root"; //mysqlにログインするための準備
private static String password = "root"; //mysql rootアカウントのパスワードを"root"に指定
public Connection getConnection() { //DBに接続をするためのクラス(下に出てくるAPIのgetConnectionとは別物)
Connection con = null; //初期化
try { //try〜catchは例外処理構文
Class.forName(driverName); //ドライバーをロードして使えるようにしている
con = DriverManager.getConnection(url,user,password); // 指定されたデータベースのURLへの接続を試みるメソッド(上で代入したurl、user、passwordも代入)
} catch (ClassNotFoundException e) { //try内でエラーが発生した場合、catchが受け取り、printStachTrace()でエラーに至る履歴の表示をする
e.printStackTrace() ; //ClassNotFoundException クラスが見つからないエラーの場合、スタックトレースを出力
} catch (SQLException e) {
e.printStackTrace() ; //SQLException データベース処理に関するエラーの場合、スタックトレースを出力
}
return con ;
}
}
struts
Javaで実装するMVC【Model(データ),View(画面),Controller(業務ロジック)を分離して実装しようという考え方】モデルを採用したWebアプリケーションフレームワーク
MVCモデル
大規模なWebアプリケーションの開発において、Model:処理、View:画面、Controller:司令塔のそれぞれの機能を持った各アプリケーションを分けて独立させることで、開発やメンテナンスをしやすくした開発手法
ログイン認証機能開発
設定ファイルの作成
web.xml
動的Webプロジェクト作成時自動的に作られる設定ファイルで、
サイトにアクセスした際、最初に表示するjspファイルや、
プロジェクトでStruts2を使用することを宣言できる。
<?xml version="1.0" encoding="UTF-8"?><!-- 使用するxmlのバージョンと、文字コードの宣言 -->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!-- Tomcat バージョン8で使われるヘッダー文 内容→xmls:xsi/schemaLocationが属している名前空間xsiの定義 xmlns/名前空間(同名クラスの衝突を避けるためのパッケージ的なもの)の名前の定義 xsi/先で設定した名前空間の定義内容が入っているファイル参照先 -->
<display-name>login</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file> <!-- welcome-file-listで囲まれたwelcome-fileのファイルがはじめに開かれるページになる(複数指定可能) -->
</welcome-file-list>
<filter> <!-- Webアプリケーションの中のweb.xmlを使って、フィルタに書かれてるものをアプリケーションの一部として設定する。 そのフィルタをWebアプリケーションのurlパターンや特定のサーブレットにマッピングできる -->
<filter-name>struts2</filter-name> <!-- 下のfilter-nameと同じ名前にする事により、filter-classとurl-patterをマッピング -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!--struts2の制御担当クラス-->
</filter>
<filter-mapping>
<filter-name>struts2</filter-name> <!-- 上のfilter-nameと同じ名前にする事により、filter-classとurl-patterをマッピング -->
<url-pattern>/*</url-pattern> <!-- /*で、このプロジェクトの配下全てという意味 このプロジェクト全てでstruts2を使いますという意味になる -->
</filter-mapping>
</web-app>
struts.xml
strutsフレームワークを利用する際に作成する設定ファイル
Javaの処理結果に応じて表示するjspファイルの設定を記述する。
strutsフレームワークのみで利用される設定ファイル。
<?xml version="1.0" encoding="UTF-8"?><!-- 使用するxmlのバージョンと、文字コードの宣言 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"><!-- struts2.3以降のバージョンの設定であることの記述 -->
<struts>
<constant name = "struts.devMode" value = "true" /> <!-- Struts2の挙動を制御(開発者が使用しやすく)する設定 具体的にはエラーを知らせてくれるようなデバッグ機能を発揮してくれるようになる。 -->
<package name = "com.login.action" extends = "struts-default"> <!-- name属性には”このプロジェクトのActionファイルが含まれるパッケージを書く” extendsで、デフォルトのstruts-defaoult(struts2が持っているstruts-default.xmlのことで、ActionSupportクラスはここに入っている)定義を継承-->
<action name = "LoginAction" class = "com.login.action.LoginAction" method = "execute"> <!-- name属性には”アクション名”、class属性には”具体的なクラス名”をパッケージ名から記述、method属性には”アクションが呼び出されたとき、最初に自動的に実行されるメソッド名(executeとつけるのが慣例) -->
<result name = "success">loginSuccess.jsp</result> <!-- Actionの結果、次に表示する画面の設定。(executeメソッドの戻り値で判断) -->
<result name = "error">loginError.jsp</result> <!-- Actionの結果、次に表示する画面の設定。(executeメソッドの戻り値で判断) -->
</action>
</package>
</struts>
DBConnecterの作成
データベースへ接続するために
・DBの場所
・DBの名前
・接続するユーザー名
・パスワード
などを設定するDBConnecterクラスを作成する
package com.login.util;//packageの宣言
import java.sql.Connection;//データベースとの接続をするためのパッケージ
import java.sql.DriverManager;//JDBCドライバを管理するためのクラス
import java.sql.SQLException;//データベースアクセスエラー等の情報を提供するための例外
public class DBConnector {
private static String driverName = "com.mysql.jdbc.Driver"; //driverNameにJDBCドライバーを代入
private static String url = "jdbc:mysql://localhost/logindb_makita"; //urlに、接続先のデータベース名を代入
private static String user = "root"; //userにmysqlのユーザー名を代入
private static String password = "root"; //passwordにmysqlのパスワードを代入
public Connection getConnection() {//DBに接続するためのメソッド
Connection con = null;//Connection型のconの初期化
try {
Class.forName(driverName);//JDBCドライバーをロードして使う準備をしているらしい
con = (Connection) DriverManager.getConnection(url,user,password);//指定したデータベースへの接続 結果をconへ代入
}catch(ClassNotFoundException e) {//try内でエラーが発生した場合、catchが受け取り、printStachTrace()でエラーに至る履歴の表示をする
e.printStackTrace();//ClassNotFoundException クラスが見つからないエラーの場合、スタックトレースを出力
}catch(SQLException e) {
e.printStackTrace();//SQLException データベース処理に関するエラーの場合、スタックトレースを出力
}
return con;//DBに接続した結果をconで返す
}
SQLファイルの準備
set names utf8;/*文字コードの設定 ※SQLコンソールからの指定は良いが、アプリケーションから使用するとSQLインジェクションに脆弱になる場合があるらしい。この記述は良いのか?*/
set foreign_key_checks = 0;/*複数テーブル間でデータの整合性を保つための「外部キー制約」を無効にする設定 今回は外部キー制約をそもそも設定していないが記述している*/
drop database if exists logindb; /*もし、データベースlogindbがあったらそれを削除*/
create database logindb;/*logindbの作成*/
use logindb;/*logindbを使う*/
create table user(/*logindbに各カラムを作る*/
id int,
user_name varchar(255),
password varchar(255)
);
insert into user values/*logindbに各データを入れる*/
(1, "taro", "123"),
(2, "jiro", "123"),
(3, "hanako", "123"),
(4, "saburo", "123");
mysql> use logindb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------------------+
| Tables_in_logindb |
+--------------------------+
| user |
+--------------------------+
1 row in set (0.00 sec)
mysql> select * from user;
+------+-----------+----------+
| id | user_name | password |
+------+-----------+----------+
| 1 | taro | 123 |
| 2 | jiro | 123 |
| 3 | hanako | 123 |
| 4 | saburo | 123 |
+------+-----------+----------+
4 rows in set (0.00 sec)
クラスファイルの作成
DTOクラスの作成
DTOクラス(DatabaseTransferObject)は、DAOが取得した値をActionへ戻す際、値を格納するためのクラス
必要なデータのテーブル上のカラム名に対応したフィールド変数及びgetter/setterで構成する
package com.login.dto;//packageの宣言
public class LoginDTO { //DTO = Database Transfer Object
private int id;//idカラムに対応する変数の宣言
private String name;//nameカラムに対応する変数の宣言
private String password;//passwordカラムに対応する変数の宣言
public int getID() {//idのgetter
return id;
}
public void setId(int id) {//idのsetter
this.id = id;
}
public String getName() {//nameのgetter
return name;
}
public void setName(String name) {//nameのsetter
this.name = name;
}
public String getPassword() {//passwordのgetter
return password;
}
public void setPassword(String password) {//passwordのsetter
this.password = password;
}
}
DAOクラスの作成
Actionから送られてきた情報を使ってDBへ問い合わせを行う
DBへ問い合わせて取得した値をDTOクラスに格納する
package com.login.dao;//packageの宣言
import java.sql.Connection;//データベースとの接続をするためのパッケージ
import java.sql.PreparedStatement;//実行するSQL文を格納するオブジェクト
import java.sql.ResultSet;//データベースの結果を表す表オブジェクト
import java.sql.SQLException;//データベースアクセスエラー等の情報を提供するための例外
import com.login.dto.LoginDTO;//LoginDTO.javaのインポート
import com.login.util.DBConnector;//DBConnector.javaのインポート
public class LoginDAO {
public LoginDTO select(String name, String password)throws SQLException{//Login.jsp→LoginActionから渡された引数name、passwordを扱うselectメソッド
LoginDTO dto = new LoginDTO();//データベースへアクセスした結果を格納するLoginDTOインスタンスを生成
DBConnector db = new DBConnector();//データベースに接続するためのフィールドとメソッドを持ったインスタンスの生成
Connection con = db.getConnection();//データベースへの接続を実際に行うクラスをconに代入
String sql = "select * from user where user_name=? and password=?";//データを取得するsql文の作成
try {
PreparedStatement ps = con.prepareStatement(sql);//sql文を表すPreparedStatement型のpsに、上記sql文の代入
ps.setString(1,name);//sql文の1つ目の?(プレースホルダー)にnameをセット
ps.setString(2, password);//sql文の2つ目の?(プレースホルダー)にpasswordをセット
ResultSet rs = ps.executeQuery();//sql文の実行(結果はResultSet型のrsに入る)
if(rs.next()) {//実行結果の1行次、つまりカラム名の次に実データが入っている場合、
dto.setName(rs.getString("user_name"));//dtoのnameのセッターにrs.getStringでuser_nameを格納
dto.setPassword(rs.getString("password"));//dtoのpassordのセッターにrs.getStringでpasswordを格納
}
}catch(SQLException e) {
e.printStackTrace();
}finally {
con.close();//データベースとの接続を終了させる
}
return dto;
}
}
Actionクラスの作成
ユーザーにより画面から送られてきたリクエストを取得する
処理内容に応じてDAOやDTOクラスを呼び出し、最終的に次のJSPへ値を返す
package com.login.action;//packageの宣言
import java.sql.SQLException;//データベースアクセスエラー等の情報を提供するための例外
import com.login.dao.LoginDAO;//LoginDAOクラスのインポート
import com.login.dto.LoginDTO;//LoginDTOクラスのインポート
import com.opensymphony.xwork2.ActionSupport;//struts2が提供するActionSupportクラスをインポート
public class LoginAction extends ActionSupport{//ActionSupportクラスを継承してログインクラスの定義
private String name;//jspファイルから受け取る値の定義 ※jspでの定義と変数名を合わせる
private String password;//jspファイルから受け取る値の定義 ※jspでの定義と変数名を合わせる
public String execute() throws SQLException{//ActionSupportクラスのexecuteメソッドのオーバーライド
String ret = ERROR;//戻り値retに初期値ERRORを代入 ERRORはActionSupportが実装しているActionインターフェースに定義されている定数ERROR=“error”
LoginDAO dao = new LoginDAO();//データベースアクセス担当クラスLoginDAOをインスタンス化
LoginDTO dto = new LoginDTO();//データベースから取得した値を返すクラスLoginDTOをインスタンス化
dto = dao.select(name, password);//dao.selectでデータベースにアクセス(login.jspから送られたname、passwordを引数)して、結果をdtoに代入
if(name.equals(dto.getName())) {//login.jspから送られてきたnameとデータベースから取得したnameが正しい場合、
if(password.equals(dto.getPassword())){//login.jspから送られてきたpasswordとデータベースから取得したpasswordが正しい場合、
ret = SUCCESS;//戻り値retにSUCCESSを代入する SUCCESSはActionSupportが実装しているActionインターフェースに定義されている定数SUCCESS=“success”
}
}
return ret;//actionの結果に"error"か"success"を代入 struts.xmlで次に遷移するページを判断する。
}
public String getName() {//nameのgetter
return name;
}
public void setName(String name) {//nameのsetter
this.name = name;
}
public String getPassword() {//passwordのgetter
return password;
}
public void setPassword(String password) {//passwordのsetter
this.password = password;
}
}
※getter/setterは、どの作成ファイルからも呼び出されていないが、
struts2では、jspファイルとActionクラス間で値をやり取りする際に、
ValueStackという値の保管庫を経由する。Actionクラス内に、リクエストパラメタ(値)と同名で
getter/setterメソッドを記述しておけば、
自動的にgetter/setterは実行される
JSPの作成
ブラウザに表示される画面
・login.jsp:name及びpasswordの入力画面
・loginSuccess.jsp:ログインに成功した際に遷移する画面
・loginError.jsp:ログインに失敗した際に遷移する画面
の3つを作成する
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><!-- ページの設定 -->
<%@ taglib prefix="s" uri="/struts-tags" %><!-- struts2のカスタムタグ(s:formとか)を使えるようにしている -->
<!-- HTMLは、バージョンごとにそのバージョンで使用できる要素(タグ)や属性の名前と、それらの配置のしかたについて厳密に定義されている。 これはDTD(Document Type Definition)と呼ばれるもので、「文書型の定義」を意味する。 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><!-- Transitional DTDのバージョンを宣言
非推奨要素や属性は使用できるが、フレーム(frame)を使用することができない。 要素の配置については比較的制限が緩やか。 -->
<html>
<head>
<meta charset = "UTF-8">
<title>ログイン画面</title>
</head>
<body>
<s:form action = "LoginAction"><!-- s:formタグで囲まれた情報が、struts.xmlのactionタグ内のname属性LoginActionで指定したactionクラスに渡される -->
<s:textfield name = "name"/><!-- "name"と同名のactionクラスのフィールドに情報を渡す ※ブラウザでは<imput type="text" name="name">と認識される-->
<s:password name = "password"/><!-- "password"と同名のactionクラスのフィールドに情報を渡す ※ブラウザでは<imput type="password" name="password">と認識される-->
<s:submit value = "ログイン"/><!-- ブラウザでは<imput type="submit" value="ログイン">と認識される -->
</s:form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>ログイン成功画面</title>
</head>
<body>
<h1>ログインに成功しました。</h1>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>ログイン失敗画面</title>
</head>
<body>
<h1>ログインに失敗しました。</h1>
</body>
</html>
ログイン認証機能開発
1.ログイン認証機能
①ログイン画面からID、パスワード情報を入力し、データベースに格納されたユーザー情報を検索
入力情報と同じ情報が存在した場合はログイン認証成功、次の画面へ遷移
入力情報と同じ情報が存在しない場合はログイン認証失敗、ログイン画面へ戻す
2.ユーザー登録機能
ログイン認証を通過するためのユーザー情報をデータベースに格納する
画面項目に従って情報を入力し、サービスに登録させる
3.商品購入機能
商品情報画面に表示されている購入ボタンを押下することで、対象の商品を購入できる
購入する商品情報が表示される
4.購入履歴機能
購入した商品の履歴情報を確認でき、ユーザーが任意に購入履歴を削除することができる
複数の商品を購入した場合は、一覧で履歴が表示される
プロパティ
ここでいきなり初歩的な話
プロパティとはメンバ変数の値の取得や変更を行うためのメソッド(アクセサー)のこと。
つまりgetter/setterのこと。
なのでjspファイルで<s:property value="">でvalueに書いたプロパティにアクセスしてメンバ変数の値を取ってこれる。
様々なクラスやメソッドとその使い方
ファイルやファイル属性等にアクセスするためのクラスやインターフェースを定義したパッケージ java.nio.fileのクラス
Pathインターフェース
ファイルを特定するために、ファイルパスを表すためのオブジェクト
resolve(String other(パス文字列))
パス文字列をpathに変換して返す
Pathsクラス
パス文字列またはURIを変換してPathを返すためのクラス
Filesクラス
ファイルやディレクトリを操作するメソッドで構成されるクラス
get(String first(パス文字列), String...more)
一つのパス文字列もしくは、連結すると1つのパス文字列になる文字列をPathに変換して返す
copy(Path(source), Path(target), CopyOption(options...))
ソースパスのファイルをターゲットのパスにコピーする
入出力エラーが発生した場合は、IOExceptionを投げる。
私が使用した時はFileAlreadyExistsException(コピー先に同じファイル名が既に存在している場合に投げられる例外)が出て苦労した。
既にある同じファイル名と置換する場合はREPLACE_EXISTINGオプションをつける。
Path source = /...
Path target = /...
Files.copy(source, target.resolve(source.getFileName());