サーブレットクラスを package
まず、サーブレットクラスをJavaに配置しますpackage
。パッケージには常にパブリックに再利用可能なJavaクラスを配置する必要があります。そうしないと、サーバー自体など、パッケージ内のクラスからは見えません。このようにして、潜在的な環境固有の問題を排除します。パッケージレスサーブレットは特定のTomcatとJDKの組み合わせでのみ機能し、これに依存することはできません。
「プレーン」IDEプロジェクトの場合、クラスは「Javaリソース」フォルダー内のパッケージ構造に配置する必要があり、「WebContent」ではなく、JSPなどのWebファイル用です。以下は、ナビゲータービューに表示されるデフォルトのEclipse ダイナミックWebプロジェクトのフォルダー構造の例です。
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
Mavenプロジェクトの場合、クラスは、そのパッケージ構造の内部に配置する必要がありmain/java
、したがってない例えばmain/resources
、これは非クラスファイルです。以下は、Eclipseのナビゲータービューに表示されるデフォルトのMaven webappプロジェクトのフォルダー構造の例です。
MavenProjectName
|-- src
| `-- main
| |-- java
| | `-- com
| | `-- example
| | `-- YourServlet.java
| |-- resources
| `-- webapp
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
/jsps
サブフォルダは必ずしも必要ではないことに注意してください。これを使わずに、JSPファイルを直接webcontent / webappルートに配置することもできますが、私はこれをあなたの質問から引き継いでいます。
サーブレットURLを設定 url-pattern
サーブレットURLは、サーブレットマッピングの「URLパターン」として指定されます。サーブレットクラスのクラス名/ファイル名は、定義ごとには絶対にありません。@WebServlet
アノテーションの値としてURLパターンを指定します。
package com.example; // Use a package!
@WebServlet("/servlet") // This is the URL of the servlet.
public class YourServlet extends HttpServlet { // Must be public and extend HttpServlet.
// ...
}
のようなパスパラメータをサポートする場合/servlet/foo/bar
は、/servlet/*
代わりにのURLパターンを使用します。/ xyz / {value} / testのようなサーブレットおよびパスパラメータも参照してください。web.xmlでマッピングする方法は?
@WebServlet
サーブレット3.0以降でのみ動作します
使用するためには@WebServlet
、あなただけ必ずあなたのことを確認する必要がありますweb.xml
(それはサーブレット3.0以降オプションです)があれば、ファイル、サーブレット3.0以上のバージョンに準拠宣言されているので、ない例えば2.5バージョンに準拠または下げます。以下は、サーブレット4.0互換のものです(これは、Tomcat 9以降、WildFly 11以降、Payara 5以降などと一致します)。
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
>
<!-- Config here. -->
</web-app>
または、サーブレット3.0以降を使用していない場合(Tomcat 6以前など)は、@WebServlet
注釈を削除します。
package com.example;
public class YourServlet extends HttpServlet {
// ...
}
代わりに、次のweb.xml
ようにサーブレットを登録します。
<servlet>
<servlet-name>yourServlet</servlet-name>
<servlet-class>com.example.YourServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>yourServlet</servlet-name>
<url-pattern>/servlet</url-pattern> <!-- This is the URL of the servlet. -->
</servlet-mapping>
したがって、両方の方法を使用しないでください。注釈ベースの構成またはXMLベースの構成のいずれかを使用します。両方がある場合、XMLベースの構成はアノテーションベースの構成をオーバーライドします。
ビルド/デプロイメントの確認
EclipseやMavenなどのビルドツールを使用している場合は、コンパイルされたサーブレットクラスファイル/WEB-INF/classes
が、生成されたWARファイルのフォルダー内のパッケージ構造に存在することを完全に確認する必要があります。の場合はpackage com.example; public class YourServlet
、に配置する必要があり/WEB-INF/classes/com/example/YourServlet.class
ます。そうしないと@WebServlet
、404エラーが発生した場合、または<servlet>
以下のようなHTTP 500エラーが発生した場合に直面します。
HTTPステータス500
サーブレットクラスcom.example.YourServletのインスタンス化中にエラーが発生しました
そして、ログサーバーに見つけjava.lang.ClassNotFoundException: com.example.YourServlet
、続いてjava.lang.NoClassDefFoundError: com.example.YourServlet
、順番に続きますjavax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
。
サーブレットが正しくコンパイルされ、クラスパスに配置されているかどうかを確認する簡単な方法は、ビルドツールでWARファイル(たとえば、右クリックプロジェクト、Eclipse でエクスポート> WARファイル)を生成し、ZIPツールでその内容を検査することです。でサーブレットクラスが見つから/WEB-INF/classes
ない場合、またはエクスポートによってエラーが発生した場合は、プロジェクトが正しく構成されていないか、一部のIDE /プロジェクト構成のデフォルトが誤って元に戻されています(たとえば、[ プロジェクト]> [自動ビルド]がEclipseで無効になっています)。
また、プロジェクトアイコンにビルドエラーを示す赤い十字がないことを確認する必要もあります。問題の ビュー(ウィンドウ>ビューの表示>その他...)で正確なエラーを見つけることができます。通常、エラーメッセージは適切にグーグル化できます。手がかりがない場合は、最初から再起動し、IDE /プロジェクト構成のデフォルトには触れないことをお勧めします。Eclipseを使用している場合は、Eclipseプロジェクトにjavax.servlet APIをインポートするにはどうすればよいですか?
サーブレットを個別にテストする
サーバーがで実行されlocalhost:8080
ており、WARがのコンテキストパス/contextname
(デフォルトではIDEプロジェクト名、大文字と小文字が区別されます)に正常にデプロイされ、サーブレットがその初期化に失敗しなかった場合(デプロイ/サーブレットの成功/失敗メッセージと実際のコンテキストパスおよびサーブレットマッピング)、URLパターンがのサーブレット/servlet
はで入手できますhttp://localhost:8080/contextname/servlet
。
ブラウザのアドレスバーに直接入力して、個別にテストできます。その場合は、doGet()
適切にオーバーライドして実装されている、あなたは、ブラウザでの出力が表示されます。または、何もないdoGet()
場合、またはが正しく呼び出されない場合super.doGet()
、「HTTP 405:HTTPメソッドGETはこのURLでサポートされていません」エラーが表示されます(405よりも優れているため、405はサーブレットであることを示します自体が実際に見つかります)。
service()
MVCフレームワークを再発明しない限り、オーバーライドは悪い習慣です。これは、サーブレットから始めたばかりであり、現在の質問で説明されている問題について無知である場合は非常に考えにくいです。)デザインパターンのWebベースのアプリケーションも参照してください。
いずれにせよ、個別にテストしたときにサーブレットがすでに404を返している場合は、代わりにHTMLフォームを試してもまったく意味がありません。したがって、論理的には、サーブレットからの404エラーに関する質問にHTMLフォームを含めることもまったく意味がありません。
HTMLからのサーブレットURLの参照
サーブレットが個別に呼び出されたときに正常に機能することを確認したら、HTMLに進むことができます。HTMLフォームに関する具体的な問題については、<form action>
値は有効なURLである必要があります。同じことがにも当てはまります<a href>
。絶対/相対URLがどのように機能するかを理解する必要があります。ご存知のとおり、URLは、Webブラウザーのアドレスバーに入力/表示できるWebアドレスです。相対URLをフォームアクションとして指定する場合、つまりhttp://
スキームを使用しない場合、Webブラウザーのアドレスバーに表示されるように、現在の URL に対して相対的になります。したがって、多くの初心者が考えているように、サーバーのWARフォルダー構造内のJSP / HTMLファイルの場所とはまったく関係ありません。
だから、HTMLフォームでのJSPページがで開かれたと仮定しhttp://localhost:8080/contextname/jsps/page.jsp
て、あなたはに位置サーブレットに提出する必要がありhttp://localhost:8080/contextname/servlet
、ここではいくつかの例(あなたが安全に置き換えることができることに注意してくださいしている<form action>
と<a href>
、ここでは):
フォームアクションは、先頭にスラッシュが付いたURLに送信します。
<form action="/servlet">
先頭のスラッシュ/
はURLをドメインに対して相対的にするため、フォームは
http://localhost:8080/servlet
しかし、これは間違ったコンテキストにあるため、おそらく404になります。
フォームアクションは、先頭にスラッシュを付けずにURLに送信します。
<form action="servlet">
これにより、URLは現在のURLの現在のフォルダーに相対的になります。したがって、フォームは
http://localhost:8080/contextname/jsps/servlet
しかし、間違ったフォルダにあるため、404になる可能性があります。
フォームアクションは、1つ上のフォルダに移動するURLに送信します。
<form action="../servlet">
これにより、1つのフォルダーが上に移動します(ローカルディスクファイルシステムのパスとまったく同じです)。したがって、フォームは
http://localhost:8080/contextname/servlet
これはうまくいくはずです!
ただし、標準的なアプローチでは、JSPファイルを別のフォルダに移動したときにURLを再度修正する必要がないように、URLをドメイン相対にします。
<form action="${pageContext.request.contextPath}/servlet">
これは生成されます
<form action="/contextname/servlet">
したがって、常に正しいURLに送信されます。
HTMLで引用符を使用する
あなたは次のように属性をHTMLに絶対にあなたがまっすぐに引用符を使用しているようにする必要がありaction="..."
、またはaction='...'
、したがって、ないようなカーリークォートaction=”...”
またはをaction=’...’
。中括弧はHTMLではサポートされておらず、単に値の一部になります。
以下も参照してください。
HTTPステータス404エラーの他のケース: