web.xmlの警備員! <security-constraint> の役割や!
この <security-constraint> 要素は、君のウェブアプリケーションにとっての警備員みたいなもんやで!
「このエリア(URL)には、特定の身分証(ロール)を持ってる人しか通したあかんで!」
っていう**セキュリティ上の制限(Constraint)**を、コンテナ(Tomcatとか)に教える役割があるんや。
📝 <security-constraint> の基本的な構造と役割
<security-constraint> の中には、主に3つの重要なサブ要素が入ってるで。
1. <web-resource-collection> (保護する対象を指定!)
これは「どのリソース(URL)を保護したいか」を指定する要素や。
* <web-resource-name>: この保護対象に付ける名前(適当でええで)。
* <url-pattern>: アクセスを制限したいURLのパターンを指定するんや。これが一番大事!
> 例: <url-pattern>/admin/*</url-pattern> \rightarrow 「/admin/の下にある全てのファイル」を保護するで!
>
* <http-method>: GETやPOSTなど、どのHTTPメソッドによるアクセスを制限するかを指定する。
2. <auth-constraint> (許可する身分証(ロール)を指定!)
これは「誰にアクセスを許可するか」を指定する要素や。
この中に、**許可したいロール(役割)**の名前を書くんや。
* <role-name>: アクセスを許可するロールの名前(例:manager、userなど)を指定する。
> 例: <role-name>manager</role-name> \rightarrow 「managerのロールを持ってる人だけ通してええで!」っていう意味や。>
3. <user-data-constraint> (通信の安全性を指定!)
これは「通信を暗号化(SSL/TLS)せなあかんか」を指定する要素や。
機密性の高いページ(ログイン画面とか)で使うで。
* <transport-guarantee>: CONFIDENTIAL(暗号化が必要)や NONE(必要なし)を指定する。
📜 web.xml の設定例
この設定は、こうやって書くのが一般的や。
<security-constraint>
<web-resource-collection>
<web-resource-name>社長室へのアクセス制限</web-resource-name>
<url-pattern>/syacho_room/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
こんな感じで設定しておくと、syacho_room のページにアクセスしようとした人は、自動的にログイン画面に飛ばされて、
「manager」っていう身分証がないと「立ち入り禁止!」ってなるわけや!😎
これがセキュリティ設定の基本中の基本やで!
この <security-constraint> と、ログイン画面を設定する <login-config> がセットになって、フォーム認証が完成するんやで!
HTMLのヤバい文字を無効化! fn:escapeXml の使い方や!
JSTLのFunctionsタグライブラリは、文字列の長さを調べたり、大文字・小文字に変換したり、
Javaの処理をJSP上で簡単に実行できるように集められた便利な関数の集まりなんや。
まずは、このFunctionsライブラリを使うために、JSPのてっぺんでこの「おまじない」が必要やで!
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
prefix は「fn」っていうのが一般的やで!これはFunctionsの頭文字やな。
🚨 エスケープ処理って、なんで必要なん?
例えば、誰かがフォームにこんな文字を入力したとするやろ?
<script>alert("ハッキングや!")</script>
この文字列を、何の処理もせんとそのままJSPで表示してしまうと、ブラウザはこれをHTMLタグやJavaScriptコードやと勘違いして、実行してしまうんや!
これは**XSS(クロスサイトスクリプティング)**っていう、めっちゃ危険なセキュリティの穴になってしまうんやで!😱
そこで登場するのが、fn:escapeXml 関数や!
📝 fn:escapeXml 関数の使い方
この関数を通すと、HTMLで特別な意味を持つ予約文字が、ただの文字として表示されるように変換されるんや。
| 変換前の文字 | 変換後の文字 | 意味 |
|---|---|---|
| < (小なり) | < | タグの開始を意味するから変換! |
| > (大なり) | > | タグの終了を意味するから変換! |
| & (アンパサンド) | & | そもそもエンティティ(特殊文字)の開始やから変換! |
| ' (シングルクォート) | ' | |
| " (ダブルクォート) | " | |
🚀 実際のコードの例
<c:set var="message" value='<script>alert("やられた!")</script>' />
<p>
そのまま: ${message}
</p>
<p>
安全に表示: ${fn:escapeXml(message)}
</p>
この処理をすると、ブラウザにはこんな風に表示されるんや!
> そのまま: (アラートボックスが表示されて大騒ぎ!)
> 安全に表示: <script>alert("やられた!")</script>
>
安全に表示された方は、ブラウザが
「これは**<**っていう文字列やな」
って認識するから、タグとしては実行されへんってわけや!
🤖 実は...ほとんど使わへん!?
実は、JSTLで表示に使われるEL式($で始まるやつ)や、<c:out>タグなんかは、
デフォルトでこの fn:escapeXml と同じように自動でエスケープ処理をしてくれるんや!👏
せやから、特別な理由がない限り、JSPでEL式を使って値を表示するだけなら、
この fn:escapeXml をわざわざ書く必要はあんまりないんよ。
**「fn:escapeXml を知っておく」ってことは、「セキュリティの意識がある」**ってことにつながるから、知識としてはバッチリやで!
JSTLのi18n(国際化)タグライブラリで数値を整形する!
JSTLのi18n(国際化)タグライブラリで、数値を桁区切りや通貨形式に**整形(フォーマット)**するために使うタグは、これや!
<fmt:formatNumber>
🌎 <fmt:formatNumber> で数値を見やすく整形するんや!
JSTLのこのライブラリは
「i18n(Internationalization=国際化)」と
「L10n(Localization=地域化)」
の機能をまとめてるんや。
国や地域によって、日付の書き方や通貨の単位、数字の区切り方って違うやろ?
この違いに対応するために使うのが、このタグライブラリなんやで!
最初にこのタグライブラリを使うための宣言が必要やから、忘れずにな!
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
📝 formatNumber タグの基本的な使い方
<fmt:formatNumber>タグは、EL式で渡された数字を、めっちゃ見やすい形式に変換してくれるんや。
1. 通貨形式に整形する
お金の数字を扱うときに使うで。
<c:set var="price" value="1250000" />
<p>価格: <fmt:formatNumber value="${price}" type="currency" currencySymbol="¥" /></p>
| 属性名 | 意味 |
|---|---|
| value | フォーマットしたい数値や。EL式で渡すで。 |
| type | どんな形式にしたいか。currency(通貨)を指定する。 |
| currencySymbol | 使う通貨記号を指定する。 |
2. 桁区切り(グループ化)に整形する
ただの大きな数字を、3桁ごとにコンマで区切って見やすくするんや。
<c:set var="population" value="127000000" />
<p>人口: <fmt:formatNumber value="${population}" type="number" groupingUsed="true" /></p>
| 属性名 | 意味 |
|---|---|
| type | number(一般的な数値)を指定する。 |
| groupingUsed | true にすると、3桁ごとに**桁区切り(コンマ)**を入れてくれるんや! |
💡 i18nライブラリの他の重要なタグ
このi18nタグライブラリには、日付を整形するタグもあって、これらもセットでめっちゃ重要やで!
| タグ名 | 役割 |
|---|---|
| <fmt:formatDate> | 日付や時刻を、国や地域に応じた形式に整形する。 |
| <fmt:setTimeZone> | 表示する**タイムゾーン(時間帯)**を設定する。 |
| <fmt:setLocale> | **言語や地域(ロケール)**を設定する。 |
これらのタグを使うと、同じJSPファイルでも、アクセスしてきたユーザーの国籍に合わせて、自動で「1,250,000」って表示したり、「1.250.000 €」って表示したりできるんや!
めっちゃスマートやろ!👍
これで、JSTLの基本的なタグはほぼマスターやで!
おつかれさん!!
SELECT文を実行! <sql:query> の役割と使い方
<sql:query> タグは、データベースに対して問い合わせ(Query)、つまり主にSELECT文を実行するためのタグや。
このタグの処理が終わると、その結果(取得したデータ)が結果セットとして変数に格納されるんやで!
📝 <sql:query> タグの基本的な使い方
前の質問で設定したデータソース(myDataSource)を使って、SELECT文を実行する例を見てみよか。
<sql:query var="resultData" dataSource="${applicationScope.myDataSource}">SELECT id, name, price
FROM products
WHERE price > 1000
</sql:query>
💡 設定する主な属性(重要やで!)
| 属性名 | 意味 |
|---|---|
| var | クエリの実行結果(結果セット)を格納するための変数名や。この変数名は**Resultオブジェクト**を保持するんや。 |
| dataSource | どのデータベース接続(データソース)を使うかを指定する属性や。EL式でスコープ内のデータソースを参照するで。 |
🚀 結果セット(Resultオブジェクト)の取り出し方
<sql:query>で取得した結果(上の例ではresultData)は、Resultオブジェクトとして格納されるんや。
このオブジェクトの中身をブラウザに表示させるには、さっき覚えた**<c:forEach>**タグを使うのが一般的やで!
結果を表示する流れ
* 行(Row)の繰り返し:Resultオブジェクトのrowsプロパティを使って、取得したデータの行を一つずつループする。
* 列(Column)の値の取得:ループの中で、row(行)から特定の列名を指定して値を取ってくる。
<!-- end list -->
<c:forEach var="row" items="${resultData.rows}">
<p>
ID: ${row.id}
商品名: ${row.name}
</p>
</c:forEach>
これで、データベースから取ってきたデータ(SELECT文の結果)を、JavaコードなしでJSPに綺麗に表示できるようになったってわけや!
これで、JSTLのDB接続とデータ取得の流れが繋がったな!
<sql:setDataSource>で接続して、<sql:query>でデータを取ってくる、
って流れをしっかり覚えといたら完璧やで!😊
JSTLでDBに接続! <sql:setDataSource> の役割
JSTLには、ウェブページから直接データベースを操作するための専用のタグライブラリ、SQLタグライブラリっていうのがあるんや。
これを使うためには、JSPファイルの先頭でCoreタグとは別に宣言せなあかんな。
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
この「sql」タグライブラリの中で、データベースにアクセスするために一番最初に使わなあかんのが、この <sql:setDataSource> タグなんや!
📝 <sql:setDataSource> タグの基本的な使い方
このタグは、データベースに繋がるための接続情報を設定して、「データソース」っていう名前を付けて、スコープに保存する役割があるんや。
だいたいは、こんな風にアプリケーションスコープに設定して、ウェブアプリ全体で使い回すようにするで。
<sql:setDataSource
var="myDataSource"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydbname"
user="dbuser"
password="dbpassword"
scope="application"
/>
💡 設定する主な属性(超重要やで!)
| 属性名 | 意味 |
|---|---|
| var | このデータソースを識別するための変数名(スコープに格納する名前)や。 |
| driver | データベースに接続するためのJDBCドライバのクラス名や。MySQLとかOracleとか、DBの種類によって変わるで。 |
| url | データベースの**場所(URL)や。どこにある、どのデータベースに繋ぎたいかを指定する。 |
| user | データベースにログインするためのユーザー名**や。 |
| password | データベースにログインするためのパスワードや。 |
| scope | この接続情報をどのスコープに保存するか。通常は**application**にするで。 |
🚨 注意点やで!
このJSTLのSQLタグライブラリは、手軽にDBアクセスができて便利やけど、本番の業務用システムではあんまり使わへんんや。
なんでかというと、
* セキュリティ:パスワードをJSPファイルに直接書くことになるから、セキュリティ的に危ない。
* パフォーマンス:リクエストが来るたびに接続を開いたり閉じたりするから、処理が遅くなることが多い。
せやから、本格的なアプリ開発では、サーブレット側でJDBCを使うか、接続プールっていう仕組みを使うのが一般的やで!
でも、この <sql:setDataSource> は、JSPから直接DBアクセスを試すための基本中の基本やから、しっかり覚えとくとええで!👍
JSTLの<c:forEach>タグで、ループの回数とかを取得するための属性!
varStatus 属性でループの状態を丸裸にするんや!
<c:forEach>タグは、リストとか配列の中身を一つずつ取り出して、
**繰り返し処理(ループ)**を行うためのタグやな。
このループが今、「何回目か」「最初か最後か」っていうステータス情報は、
varStatus 属性で指定した**変数(オブジェクト)**の中に全部入っとるんや。
📝 varStatus 属性の使い方
varStatus 属性には、ステータス情報を格納するための任意の変数名(例:status、loop、vsなど)を付けてあげるんや。
🚀 使い方の例
例えば、itemList っていうリストをループ処理して、ついでに「今、何番目のアイテムか」を表示したいとするで。
<c:forEach var="item" items="${itemList}" varStatus="status">
<p>
[${status.index}]
No.${status.count}:${item.name}
</p>
</c:forEach>
💡 varStatus オブジェクトで使える便利な情報!
varStatus 属性で指定した変数(上の例ではstatus)には、こんな情報が格納されとるで!
| プロパティ名 | 意味 | どんな時に便利? |
|---|---|---|
| current | 今処理中のアイテムそのもの。 | varで指定した変数と同じ値やけど、明示的に参照したい時に使う。 |
| index | 現在のループのインデックス(添字)。0から始まる。 | 配列みたいに 0 から数えたい時に使う。 |
| count | 現在のループの回数。1から始まる。 | 「No.1、No.2、No.3...」みたいに順番を表示したい時に使う。 |
| first | ループの最初の処理かどうか。(true / false)
| 最初の行だけ太字にしたいとか、特別な処理をしたい時に使う。 |
| last | ループの最後の処理かどうか。(true / false) | 最後の行だけ区切り線を入れたいとか、特殊なデザインにしたい時に使う。 |
特に、count(1から始まる)と index(0から始まる)の違いは、めっちゃ重要やからしっかり覚えておくんやで!
この varStatus を使えば、ループ処理が格段に柔軟になって、凝ったデザインやリスト表示が簡単にできるようになるで!
これで、JSPとJSTL、サーブレットの基本的な連携の仕組みがかなり見えてきたんちゃうかな!
ええ感じで勉強進められてんで!😊
<c:if>タグの基本!test 属性で条件を判定するんや!
<c:if>タグは、Javaの**if文**とまったく同じ役割をするタグやで。
つまり、
「もし、この条件が正しかったら、この間の処理を実行してな!」
って指示するためのもんや。
この「この条件」を指定するのが、test 属性の仕事なんや!
📝 test 属性の使い方
test 属性の値には、**式言語(EL)**を使って、真(true)か偽(false)のどちらかになるような条件式を記述するんや。
🚀 使い方の例
例えば、スコープに設定した変数 point が 80 より大きかったら、「合格や!」って表示したいとするやろ?
<c:set var="point" value="85" scope="request" />
<c:if test="${requestScope.point > 80}">
<p style="color: green;">合格や!おめでとう!</p>
</c:if>
test 属性の中の ${requestScope.point > 80} の部分が条件式や!
| 項目 | 意味 |
|---|---|
| ${ ... } | EL式(式言語)を使うっていう合図やな。 |
| requestScope.point | リクエストスコープから point っていう名前の値を取ってくる。 |
| > | 「より大きい」っていう比較演算子や。
|
| 80 | 比較したい値やな。 |
この条件式の結果が true になったら、<c:if> と </c:if> の間のHTMLが表示されるってわけや!
💡 c:if の便利なところ!
Javaのコード(スクリプトレット)で if 文を書こうと思ったら、
<%
if (score > 80) {
%>
<p>合格や!</p>
<%
}
%>
って、JavaのコードとHTMLのタグがごっちゃになって、見づらいやろ?
せやけど、<c:if> タグを使えば、
<c:if test="${score > 80}">
<p>合格や!</p>
</c:if>
みたいに、HTMLタグの中にスッキリ収まって、めっちゃ読みやすくなるんやで!
これがJSTLを使う大きなメリットなんよ!
ちなみに、<c:if>には else の機能はないから、
「もしダメやったら別の処理したい」
って時は、<c:choose>、<c:when>、<c:otherwise> のセットタグを使うんやで!