<jsp:useBean>なしで<jsp:getProperty>を使用できないのはなぜですか?

2
Stefan 2021-01-01 08:17.

コードを持つサーブレットがあるとします。

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    foo.Person p = new foo.Person("Evan");
    req.setAttribute("person", p);

    RequestDispatcher view = req.getRequestDispatcher("/result.jsp");
    view.forward(req, resp);
}

、それはresult.jsp名を印刷するために行きます(エヴァン)。これがどのように見えるかの写真です(ソースHead FirstサーブレットとJSP):

同じリクエストスコープ内にあるため、-<jsp:useBean>を呼び出すことで同じPersonオブジェクトが返されることを私は知っています。反対側にいる間、文字通り値「人」の属性を見つけようとするために呼び出します..そして最終的にエヴァンを印刷します。getAttribute()<jsp:getProperty>findAttribute()

しかし、使用しなかった場合は<jsp:useBean>どうなりますか?スコープリクエストで「person」属性にアクセスできなかったということですか?私はそれはまだ私が使用しなかった場合でも、存在することになるわけ<jsp:useBean>.私は同じ持っている必要がありますだから、なぜの両方の内側(「人物」)のID<jsp:useBean>し、名前の内側<jsp:getProperty>?単純な削除<jsp:useBean>は私のプログラムを壊します。

その<jsp:getProperty>呼び出しを知っているとfindAttribute()、スコープページ>リクエスト>セッション>アプリケーションで属性を見つけるための引数として使用される単一の属性(属性名など)があった場合、より論理的ではないでしょうか?なぜこれらの2つのタグを「結び付ける」必要があるのですか:と?<jsp:useBean><jsp:getProperty>

2 answers

2
Live and Let Live 2021-01-01 10:03.

次のコードについてどう思いますか?

public class Main {
    public static void main(String[] args) {
        System.out.println(person);
    }
}

正常にコンパイルされないことをすでに正しく推測している必要があります。

では、次のコードはどうですか?

public class Main {
    public static void main(String[] args) {
        Person person = new Person();// Declaring person
        System.out.println(person);
    }
}

もちろん、コンパイラが何であるかを理解するようになったため、正常にコンパイルされます1person

同様に、

<jsp:getProperty name="person" property="name">

personとして宣言せずに

<!-- Declaring person -->
<jsp:useBean id="person" class="foo.Person" scope="request" />

正常にコンパイルされません


1Person.classそこにあると仮定します。

1
Bogdan 2021-01-02 01:18.

TL; DR:あなたはちょうどあなたが使用する必要があることを覚えておいてください<jsp:getProperty><jsp:useBean>仕様がそう言うので。<jsp:useBean>Beanを<jsp:getProperty>使用する前に、JSPプロセッサにBeanを導入する必要があります。

より長い説明:

なぜ私が使用することはできません<jsp:getProperty>なし<jsp:useBean>

それらは「ある程度」一緒に機能するように設計されていたからです。なぜそのように決定されたのかはわかりませんが(JSP仕様の設計者だけがそれに答えることができます)、仕様自体には次のように書かれてい<jsp:getProperty>ます。

名前で指定されたオブジェクトは、jsp:useBeanアクションまたはこの名前に関連付けられたVariableInfoエントリを持つカスタムアクションのいずれかを使用して、JSPプロセッサに「導入」されている必要があります。オブジェクトがこの方法で導入されなかった場合、ページの実装は仕様に違反しているため、変換エラーを発生させるためにコンテナの実装が推奨されます(必須ではありません)。

一緒に動作するように設計された「やや」と言います。これは、<jsp:getProperty>なし<jsp:useBean>で使用できる場合もありますが、JSP.5.3仕様ルールを無視するようにJSPプロセッサを構成する必要があるためです(これを許可するサーバーの場合)。

これはあまり明確ではないので、いくつかのコードで何が起こるか見てみましょう。

私は次のJSPを持っています:

-------------------------------------------------------------------
<jsp:useBean id="person" class="test.Person" scope="application" />
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<jsp:getProperty name="person" property="name" />
-------------------------------------------------------------------

これらの区切り文字を使用して、後でJSPで生成されたサーブレットでそれらを見つけられるようにしました。これらの区切り文字は、次のコードになります。

  out.write("\t\t-------------------------------------------------------------------\r\n");
  out.write("\t\t");
  test.Person person = null;
  synchronized (application) {
    person = (test.Person) _jspx_page_context.getAttribute("person", javax.servlet.jsp.PageContext.APPLICATION_SCOPE);
    if (person == null){
      person = new test.Person();
      _jspx_page_context.setAttribute("person", person, javax.servlet.jsp.PageContext.APPLICATION_SCOPE);
    }
  }
  out.write("\r\n");
  out.write("\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n");
  out.write("\t\t");
  out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString((((test.Person)_jspx_page_context.findAttribute("person")).getName())));
  out.write("\r\n");
  out.write("\t\t-------------------------------------------------------------------\r\n");

あなたが見れば<jsp:getProperty>、あなたはそれがキャストをしていることがわかりますtest.Person

org.apache.jasper.runtime.JspRuntimeLibrary.toString((((test.Person)_jspx_page_context.findAttribute("person")).getName()))

しかし、それはどこから来たのでしょうか?で<jsp:getProperty>、Bean名(person)とプロパティ名(name)を指定しますが、クラスは指定しません。したがって、これらの属性は結果としてfindAttribute("person")、次に結果のみになりますgetName()。クラスはどこから受けましたか?そしてその答えは、<jsp:useBean>これをJSPプロセッサに導入するための以前の呼び出しです。

したがって<jsp:useBean>、JSPプロセッサにBeanを導入するために呼び出す必要があります。これにより、プロセッサは、処理している<jsp:getProperty>ものを認識したときにそれを認識できます。つまり、基本的に<jsp:useBean>は、それ<jsp:getProperty>を定義してから使用します。を呼び出さないと<jsp:useBean>、は<jsp:getProperty>未定義のものを使用しようとし、JSPプロセッサは文句を言い、次の例外が返されます。

'person'という名前のBeanのjsp:getProperty。名前は、JSP.5.3に従って以前に導入されていませんでした

しかし、仕様を読むと、次のように書かれています。

[...]変換エラーを発生させるためにコンテナの実装が推奨されます(必須ではありません)[...]

たとえば、Tomcatを使用する場合、使用org.apache.jasper.compiler.Generator.STRICT_GET_PROPERTYされるオブジェクトを<jsp:getProperty>以前にJSPプロセッサに「導入」するための要件を制御するシステムプロパティがあります(基本的に、JSP.5.3ルールを適用するかどうか)。たとえば、このTomcatのドキュメントページを参照してください。

したがって、Tomcatサーバーを次のシステム変数で起動すると、次のようになります。

-Dorg.apache.jasper.compiler.Generator.STRICT_GET_PROPERTY=false

それから私は使用することができ<jsp:getProperty>ずに<jsp:useBean>Iご紹介という条件で、personBean内のSCOPEに(とサーブレットからのような他の方法request.setAttribute()session.setAttribute()またはapplication.setAttribute()それがそう<jsp:getProperty>行うことができますpageContext.findAttribute()という名前のBeanのと見てperson、それを見つけることを。

そのシステムプロパティを使用すると、<jsp:getProperty>タグによって生成される出力が変わります。それはもはや依存せず<jsp:useBean>、キャストは削除されます:

out.write("\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n");
      out.write("\t\t");
      out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString(org.apache.jasper.runtime.JspRuntimeLibrary.handleGetProperty(_jspx_page_context.findAttribute("person"), "name")));
      out.write("\r\n");
      out.write("\t\t-------------------------------------------------------------------\r\n");

誰かがこの混乱を展開するのか、すべてに興味がある場合は、(Tomcatサーバー用)を見てクラスは次のとおりorg.apache.jasper.compiler.Validatororg.apache.jasper.compiler.Generator

Related questions

MORE COOL STUFF

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

OxyLEDの新しい15ドルのモーションセンシング常夜灯はどこにでも貼り付けられますが、充電が簡単です

OxyLEDの新しい15ドルのモーションセンシング常夜灯はどこにでも貼り付けられますが、充電が簡単です

私たちの読者は、何千ものOxyLEDのT-02モーションセンサーライトストリップを何年にもわたって購入してきましたが、充電するのが面倒だと感じた場合、新しいT-04は素晴らしいアップグレードのように見えます。T-02のように、 T-04は、付属の粘着ストリップを介して基本的にあらゆる表面に取り付けることができ、暗闇での動きを検出すると自動的に点灯します。

ハンソロ映画セットの写真は、新しいスーツと新しい乗り物を明らかにします

ハンソロ映画セットの写真は、新しいスーツと新しい乗り物を明らかにします

ユニバーサルは、フランケンシュタインの怪物を見つけるのに近いかもしれません。新しい撮影映像でアクマンの舞台裏をご覧ください。

ドナルド・トランプが解雇されたばかりのFBI長官ジェームズ・コミー

ドナルド・トランプが解雇されたばかりのFBI長官ジェームズ・コミー

写真:AP大統領ドナルド・トランプは、連邦捜査局長官のジェームズ・コミーを解雇したばかりです。火曜日の声明で、ホワイトハウスは、トランプが「両方の副検事総長ロッドの明確な勧告に基づいて行動するコミーをオフィスから削除したと述べましたローゼンスタインと司法長官のジェフセッション。

テオドリック大王は、過去の言語と政治的概念に隠された野蛮な将軍でした

テオドリック大王は、過去の言語と政治的概念に隠された野蛮な将軍でした

ウィキメディア・コモンズ経由西部のローマ帝国の中央機関が崩壊し、5世紀の間に州が分裂し、独自の道を進んだとき、新しい王国が出現しました。今日、私たちはこれらの新しい政治単位を特定の野蛮人グループで特定する傾向があります:ガリア南西部の西ゴート族、ガリア北部のフランク人、英国のアングロサクソン人、北アフリカのヴァンダル人。

バレンタインデーにユーカリのシャワースチーマーで「最高の睡眠」を贈りましょう。

バレンタインデーにユーカリのシャワースチーマーで「最高の睡眠」を贈りましょう。

BodyRestore ユーカリ シャワー スチーマーは、Amazon で 11,000 を超える 5 つ星の評価を得ています。セルフケアが必要な人へのバレンタインデーのギフトとして、ホームスパ製品を贈りましょう。

この「邪悪な吸引力」を備えたこの250ドルのハンドヘルド掃除機は、Amazonで75%オフになりました

この「邪悪な吸引力」を備えたこの250ドルのハンドヘルド掃除機は、Amazonで75%オフになりました

多くのAmazonの買い物客がUmlo H6ハンドヘルド掃除機を推奨しており、現在スーパーセール中です. ハンドヘルド デバイスには HEPA フィルターが装備されており、複数のアタッチメントが付属しています。Amazonで75%オフのときにハンドヘルド掃除機を購入する

オクタヴィア・スペンサー、「ザ・ヘルプ」共演者のシシー・スペイセクが17歳で映画のインターンをした後、彼女のことを「実際に」思い出したと語る

オクタヴィア・スペンサー、「ザ・ヘルプ」共演者のシシー・スペイセクが17歳で映画のインターンをした後、彼女のことを「実際に」思い出したと語る

オクタヴィア・スペンサーは、ヘルプで一緒に共演するずっと前に、シシー・スペイセク主演の 1990 年の映画「ロング・ウォーク・ホーム」でインターンとして働いていました。

ジュリア・フォックス、「マスカラ」がTikTokユーザーの性的暴行コードだったことを知らなかったことを謝罪

ジュリア・フォックス、「マスカラ」がTikTokユーザーの性的暴行コードだったことを知らなかったことを謝罪

ジュリア・フォックスは、彼女のTikTokで共有された応答ビデオで、「本当に申し訳ありません。今、本当に年齢を示しています」と述べました。

メリック・ガーランドはアメリカに失敗しましたか?

バイデン大統領の任期の半分以上です。メリック・ガーランドは何を待っていますか?

メリック・ガーランドはアメリカに失敗しましたか?

人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。

良いものと醜いもの: 2022

良いものと醜いもの: 2022

もうわからない。何が「ヒット」かを正確に判断することは、もはやほとんど不可能に思えます。

楽しみのために — 2022 年のトップの新しい音楽再生

楽しみのために — 2022 年のトップの新しい音楽再生

ついに!私の 2022 年のトップ ニューミュージック プレイへようこそ。私は毎年これを共有して、友達とつながります。

ヒーズ・オール・アイヴ・ガット

ヒーズ・オール・アイヴ・ガット

あなたの心をチェックしてください。私たちの心はしばしば迷います。

Language