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式内でHapMapを参照する(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='';">