はじめに
Javaのエスケープ処理は、文字列リテラル、HTML出力、ファイル読み込み、Webフォームの表示で文字の意味を取り違えないための基礎知識になる。初心者がつまずきやすいのは、"やのようなJava構文上のエスケープと、<や&のようなHTML向けの変換を同じものとして扱ってしまう点だ。
その違いを整理すると、Javaソース内で文字列を成立させる処理と、ブラウザに安全な文字として渡す処理は目的が異なる。そのため、サンプルコードを写すだけでなく、入力元、出力先、変換対象の文字を合わせて判断する姿勢が必要になる。
- Java SE 21 LTS / OpenJDK 21
- Apache Commons Text 1.12.0 / Jakarta Servlet 6.1
- HTML Living Standard / Google Chrome 126相当のHTML解釈を前提
- Java文字列リテラルで使う基本的なエスケープ処理
- HTML表示用に
<や&を変換する考え方 StringBuilderやreplaceを使ったサンプルコードの読み方- Webアプリケーションで入力値を安全に表示する実装パターン
- 初心者が混同しやすいJava構文とHTMLエンティティの違い
公式情報はJava SE 21 String APIとApache Commons Text StringEscapeUtilsを参照できる。
Javaとは
結果: 期待される出力は彼は"Javaの基本を学ぶ"と言った。です。JavaのStringでは、文字列を囲む"と本文中の引用符を区別するため、本文側の引用符に"を使います。
Javaはクラスを中心にコードを構成するオブジェクト指向言語で、javacでコンパイルした.classをJVM上で実行する仕組みを持つ。その仕組みにより、OSごとの差をJVMが吸収しやすく、Webアプリケーション、業務システム、Android関連の学習などで長く使われてきた。
基本的にJavaのソースコードはclass、public、static、void、mainなどの構文要素で組み立てる。文字列を扱う場面ではString、繰り返し結合ではStringBuilder、配列引数ではString[]がよく出てくるため、初心者はこれらの役割を先に押さえると読み進めやすい。
Javaの周辺知識は、Java List型完全ガイド、Javaアノテーションの12選、Javaでうるう年を判定、Javaでマスターするオーバーライド、Javaのオブジェクト指向で補える。
基本的な特徴
Javaの特徴は、プラットフォーム独立性、オブジェクト指向、ガベージコレクション、標準ライブラリの厚さに整理できる。ただし、どの特徴も単独で成り立つわけではなく、JDK、JRE、JVM、標準APIが組み合わさって開発体験を支えている。
| 分類 | 主な対象 | Javaでの例 | エスケープ処理の観点 | 初心者の注意 |
|---|---|---|---|---|
| 文字列 | 引用符 | " | 文字列の終端と本文を分ける | 閉じ引用符と混同しない |
| 文字列 | バックスラッシュ | \ | パスや正規表現で必要 | 1個だけでは構文が崩れる |
| 文字列 | 改行 | n | 表示上の行を分ける | OSの改行差と分ける |
| 文字列 | タブ | t | ログやTSVで使う | 空白とは幅が異なる |
| 文字列 | シングルクォート | ' | charで必要になる | Stringとの違いを見る |
| HTML | 小なり | < | タグ開始として解釈させない | Java構文の<ではない |
| HTML | 大なり | > | タグ終了として扱わせない | 入力値表示で漏れやすい |
| HTML | アンパサンド | & | エンティティの始まりを保護 | 最初に変換する |
| HTML | ダブルクォート | " | 属性値を壊さない | 属性内では特に確認する |
| HTML | アポストロフィ | ' | 引用符の区切りを避ける | 'との差を見る |
| API | 置換 | replace | 単純な文字列変換 | 順序で結果が変わる |
| API | 連結 | append | 変換後文字列を構築 | 大量結合では+を避ける |
| API | 空判定 | isEmpty | 空文字を早期返却 | nullとは別 |
| API | 配列化 | toCharArray | 1文字ずつ確認 | サロゲートペアに注意 |
| API | 長さ | length | ループ条件に使う | 文字数とコード単位は違う |
| API | 文字取得 | charAt | 対象文字を判定 | 範囲外参照を避ける |
| 制御 | 分岐 | switch | 文字ごとの変換に向く | break漏れを見る |
| 制御 | 繰り返し | for | 全文字を走査 | 終了条件を確認する |
| 制御 | 条件 | if | 入力値の分岐 | nullを先に扱う |
| 入出力 | 読み込み | BufferedReader | 行単位で変換 | 文字コードを意識する |
| 入出力 | ファイル | FileReader | テキスト入力元 | 既定文字セットに注意 |
| 入出力 | 例外 | IOException | 失敗時の処理 | 握りつぶさない |
| Web | リクエスト | HttpServletRequest | 入力値を受け取る | 信頼済みと見なさない |
| Web | レスポンス | HttpServletResponse | HTMLへ出力する | 出力直前に変換する |
| Web | パラメータ | getParameter | フォーム値を読む | nullの可能性を見る |
| Web | Content-Type | setContentType | HTMLとして返す | 文字セットも検討する |
| ライブラリ | HTML4 | escapeHtml4 | 定番のHTMLエスケープ | Commons Text側を使う |
| ライブラリ | クラス | StringEscapeUtils | 既存実装を利用 | Commons Lang版は非推奨 |
| 設計 | 出力先 | text/html | HTML文脈で変換 | JSONやSQLと混ぜない |
| 設計 | 戻り値 | return | 変換済み文字列を返す | 二重エスケープを避ける |
エスケープ処理とは
エスケープ処理とは、特別な意味を持つ文字を、意図した文脈で普通の文字として扱える形に変える処理です。Javaではソースコード上のn、t、"、\のような表記があり、HTMLでは<や>のようなエンティティが使われる。
ただし、JavaのエスケープとHTMLのエスケープは同じ目的ではありません。Javaコンパイラに文字列の範囲を誤解させないための処理と、ブラウザにタグとして解釈させないための処理を分けて考えると、サンプルコードの意図が読み取りやすくなる。
💡 Tips:String.translateEscapes()はJava文字列内のエスケープシーケンスを変換するAPIです。HTMLエスケープ用ではないため、<script>の無害化にはescapeHtml4など別の処理を選びます。
エスケープ処理の詳細な作り方
Javaでエスケープ処理を作るときは、変換対象を決めてから実装する。文字列リテラル内の引用符を扱うのか、HTML出力に備えて入力値を変換するのか、ファイルから読んだテキストを画面表示用に整えるのかで、使うAPIと変換ルールが変わる。
詳細な使い方
具体的には、Javaソースの中で"を文字として入れたいなら"、バックスラッシュ自体を入れたいなら\を書く。一方、HTMLへ出す文字列では<を<、&を&へ変えるため、文脈に合わせた変換が必要だ。
サンプルコード1:文字列のエスケープ
その基本になるのが、引用符を文字列本文として扱う書き方です。初心者向けの最小サンプルコードとして、JavaのStringに引用符を含める例を確認します。
結果: 期待される出力はこれは"エスケープ処理"の例です。です。Javaコンパイラは"を文字列終端ではなく本文中の引用符として扱います。
サンプルコード2:特殊文字のエスケープ
HTMLに文字列を埋め込む場面では、<div>のような入力がタグとして解釈される可能性がある。そのため、Java側でHTMLエンティティに変換してから出力すると、ブラウザはタグではなくテキストとして扱いやすくなる。
結果: 期待される出力はエスケープ後のテキスト: <div>Javaエスケープ処理</div>です。replaceを連ねる場合、&を先に変換することで後続のエンティティをさらに変換してしまう事故を避けます。
詳細な対処法
初心者がエスケープ処理で間違えやすいのは、入力された時点で変換するか、出力する直前に変換するかの判断です。一般的には、保存データは元の意味を保ち、HTMLとして表示する直前にHTML向けへ変換する設計のほうが扱いやすい。
サンプルコード3:エスケープのミスを避ける
これを避ける最小の対処法として、入力値を受け取り、HTML表示用の変数を別に作る形がある。元データと表示用データの名前を分けると、Javaコード内で二重エスケープを発見しやすい。
結果: 期待される出力は元の文字列: Hello <World>とエスケープ処理後の文字列: Hello <World>の2行です。Java変数originalとescapedを分けることで、処理前後の意味が読み取りやすくなります。
replace("<", "<")を実行したあとでreplace("&", "&")を行うと、生成済みの<まで変換対象になります。順序は仕様として固定しておきますし、ここがポイントです。サンプルコード4:セキュリティ対策
セキュリティ対策では、Apache Commons Textのorg.apache.commons.text.StringEscapeUtilsを使う。Commons Lang版は非推奨だ。
結果: 期待される出力は安全な出力: <script>alert('XSS');</script>に相当します。厳密なアポストロフィの表現はライブラリのバージョンやHTML仕様の扱いで差が出る場合があります。
詳細な注意点
エスケープ処理の注意点は、変換漏れ、二重変換、文脈違い、過剰な文字列生成に分けて考えられる。JavaのStringは不変なので、短い処理ならreplaceの連鎖でも読みやすいが、大量データを1文字ずつ処理するならStringBuilderが合う場面もある。
サンプルコード5:処理時間の確認
処理時間を確認するサンプルコードは、測定結果そのものより、同じ変換を大量に繰り返したときの構造を読む目的で使う。実行環境により数値は変わるため、期待される出力には固定値を書かない。
結果: 期待される出力は処理時間: 123ミリ秒のような形式です。数値はCPU、JVMオプション、実行回数、ウォームアップ状況で変わるため、固定の処理時間として扱いません。
サンプルコード6:メモリ効率を意識したエスケープ処理
同様に、1文字ずつ判定する処理ではStringBuilderに結果を積み上げる方法が使える。これにより、変換対象の文字が多い場合でも処理の流れを追いやすく、ルール追加もswitchに集約しやすい。
結果: 期待される出力はOriginal String: Hello & Welcome to the <Java> World!とEscaped String: Hello & Welcome to the <Java> World!です。StringBuilderは変換後の文字列を段階的に組み立てます。
詳細なカスタマイズ
カスタマイズでは、どの文字をどの出力先向けに変えるのかをルールとして固定する。Javaのメソッド名にescapeHtml、escapeAttribute、escapeLogTextのような文脈を含めると、呼び出し側の誤用を減らしやすい。
サンプルコード7:カスタムエスケープ処理
具体的には、<と>だけを変換する限定的なメソッドを作れる。対象を絞ったサンプルコードは学習には読みやすいが、実運用のHTML出力では&や引用符も考慮する必要がある。
結果: 期待される出力は<div>Hello Java</div>です。customEscapeは<と>だけを置き換えるため、限定用途の例として読みます。
サンプルコード8:エスケープ処理の拡張
その拡張として、HTMLでよく扱う基本文字をまとめて変換するメソッドを作る。Javaのswitch式ではなく従来のswitch文で書くと、古い学習環境でも読みやすい。
結果: 期待される出力は元の文字列: Hello <World> & 'Java'とエスケープ後の文字列: Hello <World> & 'Java'です。&も変換対象に入るため、HTML本文へ渡す文字列として扱いやすくなります。
エスケープ処理の応用例とサンプルコード
応用例では、ファイル、Webフォーム、ログ、JSON風テキストなど、入力元と出力先が変わる。Javaのエスケープ処理は単なる文字置換ではなく、どの文脈で危険な文字になるかを判断する設計上の作業でもある。
そのため、サンプルコードを読むときは、変換対象の文字、変換のタイミング、出力先の仕様をセットで見るとよい。Servletの入力処理についてはJakarta Servlet HttpServletRequestも一次情報として確認できる。
サンプルコード9:ファイルの読み込みとエスケープ処理
ファイルから読み込んだ文字列をHTMLへ出すなら、行単位で読み取り、表示直前に変換する構成が分かりやすい。try-with-resourcesを使うとBufferedReaderのクローズも自然に扱える。
結果: example.txtに<p>Java & HTML</p>という行がある場合、期待される出力は<p>Java & HTML</p>です。ファイルが存在しない場合はIOExceptionに応じたスタックトレースが出ます。
サンプルコード10:Webアプリケーションでの利用
Webアプリケーションでは、フォーム入力をHttpServletRequestから受け取り、HttpServletResponseへHTMLとして返す流れがある。このとき、入力値をそのまま連結して出力すると、HTMLタグやスクリプト断片がブラウザで解釈される可能性がある。
結果: フォームに<script>alert('XSS')</script>が入力された場合、期待される表示はスクリプトの実行ではなく、エスケープ済みの文字列表示です。escapeHtml4はHTML本文へ出す直前の変換として使います。
結果: nullが渡された場合は空文字を返し、通常の文字列ではHTMLの基本文字をエスケープした文字列を返す想定です。戻り値の方針をnull維持にするか空文字にするかは、呼び出し側の設計に合わせます。
ログとJSON風テキストでの扱い
ログではHTMLエスケープより、改行やタブを見える文字へ寄せる処理が役立つ場合がある。攻撃対策というより、ログの行構造を壊さないための整形であり、Javaのreplaceでr、n、tを明示表記に変える考え方だ。
結果: 期待される出力はJavanEscapetGuideです。実際の改行やタブを見える文字列に変えるため、ログを1行単位で読みやすくできます。
まとめ
Javaのエスケープ処理は、ソースコード内の文字列を成立させる処理と、HTMLなどの出力先で安全に表示する処理に分けて理解する。初心者は"、\、nのようなJava構文から入り、次に<、>、&のようなHTMLエンティティへ進むと整理しやすい。
そのうえで、HTML本文に出す値にはStringEscapeUtils.escapeHtml4のような既存ライブラリを使い、限定的な学習や要件だけを手書きのサンプルコードで確認する。Javaのコードレビューでは、変換順序、二重エスケープ、文脈違い、非推奨APIの混入を重点的に確認するとよい。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaでマスターする!オーバーライドのたった7つのステップ
- オブジェクト指向を10ステップで完全マスター
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


