HTML CRUD サーブレットまとめ jQuery 応用 Spring Boot
スッキリわかるサーブレット&JSP入門 Web付録 サンプルコード
HTMLファイル、CSSファイル、JSPファイルを配置。
WEB-INF以下はユーザは直接アクセスできない。
Javaプログラムを配置。パッケージを作成して配置する(例:「servlet」など)。
パッケージを右クリックし[新規]-[サーブレット]で「クラス名」を入力(例:「HelloServlet」など)。
HTMLファイルを右クリックし、[次で開く]-[その他]から「JSPエディタ」を選び、下にある「すべての'*.html'ファイルで使用する」をチェックしてOKを押す。
「サーバ」の「Tomcat9_Java17」をダブルクリックし、「モジュール」のタブを選び、プロジェクトを選択、編集ボタンを押して「自動再ロード使用可能」をチェックしてOKを押す。
コードの断片を素早く挿入できる機能。表示されていない場合には[ウィンドウ]-[ビューの表示]の「その他」から「スニペット」を選択し、表示。
サーブレット開発用スニペットダブルクリックするとカーソル位置に挿入されます。
パラメータがあるスニペットは値を設定して挿入します。
HTMLのみの場合

プログラムを実行する場合

http://localhost:8080/プロジェクト名/URLパターン
URLパターンはサーブレットクラスの上に付けられているアノテーションで設定
@WebServlet("/index")
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"utf-8\">");
out.println("<title>Hello</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>Hello World</p>");
out.println("</body>");
out.println("</html>");
ShouhinDAO dao = new ShouhinDAO();
Shouhin s = dao.findBySid(1);
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>商品</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>商品名:"+s.getSname()+"</p>");
out.println("</body>");
out.println("</html>");
jspファイルを開く(URLは変わらない)
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/sample.jsp");
rd.forward(request, response);
別アドレスに飛ぶ(URLは変わる)
response.sendRedirect("index");
JSPにデータを渡す
request.setAttribute("slist", list);
<form method="GETまたはPOST" action="送信先"> <input type="text" name="名前"> <input type="submit" value="送信"> </form>
※送信先はURL。例:form
サーブレット内のdoGetやdoPostでフォームから送られたデータを受け取るには request.getParameter(名前) を行い、戻り値の文字列で受け取る。名前はinputタグのname属性に設定されたもの。
request.setCharacterEncoding("UTF-8");
// 文字列の受け取り
String name = request.getParameter("name");
// 数値の受け取り(文字で受け取るので数値に変換)
int age = Integer.parseInt(request.getParameter("age"));
※その名前が存在しない場合、nullになる。radio、checkboxの場合、未選択時にはnull。
同じnameを設定した場合、配列で受け取ることができる。
request.setCharacterEncoding("UTF-8");
// 文字列配列の受け取り
String[] names = request.getParameterValues("name");
※数値の場合、まず文字列配列で受け取って1つずつ取り出したときに数値に変換する。
| GET | POST | |
|---|---|---|
| データの渡し方 | URLに付加 | ユーザには見えない(リクエストボディで送る) |
| サイズ制限 | 小さい(8KB程度) | 大きい |
| ブラウザ履歴 | 入力内容が残る | 入力内容が残らない |
| 入力の再現・共有 | URLで可能 | 再入力しない限り不可 |
| サーバデータの書き換え | 向かない | 向いている |
| 用途 | 検索、閲覧 | 書き込み、削除、ログイン、アップロード |
formタグ内にinputタグでtypeをhiddenにすることでユーザには見えずに値を渡すことが出来る。。
<input type="hidden" name="名前" value="送信値">
フォームでGET送信するときと同様のアドレスをリンクで指定すればよい。
<a href="shouhin?sid=1">リンク文字列</a>
フォームから送信された主キー(sid)でデータベースを検索し表示
request.setCharacterEncoding("UTF-8");
int sid = Integer.parseInt(request.getParameter("sid"));
ShouhinDAO dao = new ShouhinDAO();
Shouhin s = dao.findBySid(sid);
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>商品</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>商品名:"+s.getSname()+"</p>");
out.println("</body>");
out.println("</html>");
JavaプログラムやEL式をHTML内に書くことが出来る。
<% Javaプログラム %> <%= 式 %> 式の値の表示 <%-- コメント --%> コメント
<%@ page import="java.util.Date" %> インポート <%@ include file="ファイル名" %> 静的インクルード
例:header.jspで以下を作成する
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<header>
<h1>Sampleサイト</h1>
</header>
読み込むところで以下を書く。
<%@ include file="header.jsp" %>
| 名前 | 役割 | クラス |
|---|---|---|
| Model | データ | 一般的クラス(JavaBeans、DAO/DTOなど) |
| View | 表示 | JSP(+CSS) |
| Controller | データと表示の橋渡し | サーブレット |
Webサーバにアクセスがあった場合、まずサーブレットが実行され、モデルのクラスを利用した後、画面表示のためにJSPを呼び出すようにする。
// フォームからの送信データ取得
request.setCharacterEncoding("UTF-8");
int sid = Integer.parseInt(request.getParameter("sid"));
// モデルクラスの利用
ShouhinDAO dao = new ShouhinDAO();
Shouhin s = dao.findBySid(sid);
// モデルクラスをリクエストスコープでJSPに渡す
request.setAttribute("shouhin", s);
// JSPの呼び出し(フォワード)
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/shouhin.jsp");
rd.forward(request, response);
JSP呼び出し時にデータを渡すために使うクラス。データの入れ物。
カプセル化されて、setter/getterがあり、引数なしのコンストラクタがあるクラス。
JavaBeansがJSPに渡されてきたとき、簡単に表示できる。
サーブレット内でリクエストスコープをセット
String name = "田中";
request.setAttribute("name", name);
JSP内での表示
${name}
Shouhin s = new Shouhin(1,"りんご",100);
request.setAttribute("shouhin", s);
JSP内での表示(getterとしてgetSname() があるとき)
${shouhin.sname}
EL式内でJavaの計算式を書くことも可能
${shouhin.tanka + 100}
三項演算子(式 ? 式がtrueのとき:式がfalseのとき)を使うとif文的なこともできる。
${shouhin.tanka >= 200 ? "高額":"低額"}
EL式内でHashMapを参照する(mapという名前の場合)。以下のどちらでも良い
${map.キー名}
${map['キー名']}
<select name="seibetu">
<option value="1" ${shouhin.cid == 1 ? "selected" : ""}>果物</option>
<option value="2" ${shouhin.cid == 2 ? "selected" : ""}>野菜</option>
</select>
JSP内でforEachなどが書ける
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
リストから変数名に1つずつ値を取り出す
<c:forEach var="変数名" items="${リスト}" >
// 変数名を使ったEL式
</c:forEach>
例:サーブレット内で、ShouhinクラスのArrayListオブジェクトが list の名前で渡されたとき。
<c:forEach var="s" items="${list}">
<p>${s.sname}</p>
</c:forEach>
テーブルの例
<table>
<tr><th>商品ID</th><th>商品名</th><th>単価</th></tr>
<c:forEach var="s" items="${list}">
<tr>
<td>${s.sid}</td>
<td>${s.sname}</td>
<td>${s.tanka}</td>
</tr>
</c:forEach>
</table>
繰り返し番号を1から数えたい場合、varStatusで指定した名前の.countで出すことができる。
<c:forEach var="s" items="${list}" varStatus="status" >
${status.count}番 ${s.sname}
</c:forEach>
varStatusにはcountの他にindex(0からの回数)やfirst、last(真偽値)などがある。
begin、endを使うとJavaのfor文と同様に数値を増やしていくことが出来る。
<select name="month">
<c:forEach begin="1" end="12" var="tuki">
<option>${tuki}</option>
</c:forEach>
</select>月
c:outタグで、valueに値を指定。XSS対策としてHTMLタグなどがそのまま表示されないように特殊文字に変換(エスケープ)して画面に出力。
<c:out value="${shouhin.sname}" />
スコープへの値の設定
リクエストスコープ name に shouhin.sname を設定
<c:set var="name" value="${shouhin.sname}" />
セッションスコープ name に shouhin.sname を設定
<c:set var="name" value="${shouhin.sname}" scope="session" />
c:ifタグのtest属性でtrueのときだけ表示
<c:if test="${shouhin.tanka>=200}" >
高額
</c:if>
c:ifタグのtest属性でオブジェクトがnullのときのみ表示
<c:if test="${empty shouhin}" >
// shouhinがnullのときの表示
</c:if>
c:ifタグのtest属性でオブジェクトがnullではないときのみ表示
<c:if test="${not empty shouhin}" >
// shouhinがあるときの表示
</c:if>
c:chooseタグでtrueのときとfalseの処理で分ける。
c:whenタグのtest属性でtrueのときに表示、c:otherwiseでfalseのときの表示を書く。
<c:choose>
<c:when test="${shouhin.tanka>=200}" >
高額
</c:when>
<c:otherwise>
低額
</c:otherwise>
</c:choose>
JSTL I18N :JSP内でEL式の日付などをフォーマットできる
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
| yyyy | 年 |
| MM | 月 |
| dd | 日 |
| E | 曜日 |
| HH | 時 |
| mm | 分 |
| ss | 秒 |
<fmt:formatDate value="${u.hi}" pattern="yyyy年MM月dd日" />
| # | 数値(0の場合非表示) |
| 0 | 数字(0の場合0で表示) |
| カンマ(,) | 桁区切り |
HH 時 mm 分 ss 秒
<fmt:formatNumber value="${u.kosu}" pattern="###,###" />
HttpSession session = request.getSession();
session.setAttribute("member", member);
HttpSession session = request.getSession();
Member member = (Member)session.getAttribute("member");
その名前のデータが無い場合、nullになる
HttpSession session = request.getSession();
session.removeAttribute("member");
その名前のデータが無い場合、nullになる
HttpSession session = request.getSession(); session.invalidate();
セッションスコープ name を表示する
${sessionScope.name}
セッションスコープ name を判定する(リクエストスコープと同じ)
<c:if test="${not empty member}" >
// ログイン時の処理
</c:if>
セッションを使って一度だけ表示したいメッセージを実現できる
// サーブレット内
HttpSession session = request.getSession();
session.setAttribute("message", "ログインに失敗しました。");
response.sendRedirect("login");
※c:ifを使うのでtaglibを忘れないこと。
<c:if test="${not empty message}">
<p>エラー:${message}</p>
<c:remove var="message" scope="session"/>
</c:if>
// 自分のURI
// 例 /example/update
request.getRequestURI()
// 自分のURL
// 例 http://localhost:8080/example/update
request.getRequestURL()
// リクエストパラメータ
// 例 sid=1
request.getQueryString()
// 呼び出し元のURL取得
request.getHeader("REFERER")
// WebContentの実際のパス
getServletContext().getRealPath("相対パス");
例:FileupServlet(URLは /fileup)でdoGetでは fileup.jsp で画像アップフォームを表示する。フォームは/fileupにPOSTする。リダイレクトで /fileupに戻る。
formタグは必ずpostで、enctype="multipart/form-data"を付ける。
ファイルをアップロードする部品はtype="file"
acceptでファイルの種類を指定する(省略時は全てのファイル)
例:fileup.jsp
<form action="fileup" method="post" enctype="multipart/form-data"> 写真:<input type="file" name="pict" accept="image/jpeg"><br> <input type="submit" value="送信"> </form>
※この例ではtype="file"のみだが、他にテキストボックスなどを通常通りに設置しても良い。
サーブレットのクラスに@MultipartConfigを付ける
Partクラスでアップロードされたファイルの情報を取得する。ファイルは既にサーバの規定の場所にあるので、それを自分の望む位置に移動する。
@WebServlet("/fileup")
@MultipartConfig
public class FileupServlet extends HttpServlet {
// 途中省略
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/fileup.jsp");
rd.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Partクラス取得(name属性を指定する)
Part part=request.getPart("pict");
if(part.getSize()==0) {
// ファイルがアップされていないときの処理
return;
}
// ファイルの移動先(この例ではimageフォルダ。あらかじめwebappに作成)
String path = getServletContext().getRealPath("/image");
// フォルダがなければ作成
File upFolder = new File(path);
if (!upFolder.exists()) {
upFolder.mkdir();
}
// アップするファイル名。
String fileName = "up.jpg";
// ファイルの移動
part.write(path + File.separator + fileName);
// リダイレクト
response.sendRedirect("fileup");
}
}
上記の例の場合、画像ファイルは以下で表示される。
<img src="image/up.jpg">
なお、Eclipse上にはアップされた画像は反映されない。動いたサーバ上に反映される(workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\プロジェクト名)。
String fileName = part.getSubmittedFileName();
String fileName = UUID.randomUUID() + ".jpg"; // ed14621c-a9d9-4eee-b0a4-ffbd0fa99a1f.jpgのような名前になる
String fileName = sid + ".jpg";
※JavaScriptでの対策例 <img src="画像パス" onerror="this.onerror = null; this.src='';">