サーブレットが「HTTPステータス404リクエストされたリソース(/ servlet)は利用できません」を返す


95

WebContent/jspsフォルダー内のJSPファイルにHTMLフォームがあります。フォルダーのservlet.javaデフォルトパッケージにサーブレットクラスがありsrcます。私web.xmlではそれはとしてマッピングされ/servletます。

actionHTMLフォームの属性でいくつかのURLを試しました:

<form action="/servlet">
<form action="/servlet.java">
<form action="/src/servlet.java">
<form action="../servlet.java">

しかし、それらのどれも機能しません。Tomcat 6/7/8では、以下のようなHTTP 404エラーが返され続けます。

HTTPステータス404 — / servlet

説明:要求されたリソース(/ servlet)は利用できません。

または、Tomcat 8.5 / 9の以下のように:

HTTPステータス404-見つかりません

メッセージ:/ servlet

説明:オリジンサーバーがターゲットリソースの現在の表現を見つけられなかったか、存在することを開示しようとしません

なぜ機能しないのですか?

回答:


127

サーブレットクラスを 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エラーの他のケース:


1
web-app version = "3.1"をglassfishを使用して、web.xmlと注釈にマッピングした場合、サーブレットを個別にテストできました。最新バージョンを持っているので、マッピングを削除してアノテーションを残しましたが、404エラーが発生しますか?
SallyRothroat 2018年

1
これは、サーブレットライブラリ自体を提供するためにターゲットランタイムに依存するのではなく、サーブレット2.5以降のライブラリをWebアプリケーション自体に含める場合に発生する可能性があります。
BalusC 2018年

@xdola:リクエストURIに依存しているため、確かに脆弱です。答えを読んで問題の説明と正しいアプローチを教えてください。
BalusC

4

シナリオ#1:あなたはaccidentially再配備 Tomcatがしている間に、コマンドラインからすでに実行されています

短い答え: Tomcatを停止し、ターゲットフォルダー、mvnパッケージを削除してから、再デプロイします


シナリオ#2: request.getRequestDispatcher( " MIS_SPELLED_FILE_NAME .jsp")

短い回答:ファイル名のスペルを確認し、大文字小文字が正しいことを確認してください。


シナリオ#3:Class Not Found Exceptions (Answer here here for:Question#17982240)(java.lang.ClassNotFoundException for servlet in tomcat with eclipse)(重複としてマークされ、ここに指示されました)

短い回答#3.1:web.xmlのservlet-classタグのパッケージパスが間違っています。

短い回答#3.2:Javaファイルに間違ったインポート文があります。


以下は、シナリオ#1の詳細です。


1:Tomcatを停止する

  • オプション1:端末でCTRL + Cを使用。
  • オプション2:(Tomcatの実行中にターミナルを閉じる)
  • ------------ 2.1:押す:Windows + R- >タイプ: " services.msc "
  • ------------ 2.2:リストの[名前]列で「Apache Tomcat#。#Tomcat#」を見つけます。
  • ------------ 2.3:右クリック-> " 停止 "

2:「ターゲット」フォルダーを削除します。 (mvn cleanはここでは役に立ちません)

3:mvnパッケージ

4:YOUR_DEPLOYMENT_COMMAND_HERE

(鉱山:java -jar target / dependency / webapp-runner.jar --port 5190 target / *。war)

完全なバックストーリー:


誤って新しいgit-bashウィンドウを開き、次の方法でherokuプロジェクトの.warファイルをデプロイしようとしました:

java -jar target / dependency / webapp-runner.jar --port 5190 target / *。war

デプロイに失敗した後、2つのgit-bashウィンドウが開いていて、以前のデプロイを停止するためにCTLR + Cを使用ていないことに気付きました

私は会った:

HTTPステータス404 –見つからないタイプのステータスレポート

メッセージ/if-student-test.jsp

説明送信元サーバーがターゲットリソースの現在の表現を見つけられなかったか、存在することを開示しようとしませんでした。

Apache Tomcat / 8.5.31

以下は、シナリオ#3の詳細です。


シナリオ3.1:web.xmlファイルのservlet-classパッケージパスが間違っている。

Javaサーブレットクラスの先頭にあるパッケージステートメントと一致する必要があります。

ファイル:my_stuff / MyClass.java

   package my_stuff;

ファイル:PRJ_ROOT / src / main / webapp / WEB-INF / web.xml

   <servlet-class>
   my_stuff.MyClass
   </servlet-class>

シナリオ3.2:

myClass.javaファイルの先頭に間違った「package」ステートメントを配置しました。

例えば:

ファイルは次の場所にあります: " / my_stuff "フォルダー

あなたは誤って書きます:

package com.my_stuff

これはトリッキーです:

1:mavenビルド(mvnパッケージ)はここでエラーを報告しません。

2:web.xmlのservlet-class行に正しいパッケージパスを含めることができます。例えば:

<servlet-class>
my_stuff.MyClass
</servlet-class>

使用スタック: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10


AppName.warと展開されたフォルダー名が期待した名前と一致しません。たとえば、warファイルのバージョンがAppName-1.0-SNAPSHOT.warであり、/ AppName /を試行している場合などです。
jla 2018年

0

HTTP Status 404NetBeans IDEでの解決策:プロジェクトを右クリックしてプロジェクトのプロパティに移動し、[実行]をクリックして、プロジェクトの相対URLを次のように入力しますindex.jsp

  1. プロジェクト->プロパティ
  2. 実行をクリックします
  3. 相対URL:/index.jsp(プロジェクトのルートURLを選択)

ここに画像の説明を入力してください


0

私の問題は、私のメソッドに@RequestBodyアノテーションがないことでした。注釈を追加した後、404例外を受け取りませんでした。


0

次の2つの手順を実行します。Javaサーブレットアプリケーションの開発中にTomcatサーバーの「404が見つかりません」の問題が解決されることを願っています。

ステップ1: Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server

ステップ2: Double Click on the server(in the server explorer tab)->Select Use tomcat installation option inside server location menu


0

Springフレームワークライブラリである古いWebライブラリを削除しました。そして、ライブラリの新しいパスを構築します。その後、動作します。


0

古いスレッドですが、他の場所では見つけられなかったため、もう1つの可能性があります。

あなたが使用している場合3.0+サーブレットAPIを、そしてあなたのweb.xmlが必要がありませ含まmetadata-complete="true"属性を

ここに画像の説明を入力してください

これはweb.xml@WebServletアノテーションを使用する代わりに、で指定されたデータを使用してサーブレットをマップするようにtomcatに指示します。


0

まず、IDEを管理者として実行します。その後、プロジェクトフォルダーを右クリックし、[プロジェクトファセット]をクリックして、Javaバージョンが正しく設定されていることを確認します。私のPCで。(例1.8の場合)これで動作するはずです。

cmdを使用して、Wildflyなどのサーバーを起動しないでください。IDE内で起動し、localhost URLにアクセスする必要があります。例:http:// localhost:8080 / HelloWorldServlet / HelloWorld


0

私にとってうまくいった修正は(Mavenを使用している場合):プロジェクトを右クリックし、[Maven]-> [プロジェクトの更新]をクリックします。これにより、JDKおよびその他のライブラリ(私の場合はMySQLコネクタ)で他のエラーが発生する可能性がありますが、修正すると、元の問題が修正されます。


0

「フォーム」と「送信」ボタンを使用せずにJavaScriptでサーブレットを開く場合は、次のコードを使用します。

var button = document.getElementById("<<button-id>>");
button.addEventListener("click", function() {
  window.location.href= "<<full-servlet-path>>" (eg. http://localhost:8086/xyz/servlet)
});

キー:

1)button-id:html / jspファイルでボタンに付ける「id」タグ。

2)full-servlet-path:サーブレットを単独で実行したときにブラウザに表示されるパス


0

web.xmlでのマッピングは私がやったことです:-

  1. 新しいプログラム用に作成された別のパッケージがある場合は、次に言及する必要があります。

xmlファイルのservlet-classタグの開始と終了の間のpackagename.filename。

  1. ファイルをxmlでマッピングしていて、それらが機能しない、またはエラーが表示される場合は、それぞれのファイルのコードの注釈行にコメントを付けてください。

どちらの方法も相互に機能しないため、サーブレットの作成時に言及したファイルのアノテーションメソッドまたはマッピングの方法を使用してから、アノテーション行を削除またはコメント化します。例えば:

 <servlet>
   <servlet-name>s1</servlet-name>
   <servlet-class>performance.FirstServ</servlet-class>
   </servlet>    
   
   <servlet-mapping>
   <servlet-name>s1</servlet-name>
   <url-pattern>/FirstServ</url-pattern>
   </servlet-mapping>
   
   <servlet>
   <servlet-name>s2</servlet-name>
   <servlet-class>performance.SecondServ</servlet-class>
   </servlet>
   
   <servlet-mapping>
   <servlet-name>s2</servlet-name>
   <url-pattern>/SecondServ</url-pattern>
   </servlet-mapping>

xmlでマッピングが行われている場合は、各ファイルのコードの注釈行にコメントを付けます。

//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")

-1

コンテキストルートは空にできないことを確認してください

Eclipseを使用している場合:
右クリックして[ プロパティ]を選択し、次に[ Webプロジェクト設定]を選択しますコンテキストルートは空にできないことを確認してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.