2018.12.16 補足: 本記事では「Tomcatプロジェクト」を使って作成してますが、あとあとを考えると「Mavenプロジェクトでmaven-archetype-webapp
を指定」して作るのがよいです。 (あるいは「動的Webプロジェクト」で)
参考
何番煎じかわからない内容だけど、社内の入門向けJava勉強会で少しかじったのでその復習&予習に。
(あと、ちょっとした環境構築後にwebアプリ+DBなアプリケーションを動かすときのネタがあればいろいろはかどるかな、と)
- 開発環境はPleiades Java Full Edition
- MySQLは別途構築 -> MySQL 8.0をWindows10へzipでインストール - Qiita
- Java-MySQLの接続はMavenを使ってJDBCをインストール
各バージョン
- Pleiades: Eclipse 4.6 Neon 3 Java Full Edition
- Java 1.8
- Tomcat 8.0.x
- MySQL 8.0.13
- MySQL Connector/J: 8.0.13
今どきならいろいろなフレームワークを使って開発するものだけど、プリミティブなところでどんな実装や処理をするのかを見てみたいので、ここでは素のJSP+Servletでやってます。
Tomcatプロジェクト作成
Java | Tomcatプロジェクト
を作成
プロジェクト名はmemoapp
コンテキスト名は(デフォルトの)/memoapp
※ コンテキスト名はwebアクセス時のURLに使用される
これでプロジェクトが作成される
メイン画面のUIと処理部分を作成する
JSPファイルの作成
UI部分のJSPファイルを作成する。
Eclipseの新規作成メニューからJSPファイルを選択。
作成フォルダはWEB-INF/jsp
を選択(なければ手動入力すれば作成される)
ファイル名はわかりやすく。
テンプレートは「新規JSPファイル(html)」を選択
これでJSPファイルが作成される
<title>
を編集して<h1>
でページタイトルを追加
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Memo App</title>
</head>
<body>
<h1>memo app</h1>
</body>
</html>
サーブレットの作成
作成したJSPとデータをやり取りする処理を行うサーブレットのクラスを作成する。
※ 新規作成メニューに「サーブレット」があるが、「動的Webプロジェクト」で作成したプロジェクトだけが対象っぽくて使用できないので、普通にJavaクラスの作成で作る。
自動生成時のソースはクラス定義のみでコンストラクタとかも何もないけど、以下のようにdoGet()
を定義する。(GETリクエストがあった際に呼ばれるメソッドを作成)
package jp.example.org;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/")
public class MemoAppMain extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String view = "/WEB-INF/jsp/index.jsp";
RequestDispatcher dispatcher = req.getRequestDispatcher(view);
dispatcher.forward(req, resp);
}
}
doGet()
では、/WEB-INF/jsp/index.jsp
にあるJSPファイルを読み込み、フォワード処理を使ってJSPの内容をブラウザで表示させる。
なお、Servletの画面遷移にはフォワードとリダイレクトがあるそうな: リダイレクトとフォワードの違いを知る:JavaTips ~JSP/サーブレット編 - @IT
これでTomcatを起動し、「コンテキスト定義を更新」すると、ブラウザからアクセスしたときにJSPの内容が表示されるはず。
メモの入力処理の作成
JSPで入力フォーム作成
これは普通にhtmlのformタグで。
ざっくりとこんな感じで。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Memo App</title>
</head>
<body>
<h1>memo app</h1>
<form method="post">
<input type="text" name="title" size="50"/>
<br/>
<textarea rows="5" cols="80" name="memo"></textarea>
<br/>
<input type="submit"/>
</form>
</body>
</html>
通常だとformタグにはaction
属性で、入力データの送信先を記述するが、今回は自分自身へpostする作りにするため省略
表示すると(なんの装飾もないため)こんな感じ。
(Bootstrapとかでなんとかしたいですね…)
Servletでpostされたデータを受け取る
JSPで記述したformにactionを書かなかったので、post先は自分自身になる。
つまり、すでに作成済みのMemoAppMain
クラス内に、POSTの受け取り処理を作ればよい。
MemoAppMain
には作成済みのGETリクエストを処理するdoGet()
があるが、これと同じようにPOSTリクエストを処理するdoPost()
を作成する。
とりあえずこんな感じ
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
System.out.println("title: " + req.getParameter("title"));
System.out.println("memo: " + req.getParameter("memo"));
// -- ここにDBへ保存処理 --
resp.sendRedirect(".");
}
このメソッドは、POSTリクエストがあるとコールされる。
POST時のパラメータ(HTTPリクエスト)は、名前の通りreq
オブジェクトにセットされており、getParameter(String)
でアクセスできる。
このgetParameter(String)
で指定する文字列の"title"と"memo"は、html formのフォーム名の文字列。
今はまだPOSTされたテキストデータにアクセスしているだけなので、これをDBに保存する処理を作成する。
setCharacterEncoding("UTF-8");
は文字化け対策。
参考: 日本語パラメータの対応(setCharacterEncoding) - リクエスト情報の取得 - サーブレット入門
保存処理が終わったら画面を自分へリダイレクトするためにsendRedirect(".");
をコールして、再読み込みしている。
Todo: Tomcatの起動・終了と、この時点でのアプリの動作を説明してない
DB接続処理
MySQLを使用します。
フォームに入力されたデータをDB保存するための処理を作成する。
その前に、まずはJavaアプリケーションからDB操作を行うための、JDBCのセットアップを行う。
JDBCの設定(JDBCドライバのアプリケーションへの組み込み)は手動でもできるけど、ここではMavenを使って導入する。
Mavenは…ググってね♡
TomcatプロジェクトをMavenに変換する
プロジェクトの右クリックメニューから[構成]->[Mavenプロジェクトへ変換]を選択
新規POMの作成ダイアログが表示される。内容はデフォルトのままで[完了]でOK
すると、pom.xmlファイル(と出力用target
ディレクトリ)が生成される。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>memoapp</groupId>
<artifactId>memoapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>WEB-INF/src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source/>
<target/>
</configuration>
</plugin>
</plugins>
</build>
</project>
また、Mavenプロジェクトへ変換すると、JREのバージョンやビルド先など、いくつかの設定が書き換えられるので修正する
出力フォルダの修正
プロジェクトのプロパティの[Javaのビルドパス]の[ソース]タブで、「デフォルト出力フォルダー」が[/target/classes]になっているので、[参照]ボタン押下して[/WEB-INF/classes]に変更する
デフォルト値を変更したら、[ビルド・パス上のソース・フォルダー]のリストから/WEB-INF/srcの出力フォルダーを選択して[編集]を押下
出力フォルダの設定を「プロジェクトのデフォルト出力フォルダー」に設定
JREの変更
設定を更新すると、変更前のファイルの削除確認がされるので、[はい]で削除する
もしwork
以下に見覚えのないファイルが生成された場合は、それも削除してよい
JDBCの導入
Mavenリポジトリにブラウザでアクセスし、必要なファイルを探す。
Maven Repository: Search/Browse/Explore
今回はmysql jdbc
で検索。
すると、[MySQL Connector/J]がヒットするのでリンクを開く
https://mvnrepository.com/artifact/mysql/mysql-connector-java
リンクを開くとバージョン一覧が表示されるので、基本的にはMySQLのバージョンと同じものを選択する。今回は、MySQL 8.0.13を使用しているので、同じバージョンを選択。
リンク先にソースの記述例が記載されている。この[Maven]タブで表示されている内容を、プロジェクトのpom.xml
ファイル内の<dependencies>~</dependencies>
の中へ転記する。
ただし、Mavenプロジェクトへの変換直後など、初期状態では<dependencies>
タグが存在しないので、(手動で記述するか)依存関係タブからUIで入力する。
依存関係の選択ダイアログに以下の通りにMavenのサイトで表示されていた値を入力して[OK]押下する
と、mysql-connector-javaが追加されるので、ファイルを保存する。
保存すると同時に必要ファイル類のダウンロードとビルドが開始され、ビルド完了するとプロジェクト構成も「Maven依存関係」などのファイルの追加などが行われる
この時点でpom.xmlの内容はこんな感じ
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>memoapp</groupId>
<artifactId>memoapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>WEB-INF/src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source/>
<target/>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
</dependencies>
</project>
データベースとユーザの作成
アプリケーションで使用するDBとユーザを作成する。
これはTomcatやJava関係なく、MySQL上で実施する。
C:\Users\zaki>mysql -u root -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.13 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> create database memoapp_db;
Query OK, 1 row affected (0.06 sec)
mysql> create user memoapp identified by "memoapp";
Query OK, 0 rows affected (0.13 sec)
mysql> grant all on memoapp_db.* to memoapp;
Query OK, 0 rows affected (0.03 sec)
mysql>
JavaからDB接続
// -- ここにDBへ保存処理 --
Connection con = null;
Statement smt = null;
String url = "jdbc:mysql://localhost:3306/memoapp_db";
String user = "memoapp";
String pass = "memoapp";
try {
con = DriverManager.getConnection(url, user, pass);
smt = con.createStatement();
System.out.println("smt: " + smt);
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// -- ここまでDB処理 --
これでformからデータ登録しようとしても例外が発生する
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/memoapp_db
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at jp.example.org.MemoAppMain.doPost(MemoAppMain.java:44)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
:
:
これは、Eclipse上でのビルドのタイミングではMavenで導入したJDBCのjarファイルを参照できているため問題ないが、Tomcatでの実行時にはJDBCのjarファイルのパスは設定されないため。
プロジェクトのプロパティでTomcatの設定の「開発用クラスローダーのクラスパス」画面で[Use SMART! Maven classpath]にチェックすれば、Mavenのライブラリ類もTomcat実行時に参照してくれる……?
と思ったんだけど、Tomcatがエラーこいてmemoappを動作してくれない
重大: Begin event threw exception [土 12 01 13:38:19 JST 2018]
重大: Parse error in context.xml for /memoapp [土 12 01 13:38:19 JST 2018]
重大: 2行の126列目で発生しました [土 12 01 13:38:19 JST 2018]
重大: 前のエラーのためにこのアプリケーションは利用できないようにマークします [土 12 01 13:38:19 JST 2018]
重大: One or more components marked the context as not correctly configured [土 12 01 13:38:19 JST 2018]
重大: 以前のエラーのためにコンテキストの起動が失敗しました [/memoapp] [土 12 01 13:38:19 JST 2018]
ちなみにこの設定を行ってコンテキスト定義を更新するとmemoapp.xmlはこんな感じ
<Context path="/memoapp" reloadable="true" docBase="C:\Users\zaki\src\2018b-java-study\memoapp" workDir="C:\Users\zaki\src\java-study\memoapp\work" >
<Loader className="org.apache.catalina.loader.DevLoader" reloadable="true" debug="1" useSystemClassLoaderAsParent="false" />
</Context>
調べてみると「Tomcatプラグインに含まれるDevLoader.zip
ファイルをTOMCAT_HOME/server/libへjarにリネームしてコピーする」という情報が散見される
2018.12時点でのEclipse Tomcat Plugin 9.13では、DevLoader.zipファイルは直接含まれていなくて、net.sf.eclipse.tomcat_9.1.3.jar
ファイルの中にある(わかりにくい!)
jarファイルは実体はzipなので、拡張子をリネームして展開して、中に入っているDevloaderTomcat7.jar
を……あれ?Tomcat7しかないの?
このファイル実際に使ってみても、Tomcat8では動かなかった
重大: Begin event threw error [土 12 01 14:48:25 JST 2018]
重大: ContainerBase.addChild: start: [土 12 01 14:48:25 JST 2018]
重大: 設定記述子 C:\pleiades\pleiades\tomcat\8\conf\Catalina\localhost\memoapp.xml を配備中のエラーです [土 12 01 14:48:25 JST 2018]
EclipseのTomcatプラグイン内に必要なファイルはなさそうなので、ネットからダウンロードする。
https://sourceforge.net/projects/tomcatplugin/files/additional/
↑
なんかつながらない…
ので、こちらから。
https://github.com/his-eg/tomcatplugin/blob/master/net.sf.eclipse.tomcat/DevLoaderTomcat8.jar
このファイルをTomcatのlibディレクトリへコピーする。(Pleiadesの場合はpleiades\tomcat\8\lib\DevloaderTomcat7.jar
あたり)
これでTomcatを再起動すれば動作するはず…が、まだ同じエラーが出る
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/memoapp_db
(想像)このエラーは、実行の時点ではDevLoaderがどのクラスをロードするか決定されておらず、jdbcのjarがないと実行できないDriverManager.getConnection()
に失敗している。
なので直前にjdbcのjarをロードする処理を行えばよい。
そこでClass.forName("com.mysql.cj.jdbc.Driver");
を行う
// -- ここにDBへ保存処理 --
Connection con = null;
Statement smt = null;
//String url = "jdbc:mysql://localhost:3306/memoapp_db?useSSL=false&useUnicode=true&serverTimezone=UTC";
String url = "jdbc:mysql://localhost:3306/memoapp_db";
String user = "memoapp";
String pass = "memoapp";
try {
Class.forName("com.mysql.cj.jdbc.Driver");
con = DriverManager.getConnection(url, user, pass);
smt = con.createStatement();
System.out.println("smt: " + smt);
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
finally {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// -- ここまでDB処理 --
というわけでDB接続部分のコードはこんな感じ。
サンプルコードによく出てくるforName()
の引数のクラス名は、現バージョンはFQCNが変更されていて「com.mysql.cj.jdbc.Driver」になっているので注意(cjが追加されてる)
それと、開発用クラスローダーのクラスパス、org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER
を追加する必要があった
余談だけどこのDB接続の完了にたどり着くまで1週間かかりますた…
※ スマートじゃないけどTomcatのライブラリ用のlib
ディレクトリ以下に直接mysql-connector-java-8.0.13.jar
とprotobuf-java-3.6.1.jar
をコピーするとEclipse側の設定は何もなくても動く。
DB操作
MySQLの操作のかんたんなまとめはこちらへどうぞ。
[(ゆるりと更新) MySQL / SQLメモ](Qiita https://qiita.com/zaki-lknr/items/4d330b64e1d8cdd9ce59)
テーブルの設計と作成
サンプルなのでシンプルに
field | type | size | not null | comment | etc |
---|---|---|---|---|---|
memo_id | int | 11 | ✓ | ID | auto_increment |
category | int | 11 | カテゴリ | ||
title | varchar | 64 | タイトル | ||
memo | text | メモ | |||
create_date | datetime | 作成日 | |||
modified_date | datetime | 更新日 |
テーブルを作成するSQLの作成
create table if not exists memo_data (
memo_id INT(11) auto_increment not null comment 'ID',
category INT(11) comment 'カテゴリ',
title VARCHAR(64) comment 'タイトル',
memo TEXT comment 'メモ',
create_date DATETIME comment '作成日',
modified_date DATETIME comment '更新日',
primary key (memo_id)
)
テーブルを作成するためのJavaコード(ちょっと適当だけど)
con = DriverManager.getConnection(url, user, pass);
smt = con.createStatement();
System.out.println("smt: " + smt);
String create_table = "create table if not exists memo_data (" +
"memo_id INT(11) auto_increment not null comment 'ID'," +
"category INT(11) comment 'カテゴリ'," +
"title VARCHAR(64) comment 'タイトル'," +
"memo TEXT comment 'メモ'," +
"create_date DATETIME comment '作成日'," +
"modified_date DATETIME comment '更新日'," +
"primary key (memo_id)" + ")";
// create table
smt.executeUpdate(create_table);
これで実行すればテーブルが作成される
mysql> show tables;
+----------------------+
| Tables_in_memoapp_db |
+----------------------+
| memo_data |
+----------------------+
1 row in set (0.01 sec)
mysql> describe memo_data;
+---------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+----------------+
| memo_id | int(11) | NO | PRI | NULL | auto_increment |
| category | int(11) | YES | | NULL | |
| title | varchar(64) | YES | | NULL | |
| memo | text | YES | | NULL | |
| create_date | datetime | YES | | NULL | |
| modified_date | datetime | YES | | NULL | |
+---------------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
mysql>
メモの保存処理
doPost()
のメソッドでreq.getParameter("title")
とreq.getParameter("memo")
で参照できるform入力データをテーブルに保存する処理を作成する。
String form_title = req.getParameter("title");
String form_memo = req.getParameter("memo");
と変数に取得しておいて、INSERT文は以下のような感じで。
insert into memo_data (
category, title, memo, create_date, modified_date
) values (
0,
form_title,
form_memo,
cast(now() as datetime),
cast(now() as datetime)
);
レコードを保存するJavaコード
con = DriverManager.getConnection(url, user, pass);
smt = con.createStatement();
String form_title = req.getParameter("title");
String form_memo = req.getParameter("memo");
System.out.println("title: " + form_title);
System.out.println("text: " + form_memo);
String insert_memo = "insert into memo_data (" +
"category, title, memo, create_date, modified_date" +
") values (" +
"0," +
"'" + form_title + "'," +
"'" + form_memo + "'," +
"cast(now() as datetime)," +
"cast(now() as datetime) " +
");";
// レコード保存
smt.executeUpdate(insert_memo);
これでブラウザからテキスト入力してsubmitすると、DBに内容が保存される。
(改行が入って見づらいけど)こんな感じ
mysql> select * from memo_data;
+---------+----------+--------+----------------------------+---------------------+---------------------+
| memo_id | category | title | memo | create_date | modified_date |
+---------+----------+--------+----------------------------+---------------------+---------------------+
| 1 | 0 | 買い物 | - カレー
- やさい
- にく | 2018-12-02 09:52:07 | 2018-12-02 09:52:07 |
+---------+----------+--------+----------------------------+---------------------+---------------------+
1 row in set (0.00 sec)
mysql>
メモの取得と表示処理
最後に保存したメモデータを画面に表示する処理を作成する。
表示時なので、場所はdoGet()
で実行する。
ひとまず表示するカラムは
- タイトル
- メモ
- 更新日
の3つで。
まずはSELECT文
select title, memo, modified_date from memo_data;
Javaのソースは、createやinsertと違って実行結果を受け取る処理も作成する。
con = DriverManager.getConnection(url, user, pass);
smt = con.createStatement();
String select_memo = "select title, memo, modified_date from memo_data;";
ResultSet result = smt.executeQuery(select_memo);
while (result.next()) {
System.out.println("title: " + result.getString("title"));
System.out.println("memo: " + result.getString("memo"));
System.out.println("modify: " + result.getString("modified_date"));
}
これでレコード情報が取得できる。
次に、DBから取り出したメモデータを画面(JSP)へ渡す。
メモの出力処理の作成
今度はServletからJSPへデータを渡す(JSPでServletから受け取った値を参照する)処理を作成する。
Servlet側
まずexecuteQuery()
の結果は、そのままだとConnectionのクローズ後では使用できないので、受け渡し用の変数を作成しその中へレコード情報をコピーする。
ArrayList<HashMap<String, String>> record_list = new ArrayList<>();
// 中略
ResultSet result = smt.executeQuery(select_memo);
while (result.next()) {
HashMap<String, String> record = new HashMap<>();
record.put("title", result.getString("title"));
record.put("memo", result.getString("memo"));
record.put("modified_date", result.getString("modified_date"));
record_list.add(record);
}
そして、JSPへこのrecord_list
を渡すために、Servletのリクエスト変数にsetAtribute()
で値を設定する(HashMapのように、キー-値形式のデータ構造を渡すことができる)
req.setAttribute("record_list", record_list);
String view = "/WEB-INF/jsp/index.jsp";
RequestDispatcher dispatcher = req.getRequestDispatcher(view);
dispatcher.forward(req, resp);
これで、JSPでrecord_list
というキー名で参照できるようになる
JSP側
ServletでsetAttribute(KEY)
でセットした値はrequest.getAttribute(KEY)
で取り出せる。
ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) request.getAttribute("record_list");
取り出した後は普通のJavaのコーディングと同様に、html形式で出力する。
Iterator<HashMap<String, String>> i = list.iterator();
while (i.hasNext()) {
HashMap map = i.next();
out.println("<hr/>");
out.println("<div>" + map.get("title") + "</div>");
out.println("<div>" + map.get("modified_date") + "</div>");
out.println("<div>" + ((String) map.get("memo")).replace("\n", "<br/>") + "</div>");
}
あと最初にimport文が必要
<%@page import="java.util.Iterator"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.HashMap"%>
全体のソースはこんな感じ
<%@page import="java.util.Iterator"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.HashMap"%>
<%@page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Memo App</title>
</head>
<body>
<h1>メモアプリ</h1>
<form method="post">
<input type="text" name="title" size="50" /> <br />
<textarea rows="5" cols="80" name="memo"></textarea>
<br /> <input type="submit" />
</form>
<%
ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) request
.getAttribute("record_list");
Iterator<HashMap<String, String>> i = list.iterator();
while (i.hasNext()) {
HashMap map = i.next();
out.println("<hr/>");
out.println("<div>" + map.get("title") + "</div>");
out.println("<div>" + map.get("modified_date") + "</div>");
out.println("<div>" + ((String) map.get("memo")).replace("\n", "<br/>") + "</div>");
}
%>
</body>
</html>
画面表示
なんとか表示と保存ができるようになりました。
今後の課題
- DBサーバのアドレス指定がハードコーディングされているため環境が変わるたびにリビルドが必要
- SQLインジェクション対策
- プレースホルダの使用とか
- ローカル以外の環境で動かすためのwarファイルの作成
- たぶんEclipseの操作の世界
- 関連情報: EclipseでサーバサイドJavaを作るときのプロジェクトとwarファイルのエクスポート
- 脱Eclipse
- CLIビルドとか
- Mavenプロジェクトとして作られたディレクトリ構成をしていれば、例えばDebian系Linuxならaptで
maven
を入れれば、pom.xml
のあるディレクトリでmvn package
を実行すればwarファイルができる - GitHubにソースをアップしたので参考
- Mavenプロジェクトとして作られたディレクトリ構成をしていれば、例えばDebian系Linuxならaptで
- あとやっぱIDEAかな
- CLIビルドとか
- DBの初期化処理
- JPA(Java Persistence API)とか
- DB処理をちゃんとクラス化
- DAOという考え方
- 平たく言うとデータの入出力操作を別クラスに分離して実装することで、例えばDBがPostgresに変更した場合も呼び出し側の変更を最小にする、みたいな商用コードでよくやるやつ。
- DAO側のソース例(GitHub)
- 呼び出し側のソースの変更点(GitHub)
- DAOという考え方
- Servlet -> JSPのデータ受け渡しをもう少しきれいに書く
- JavaBeansを使う: JavaBeansとJSTLでJSP/Servletの記述を簡易にする
- ループの表示部分をもう少し綺麗に書けないか
- JSTL coreタグライブラリのforEachで: JavaBeansとJSTLでJSP/Servletの記述を簡易にする
- フレームワーク対応
- Springとか
- ログインとかセッションとか
- 画面の見た目
- Bootstrapとか…