【Struts2超基礎】HelloStruts!と表示される動きを図解【第2章】
プログラマカレッジでStruts2について学習したことをまとめた第2章。
第1章を読んでいる前提で書いたので、まだ読んでないという方はまずこちらからどうぞ。
【Struts2とは?】初歩の初歩をイメージでつかむ【第1章】
本記事では、ボタンを押すとHelloStruts!と表示されるだけの簡単なアプリが裏側では実際にどうなっているのか、を豊富な図解を用いながら解説してみます。
超単純なアプリですが、だからこそMVCモデルに沿って動いているという実感を得ることができ、もう一段階複雑なアプリの仕組みの理解に繋がると思います。
※スマホからだと絵が小さくて読みにくいかもしれません
本記事を読むと分かること
- Struts2のMVC的な動きの流れが分かった気分になる
繰り返しますが、厳密な理解を求める記事ではありませんので悪しからず。
ー もくじ ー
Struts2でHelloStruts!が表示されるまでの流れ
実際に作ったものをベースに説明していきます。
繰り返しですが、今回のStruts2解説で使うWebアプリケーションは、HelloStrutsボタンを押すと「HelloStruts!」と表示されるだけの、一番最初に作る超簡単なものです。
こんな単純なものにも関わらず、1回目にサンプルコードを書き写して完成させた段階では「何を書いたかよく分からんけど動いた」という状態であることは間違いないです。
しかし、意外にもこのHelloStrutsアプリにStruts2の基本全てが詰まっていると言っても過言ではないのでした。
ではこの超ミニアプリケーションを構成する全てのファイルの繋がりを、プロジェクトを実行するところから処理の順番に図解説明してみます。
構成するファイル
- web.xml
- index.jsp
- struts.xml
- HelloStrutsAction.java
- hello.jsp
web.xml
まずは、「web.xml」というファイルの中身から始まります。
web.xmlの重要な役割のうちの一つは、
プロジェクトを実行した時に最初にパソコンのブラウザに表示されるページを決める
ことです。
実行すると・・・↓
もちろん他にも色々と役割はあるのですが、ま・ず・は、これをおさえないことには始まらないのです。
今までEclipseでプロジェクトを実行すると何も意識することなく最初にindex.jspに書いてあるものが表示されていたはずですが、しっかりとここで規定していたのですね。
web.xmlの要点①
<welcome-file-list>
<welcome-file>▲▲.jsp</welcome-file>
</welcome-file-list>
これは、
▲▲.jspファイルの内容でwelcome(最初にお出迎え)します
という意味。
これを覚えたら、Struts2に関わるweb.xmlの次の機能です。
Struts2機能を使うことを宣言
web.xmlファイル上で、Struts2フレームワークの機能を使うことを宣言しないといけません。(一字一句暗記する必要はありません。そんな風に書けばいいんだな、程度で大丈夫です)
これを書かないと、Struts2が機能しないのです。
web.xmlの要点②
<filter>タグ・<filter-mapping>タグで、Struts2の機能を使うことを宣言する
これでStruts2を使う準備が整いました。
※Struts2を使うために必要な.jarファイルをWEB-INF/libフォルダ配下へ置く、とかの説明は省きます
次は、最初に表示されるWebページである「index.jsp」ファイルについて。
index.jspファイル
プロジェクトを実行すると最初に表示されるindex.jspのファイルでは、HelloStrutsと書かれたボタンが一つあるだけです。
しかし一見単純に見えるファイルの中身を見てみると、実はStruts2に関する事が色々と書いてあります。
まずは、ファイルの最初に<%@ taglib prefix="s"〜%>のところで「このファイル内では、"s"を頭につければStruts2の機能を使えるルールにしますよ!」と宣言します。
先ほどweb.xmlファイル内でも「どんなURL(ファイル)だろうとアクセスがあればStruts2の機能を適用しますぜ」と描きましたが、JSPファイル内でもこのように宣言しないといけません。
慣れないうちはこのtaglibディレクティブ(といいます)を書き忘れて「あれ、タグの頭に "s:" 付けてるのにeclipseが認識してくれないぞ!」と焦るときがあります。
もう一つ気をつけるとしたら、よく見るとボタン部分のコードが従来のHTMLコードと少し違うことです。
初見だと慣れないかもしれませんが、これくらいならすぐ慣れます。少しだけ短く簡単になっているので、これは「フレームワークはコードの量が少なくて済む」の例とも言えます。
Struts2を使う時のJSPの要点①
- <%@ taglib prefix="s"〜 でStruts2の利用を宣言する。
- "s:"をタグの頭につけるとStruts2機能を利用できるが、Struts2専用の文法が必要(フレームワークの特徴でしたね)
ボタンを押すとページが飛ぶのはなぜ?(超重要)
そもそもなぜボタンを押すと別のページに飛ぶというアクションが発生するか分かるでしょうか?
僕達はリンクやらボタンをクリックするとページが変わるのは当たり前のことだと思っていますが、その裏側まで考えることはありませんよね。
正解は、ボタンのコード部分を見ると「ボタンが押されたらこの行動を起こせ」という指示が書いてあるからです。
僕の感覚だと、これをすぐに答えられない人が意外と多かったです。
ボタンの中に以下図のように「起こるべき次の行動」がしっかり書いてあるんですね。
もう一度書きます。
このボタンを押すとパソコンのブラウザから「HelloStrutsActionを起こしてね」という依頼が飛びます(しつこいですが、htmlフォームにaction="HelloStrutsAction"と他でもないあなたが書いているからです)。
さて、ここで依頼が飛ぶところまで完了しました。
では、一体誰がその飛んできた依頼を受け取っているのでしょうか?
このボタンを押した瞬間のイメージ図がこちら。
「誰か」にHelloStrutsActionをしてくださいと頼んでいますが、誰に対して?
答えは「Struts2に対して」です。
つまり、「Struts2」がまず一番最初にブラウザからの依頼を受け取ります。
もう少し正確に書くとStruts2の「Interceptor(インターセプタ)」という機能が受け取るのですが、最初は大雑把に「Struts2が受け取る」と覚えておけばいいです。インターセプタはStruts2について調べているといつか必ず目にする用語なので、頭の片隅に置いといて損はしません。ちなみにインターセプタは「横取りする者」という意味なので、何がなんでも一番最初に依頼を受け取るという意味で覚えやすいかもしれませんね。
ここから第1章で説明した「MVCモデル」のM・V・Cそれぞれの役割を思い出しつつ結びつけていってほしいのですが、
Struts2は依頼を受け取ったはいいものの、依頼の「処理実行まではしない」のです。絶対しません。
Struts2は、自分で仕事をせずに他のファイル達を支配して働いてもらうことしか考えていません。
そうです。
Struts2がMVCモデルにおける「C」・コントローラに該当します。
では、依頼を最初に受け取ったStruts2が他のファイルに仕事を振っていく仕組みを見ていきましょう。
理解のカギは「struts.xml」というファイルです。
struts.xmlファイル
まず、Struts2は仕事の割当て表である「struts.xml」というファイルを確認します。
なのでStruts2が依頼を受け取るというよりも「struts.xmlというファイルが依頼を受け取る」とイメージしてしまっても問題ないです。Struts2って言われても「物理的に存在しない概念を想像するのは難しいわボケ!」ってなるので。
このstruts.xmlというファイルの中には、どのファイルがどんな仕事をするかが全て書かれています。
struts.xmlファイルの中身を見て、ボタンが押されて飛んできた「HelloStrutsAction」という処理を誰がやるか決めてたっけ?と確認します。
※なければエラーになります
struts.xmlファイルは今までと比べるとちょっと長いコードになりますが、必要なところだけ意味を考えながら読むと超簡単なのでご安心を。
以下の図でも、強調したところ以外は読まなくてOKです。
無事、htmlフォームから依頼のあった「HelloStrutsAction」と一字一句同じaction nameがあることをチェックしたStruts2は、最後に誰(どのファイル)に働いてもらうかを確認します。
それが、以下「class="..."」で定義されているファイル。このファイル(HelloStrutsAction.java)が処理実行の主体となります。
Struts2は、無事に仕事をさせる「奴隷ファイル」を見つけることができましたね。
あとはStruts2は「HelloStrutsAction.java」というクラスファイルに「executeメソッドを実行しろ!」と命令して、executeメソッド実行結果が返ってくるのを待つだけ。(上図の下線部には method="execute" と書かれている点にも注目してください)
は?executeメソッドってなに?と思ったなら、あなたのお手元のHelloStrutsAction.javaのファイルを開いてみてください。
public String execute() {
return SUCCESS;
}
というメソッドが見つかったはずです。
struts.xmlファイルの要点①
- ブラウザからアクション依頼を受け取ったStruts2がまず最初に確認するのがstruts.xml
- 受け取ったアクション名に紐づいているクラスファイル名と実行すべきメソッド名を探し出す(この例では、HelloStrutsAction.javaにexecuteメソッドを実行させる、と判断する)
さて、ここで処理の実体がStruts2からHelloStrutsAction.javaファイルへと移りましたね。
Struts2から「executeメソッドを実行しやがれ!」と言われたのでした。
今度はHelloStrutsAction.javaファイルが働く番です。
HelloStrutsAction.javaファイル
HelloStrutsAction.javaの中身を見てみましょう。Struts2から「executeメソッド」を実行しろと言われたのですが、何をするのでしょう。
今回のメソッドはとても単純なもので、Struts2に対して「SUCCESS」という文字列をリターンする処理をします。
returnとはそのまんま英単語のイメージ通り、return直後に書かれたものを依頼元のStruts2へと渡すのです。
処理をする役目ということで、HelloStrutsAction.javaというクラスファイルはMVCの「M」・モデルに該当します。
HelloStrutsAction.javaから「SUCCESS」という結果を受け取ったStruts2は、「パソコン画面に結果を表示する準備」にかかります。
ここでも画面表示の準備をするのはStruts2ではありません。また別のファイルへと仕事をさせます。Struts2はコントローラなので指示しかしません。
ではどのようにして仕事をさせるファイルを決めるか?ここでStruts2は再び「struts.xmlファイル」を確認します。
再び、struts.xml
result name、つまりHelloStrutsAction.javaから受け取った結果名が"SUCCESS"だった場合は「hello.jsp」ファイルへ依頼する、という意味です。
あれ?HelloStrutsAction.javaから受け取った結果は「SUCCESS」で大文字、struts.xmlファイルに書いてあるのは「success」で小文字。一致してないじゃん?と思った方は、正しいです(Javaは大文字小文字を厳密に区別します)。
Javaの継承、インターフェースの実装、という理解の話になるのでここでは扱いません。特に今は気にしなくても記事を読み進めるに支障はないです。
気になる方は、こちらの記事を参考 ≫
今回の例では「result name="success"」しか書いていませんが「result name="error"」 で別のファイル名を指定することで、メソッド実行の結果「ERROR」と返ってきた時はエラー表示用のJSPへ誘導する、という風に「返ってきた結果によって表示するJSPを分岐する」ということが可能になります。
さて、これでStruts2の仕事は終わりです。あとはhello.jspが画面表示を頑張るだけ。
struts.xmlファイルの要点②
受け取ったアクション実行結果をもとに、どのJSPファイルへパソコンに画面を返す仕事をさせるか確認する
hello.jsp
では、パソコンに表示される画面を返す依頼を受けたhello.jspファイルの中身を見てみましょう。何を表示するのでしょうか。
<body>の中には、HelloStruts!!(^ ^)しかありませんね。このhello.jspファイルがパソコンのブラウザ画面に送られます。
もう分かるかと思いますが、hello.jspがMVCの「V」・ビューに該当します。ビューという英単語の意味通りにユーザーに見えるところの担当だからです。
これでやっとHelloStrutsボタンを押してから「HelloStruts!!」と表示されるまでの旅が終わりました。
HelloStruts!!と表示されるだけなのにこんな面倒なことが裏側で起きているんですね。
最後に、Struts2をMVCモデルに当てはめた図を。
繰り返しになりますが、MVCは「役割毎にコードを分けて管理する」的な意味だと言いました。
綺麗に3つに分かれていますよね。
今後より複雑なアプリケーションを作るようになって何個のファイルを作成しようとも、基本的にはこの3種類しかありません。
依頼が来る → 処理する → 表示する
これだけです。
そう考えると、少し気が楽になってきませんか?
Struts2 HelloStrutsActionのまとめ
今までは僕の文章やファイルの中身に書いてあるコードでごちゃごちゃしてしまいました。
もう一度イラストだけでHelloStrutsの一連の流れを載せるので、これを見て「なんとなく動きは分かったかな」となってくれば嬉しいです。
これで図解は終わりです。
Struts2の理解度確認問題
せっかくなので、腕試しの問題を用意してみました。記事先頭に戻らずにソラで回答できればもうビギナーは卒業です!
Struts2問題 ①
MVCモデルのM、V、C、それぞれ
- 何の略か
- どんな役割か
を簡潔に答えてください。
【解答例】
M=モデル、処理担当
V=ビュー、画面表示担当
C=コントローラ、指示出し担当
▼第1章のMVCモデルのイメージを再掲。こんな感じで絵で思い浮かべるといいですね。
Struts2問題 ②
以下のように、Eclipseからプロジェクトを実行したとします。
すると直後にwebブラウザに「index.jsp」の内容が表示されました。
ここで、「index.jspを最初に表示する」と規定しているファイルは何ですか?
【解答】
web.xml
Struts2問題 ③
HelloStrutsボタンを押した瞬間、actionを起こすよう飛んできた依頼を最初に受け取るのは誰ですか。
【解答例】
Struts2(のstruts.xml)
【よくある誤答】
Actionクラス
【解説】
まず、JSPのhtmlフォームには、以下のようにaction="..."という「次の行動」が書かれているのでした。
<s:form action="HelloStrutsAction">
<s:submit value="HelloStruts" />
</s:form>
このaction依頼をまず受け取るのは、Struts2です。
受け取ったStruts2はstruts.xmlと照合してどのActionクラスに実際の仕事をさせるのかを決めるのでした。
struts.xmlは、JSPやxxxAction.javaファイルより編集頻度が少ないのでその存在を忘れがちになりつい「JSPのフォーム → Action」という流れだと勘違いしやすいですが、必ず間には全体指揮役としてのStruts2がいることを強く意識してください。
Struts2問題 ④
問題③の「HelloStrutsボタンを押すと、ブラウザにHelloStrutsと表示される」までの一連の流れを可能な限り詳しくノートに書き出してください。
頭の中で考えるだけはNG。途中で書けなくなる=分からないところが分かるようになるメリットがあります。アウトプットのトレーニングです!
【解答例】
ボタンを押すと、formに書いてある「action="HelloStrutsAction"」という次の行動がStruts2へと伝わる。
Struts2は、受け取ったHelloStrutsActionに一致するaction名がstruts.xmlにあるかを確認し、一致したaction名に紐付くActionクラスへ処理を依頼する(executeメソッド等の実行を依頼)
Actionクラスは、処理(executeメソッド)を実行し、その結果得られた"SUCCESS"をStruts2へ返す。
Struts2は、再びstruts.xmlを確認し、返された結果がSUCCESSの場合のJSPファイルを判断。そのJSPファイルへ画面表示を依頼する。
JSPファイルが画面に表示される。【終了】
JSP→Struts.xml→Action→Struts.xml→JSP というファイルの流れを正確に追えていること。
これはコチラの図解を文字化したものなので、文字じゃ分からん!という方は図解をもう一度追ってみてください。
以上、練習問題でした。
これが取っ掛かりとなり、より詳細な理解へと進めば嬉しいです。
関連記事Javaが難しい?Udemyで学習すべし【おすすめ入門講座1選】