1

質問の短いバージョン:リクエスト属性「javax.servlet.error.exception」を設定せずに、Scalatra/(Jetty または Tomcat) が実行をErrorHandler のハンドルに渡す原因は何ですか?

より長いものとより多くのコンテキスト: 最近参加したプロジェクトでは、ErrorHandlers のハンドル メソッドに、"javax.servlet.error.exception" 要求属性と他のすべての例外からの例外を処理するための個別のブロックがあります。Jetty でアプリケーションを実行し、Jetty が ServletExceptions をアンラップして上記の属性に配置することを理解しています。「javax.servlet.error.exception」以外の例外を処理するブロックが呼び出される原因は何ですか? それとも冗長で削除できますか?

最初にコードを書いた人がプロジェクトを去りました。残りの技術スタックは、違いがあれば Scala と Scalatra です。

  Option(request.getAttribute("javax.servlet.error.exception"))
  .map { 
    exception => exception match {
         //various exceptions handled
   }.getOrElse(handleStatusCode(currentStatus))

編集: 特定の環境では、コードが Tomcat で実行されるようです。

4

2 に答える 2

0

私は完全な文脈を知りませんが、私は次のシナリオを想像することができました。

<servlet-mapping>
  <servlet-name>ErrorPageServlet</servlet-name>
  <url-pattern>/servlet/errorPage/*</url-pattern>
</servlet-mapping>

<error-page>
  <!--unauthorized-->
  <error-code>401</error-code>
  <location>/servlet/errorPage/401</location>
</error-page>

<error-page>
  <!--internal server error-->
  <error-code>500</error-code>
  <location>/servlet/errorPage/500</location>
</error-page>

上記は基本的に、さまざまなタイプのHTTPエラーに対して「同じErrorPageServletを使用する」と述べています。

"javax.servlet.error.exception"次に、サーブレットで、キャッチされなかった例外があったかどうか(リクエスト属性を確認)、または例外がなかった場合は、HTTP401の原因となった何かがあったかどうかを確認する条件があります。

于 2012-10-05T16:20:02.860 に答える
0

このコードブロックで発生するメソッド呼び出しはいくつかあります。これは、次のコードと同等です。

val a = request.getAttribute("javax.servlet.error.exception")
val b = Option(a)
val c = b.map { exception => /* various exceptions handled... */ }
val d = c.getOrElse(handleStatusCode(currentStatus))

つまり、これaは単なるJava呼び出しです。リクエストで指定された属性を検索し、Objectその属性にマップされた属性、またはのいずれかを返しますnull

bコンストラクターを呼び出して、Option前の結果をOptionでラップします(これは、nullを処理するよりもScala風です)。したがって、aだったnull場合bNone、、そうでない場合はSome、(null以外の)値を含むインスタンスになりますa

次の行で、このオプションは新しい値にマップされます。bだった場合None(つまりaだったnull)、それcからもなりますNone。それ以外の場合、中括弧内のロジックは、内に含まれる値に適用され、bこの結果は。でラップされて返されSomeます。

最後に、オプションがアンラップされます。何らかのc値が含まれている場合、この値自体はブロック全体の結果です。それ以外の場合、is cwas None、thenhandleStatusCode(currentStatus)が評価され、その結果はブロック全体の結果になります。


したがって、is => was => was =>リクエストに属性がマップされていないhandleStatusCode場合にのみ、これが呼び出されると言えます。cNonebNoneanull"javax.servlet.error.exception"

これは通常、当てはまるはずです(たとえば、エラー以外のすべての要求)。そのため、次のようなチェック内にこのブロックが表示された場合にのみ、コードを削除しても安全です。

if (request.getAttribute("javax.servlet.error.exception") != null) {
   ...
   // your posted code
}

取り除いたとしても、何に置き換えますか?Optionが空の場合の結果はどうなりますか?get()オプションを呼び出すことは、この理由から一般的に悪い考えです。空になることがないことがわかっている場合は、上記の行のように折り返す必要はありませんb

于 2012-10-01T16:24:00.483 に答える