Servlet mengembalikan "Status HTTP 404 Sumber daya yang diminta (/ servlet) tidak tersedia"


99

Saya memiliki bentuk HTML dalam file JSP di WebContent/jspsfolder saya . Saya memiliki kelas servlet servlet.javadalam paket default saya di srcfolder. Dalam saya web.xmlitu dipetakan sebagai /servlet.

Saya telah mencoba beberapa URL dalam actionatribut bentuk HTML:

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

Tapi tidak ada yang berhasil. Mereka semua terus mengembalikan kesalahan HTTP 404 seperti di bawah ini di Tomcat 6/7/8:

Status HTTP 404 - / servlet

Deskripsi : Sumber daya yang diminta (/ servlet) tidak tersedia.

Atau seperti di bawah ini di Tomcat 8.5 / 9:

Status HTTP 404 - Tidak Ditemukan

Pesan : / servlet

Deskripsi : Server asal tidak menemukan representasi saat ini untuk sumber daya target atau tidak bersedia mengungkapkan keberadaannya

Mengapa tidak berhasil?

Jawaban:


131

Tempatkan kelas servlet di a package

Pertama-tama, letakkan kelas servlet di Java package. Anda harus selalu meletakkan kelas Java yang dapat digunakan kembali secara publik dalam sebuah paket, jika tidak, kelas tersebut tidak akan terlihat oleh kelas yang ada dalam paket, seperti server itu sendiri. Dengan cara ini Anda mengeliminasi potensi masalah khusus lingkungan. Servlet tanpa paket hanya berfungsi dalam kombinasi Tomcat + JDK tertentu dan ini tidak boleh diandalkan.

Dalam kasus proyek IDE "biasa", kelas harus ditempatkan dalam struktur paketnya di dalam folder "Sumber Daya Java" dan bukan "Konten Web", ini untuk file web seperti JSP. Di bawah ini adalah contoh struktur folder dari Proyek Web Dinamis Eclipse default seperti yang terlihat pada tampilan Navigator :

EclipseProjectName
 |-- src
 |    `-- com
 |         `-- example
 |              `-- YourServlet.java
 |-- WebContent
 |    |-- WEB-INF
 |    |    `-- web.xml
 |    `-- jsps
 |         `-- page.jsp
 :

Dalam kasus proyek Maven, kelas perlu ditempatkan dalam struktur paketnya di dalam main/java dan bukan misalnya main/resources, ini untuk file non-kelas . Di bawah ini adalah contoh struktur folder dari proyek webapp Maven default seperti yang terlihat di Eclipse tampilan Navigator :

MavenProjectName
 |-- src
 |    `-- main
 |         |-- java
 |         |    `-- com
 |         |         `-- example
 |         |              `-- YourServlet.java
 |         |-- resources
 |         `-- webapp
 |              |-- WEB-INF
 |              |    `-- web.xml
 |              `-- jsps
 |                   `-- page.jsp
 :

Perhatikan bahwa /jspssubfolder tidak sepenuhnya diperlukan. Anda bahkan dapat melakukannya tanpa itu dan meletakkan file JSP langsung di webcontent / webapp root, tetapi saya hanya mengambil alih ini dari pertanyaan Anda.

Setel URL servlet di url-pattern

URL servlet ditentukan sebagai "pola URL" dari pemetaan servlet. Ini sama sekali bukan per definisi nama kelas / nama file dari kelas servlet. Pola URL harus ditentukan sebagai nilai @WebServletanotasi.

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.
    // ...
}

Jika Anda ingin mendukung parameter jalur seperti /servlet/foo/bar, gunakan pola URL /servlet/*sebagai gantinya. Lihat juga Servlet dan parameter jalur seperti / xyz / {value} / test, bagaimana cara memetakan di web.xml?

@WebServlet hanya berfungsi pada Servlet 3.0 atau yang lebih baru

Untuk menggunakan @WebServlet, Anda hanya perlu memastikan bahwa web.xmlfile Anda , jika ada (opsional sejak Servlet 3.0), dinyatakan sesuai dengan versi Servlet 3.0+ dan dengan demikian tidak sesuai misalnya versi 2.5 atau lebih rendah . Di bawah ini adalah yang kompatibel dengan Servlet 4.0 (yang cocok dengan Tomcat 9+, WildFly 11+, Payara 5+, dll).

<?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>

Atau, jika Anda belum menggunakan Servlet 3.0+ (mis. Tomcat 6 atau lebih lama), hapus @WebServletanotasi tersebut.

package com.example;

public class YourServlet extends HttpServlet {
    // ...
}

Dan daftarkan servlet sebagai gantinya web.xmlseperti ini:

<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>

Perhatikan dengan demikian bahwa Anda tidak boleh menggunakan kedua cara tersebut. Gunakan konfigurasi berbasis anotasi atau konfigurasi berbasis XML. Jika Anda memiliki keduanya, konfigurasi berbasis XML akan menggantikan konfigurasi berbasis anotasi.

Memverifikasi build / deployment

Jika Anda menggunakan alat build seperti Eclipse dan / atau Maven, Anda harus benar-benar memastikan bahwa file kelas servlet yang dikompilasi berada dalam struktur paketnya dalam /WEB-INF/classesfolder file WAR yang dihasilkan. Dalam kasus package com.example; public class YourServlet, itu harus ditempatkan di /WEB-INF/classes/com/example/YourServlet.class. Jika tidak, Anda akan menghadapi jika @WebServletjuga terjadi kesalahan 404, atau dalam kasus <servlet>kesalahan HTTP 500 seperti di bawah ini:

Status HTTP 500

Kesalahan membuat instance kelas servlet com.example.YourServlet

Dan temukan di log server a java.lang.ClassNotFoundException: com.example.YourServlet, diikuti oleh a java.lang.NoClassDefFoundError: com.example.YourServlet, pada gilirannya diikuti oleh javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet.

Cara mudah untuk memverifikasi apakah servlet dikompilasi dan ditempatkan dengan benar di classpath adalah dengan membiarkan alat build menghasilkan file WAR (misalnya proyek klik kanan, Ekspor> file WAR di Eclipse) dan kemudian periksa isinya dengan alat ZIP. Jika kelas servlet tidak ada di /WEB-INF/classes, atau jika ekspor menyebabkan kesalahan, maka proyek tersebut dikonfigurasi dengan buruk atau beberapa default konfigurasi IDE / proyek telah dikembalikan secara keliru (mis. Project> Build Automatically telah dinonaktifkan di Eclipse).

Anda juga perlu memastikan bahwa ikon proyek tidak memiliki tanda silang merah yang menunjukkan kesalahan versi. Anda dapat menemukan kesalahan yang tepat dalam tampilan Masalah ( Window> Show View> Other ... ). Biasanya pesan kesalahan baik-baik saja di Google. Jika Anda tidak tahu, yang terbaik adalah memulai ulang dari awal dan jangan menyentuh default konfigurasi IDE / proyek apa pun. Jika Anda menggunakan Eclipse, Anda dapat menemukan petunjuk di Bagaimana cara mengimpor API javax.servlet di proyek Eclipse saya?

Menguji servlet secara individual

Asalkan server berjalan localhost:8080, dan WAR berhasil diterapkan pada jalur konteks /contextname(yang default ke nama proyek IDE, case sensitive!), Dan servlet tidak gagal inisialisasi (baca log server untuk penerapan / pesan keberhasilan / kegagalan servlet dan jalur konteks aktual serta pemetaan servlet), maka servlet dengan pola URL /servlettersedia di http://localhost:8080/contextname/servlet.

Anda cukup memasukkannya langsung di bilah alamat browser untuk mengujinya secara individual. Jika doGet()itu diganti dan diterapkan dengan benar, maka Anda akan melihat outputnya di browser. Atau jika Anda tidak memiliki doGet()atau jika panggilan salah super.doGet(), maka " HTTP 405: metode HTTP GET tidak didukung oleh URL ini " akan ditampilkan (yang masih lebih baik daripada 404 karena 405 adalah bukti bahwa servlet sendiri sebenarnya ditemukan).

Mengganti service()adalah praktik yang buruk, kecuali Anda menemukan kembali kerangka kerja MVC - yang sangat tidak mungkin jika Anda baru memulai dengan servlet dan tidak mengerti masalah yang dijelaskan dalam pertanyaan saat ini;) Lihat juga Pola Desain aplikasi berbasis web .

Terlepas dari itu, jika servlet sudah mengembalikan 404 saat diuji secara invidivual, maka tidak ada gunanya mencoba dengan bentuk HTML sebagai gantinya. Oleh karena itu, secara logis, itu juga sama sekali tidak ada gunanya untuk memasukkan bentuk HTML dalam pertanyaan tentang kesalahan 404 dari servlet.

Mereferensikan URL servlet dari HTML

Setelah Anda memverifikasi bahwa servlet berfungsi dengan baik saat dipanggil secara individual, Anda dapat melanjutkan ke HTML. Untuk masalah konkret Anda dengan formulir HTML, <form action>nilainya harus berupa URL yang valid. Hal yang sama berlaku untuk <a href>. Anda perlu memahami cara kerja URL absolut / relatif. Anda tahu, URL adalah alamat web seperti yang Anda masukkan / lihat di bilah alamat browser web. Jika Anda menentukan URL relatif sebagai tindakan formulir, yaitu tanpa http://skema, maka URL tersebut menjadi relatif terhadap URL saat ini seperti yang Anda lihat di bilah alamat browser web Anda. Jadi ini sama sekali tidak relatif terhadap lokasi file JSP / HTML dalam struktur folder WAR server seperti yang dipikirkan banyak pemula.

Jadi, dengan asumsi bahwa halaman JSP dengan bentuk HTML dibuka oleh http://localhost:8080/contextname/jsps/page.jsp, dan Anda perlu mengirimkan ke servlet yang terletak di http://localhost:8080/contextname/servlet, berikut adalah beberapa kasus (perhatikan bahwa Anda dapat menggantinya <form action>dengan aman di <a href>sini):

  • Tindakan formulir dikirimkan ke URL dengan garis miring di depan.

      <form action="/servlet">
    

    Garis miring di depan /membuat URL relatif terhadap domain, sehingga formulir akan dikirim

      http://localhost:8080/servlet
    

    Tetapi ini kemungkinan akan menghasilkan 404 karena berada dalam konteks yang salah.


  • Tindakan formulir dikirimkan ke URL tanpa garis miring di awal.

      <form action="servlet">
    

    Ini membuat URL relatif ke folder saat ini dari URL saat ini, sehingga formulir akan dikirim

      http://localhost:8080/contextname/jsps/servlet
    

    Tetapi ini kemungkinan akan menghasilkan 404 karena berada di folder yang salah.


  • Tindakan formulir dikirimkan ke URL yang naik satu folder.

      <form action="../servlet">
    

    Ini akan naik satu folder ke atas (persis seperti di jalur sistem file disk lokal!), Sehingga formulir akan dikirim ke

      http://localhost:8080/contextname/servlet
    

    Yang ini harus berhasil!


  • Pendekatan kanonik, bagaimanapun, adalah membuat URL domain-relative sehingga Anda tidak perlu memperbaiki URL sekali lagi ketika Anda kebetulan memindahkan file JSP ke dalam folder lain.

      <form action="${pageContext.request.contextPath}/servlet">
    

    Ini akan menghasilkan

      <form action="/contextname/servlet">
    

    Yang dengan demikian akan selalu mengirimkan ke URL yang benar.


Gunakan tanda kutip lurus dalam HTML

Anda harus benar-benar memastikan bahwa Anda menggunakan tanda kutip lurus dalam atribut HTML seperti action="..."atau action='...'dan dengan demikian bukan tanda kutip keriting seperti action=”...”atau action=’...’. Tanda kutip keriting tidak didukung dalam HTML dan hanya akan menjadi bagian dari nilai. Hati-hati saat menyalin potongan kode dari blog! Beberapa mesin blog, terutama Wordpress, diketahui secara default menggunakan apa yang disebut "tanda kutip pintar" yang dengan demikian juga merusak tanda kutip dalam cuplikan kode dengan cara ini. Di sisi lain, alih-alih menyalin-tempel kode, coba ketikkan sendiri kode itu. Keuntungan tambahan dari benar-benar mendapatkan kode melalui otak dan jari Anda adalah bahwa itu akan membuat Anda mengingat dan memahami kode jauh lebih baik dalam jangka panjang dan juga membuat Anda menjadi pengembang yang lebih baik.

Lihat juga:

Kasus lain dari kesalahan HTTP Status 404:


1
web-app version = "3.1" menggunakan glassfish, saya dapat menguji servlet saya satu per satu dengan baik ketika saya memiliki pemetaan di web.xml DAN penjelasannya. Saya menghapus pemetaan dan meninggalkan anotasi karena saya memiliki versi terbaru tetapi kemudian saya akan mendapatkan kesalahan 404?
SallyRothroat

1
Itu bisa terjadi jika Anda menyertakan servlet 2.5 atau pustaka yang lebih lama di webapp itu sendiri alih-alih mengandalkan runtime target untuk menyediakan pustaka servlet dengan sendirinya.
BalusC

@xdola: Ini memang rapuh karena bergantung pada URI permintaan. Baca saja jawaban untuk penjelasan masalah Anda dan apa pendekatan yang benar.
BalusC

4

Skenario # 1: Anda secara tidak sengaja menerapkan ulang dari baris perintah saat tomcat sudah berjalan .

Jawaban Singkat: Hentikan Tomcat, hapus folder target , paket mvn, lalu gunakan kembali


Skenario # 2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME .jsp")

Jawaban Singkat: Periksa ejaan nama file , pastikan kapitalisasi sudah benar.


Skenario # 3: Pengecualian Kelas Tidak Ditemukan (Jawaban diletakkan di sini karena: Pertanyaan # 17982240) ( java.lang.ClassNotFoundException untuk servlet di kucing jantan dengan gerhana ) (ditandai sebagai duplikat dan mengarahkan saya ke sini)

Jawaban Singkat # 3.1: web.xml memiliki path paket yang salah dalam tag kelas servlet.

Jawaban Singkat # 3.2: File java memiliki pernyataan impor yang salah.


Di bawah ini adalah rincian lebih lanjut untuk Skenario # 1:


1: Hentikan Tomcat

  • Opsi 1: Melalui CTRL + C di terminal.
  • Opsi 2: (terminal ditutup saat tomcat masih berjalan)
  • ------------ 2.1: tekan: Windows + R -> ketik: " services.msc "
  • ------------ 2.2: Temukan "Apache Tomcat #. # Tomcat #" di kolom Nama daftar.
  • ------------ 2.3: Klik Kanan -> " stop "

2: Hapus folder "target". (mvn clean tidak akan membantu Anda di sini)

3: paket mvn

4: ANDA_DEPLOYMENT_COMMAND_HERE

(Milik saya: java -jar target / dependency / webapp-runner.jar --port 5190 target / *. War)

Cerita Lengkap Lengkap:


Secara tidak sengaja membuka jendela git-bash baru dan mencoba menerapkan file .war untuk proyek heroku saya melalui:

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

Setelah gagal menerapkan, saya menyadari bahwa saya memiliki dua jendela git-bash yang terbuka, dan tidak menggunakan CTLR + C untuk menghentikan penerapan sebelumnya .

Saya bertemu dengan:

Status HTTP 404 - Laporan Status Jenis Tidak Ditemukan

Pesan /if-student-test.jsp

Deskripsi Server asal tidak menemukan representasi saat ini untuk sumber daya target atau tidak bersedia mengungkapkan bahwa ada.

Apache Tomcat / 8.5.31

Di bawah ini adalah rincian lebih lanjut untuk Skenario # 3:


SKENARIO 3.1: Path paket kelas servlet salah di file web.xml Anda.

Ini harus SESUAI dengan pernyataan paket di atas kelas servlet java Anda.

File: my_stuff / MyClass.java :

   package my_stuff;

File: PRJ_ROOT / src / main / webapp / WEB-INF / web.xml

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

SKENARIO 3.2:

Anda meletakkan pernyataan " package " yang salah di atas file myClass.java Anda.

Sebagai contoh:

File ada di: folder " / my_stuff "

Anda salah menulis:

package com.my_stuff

Ini rumit karena:

1: Maven build (paket mvn) tidak akan melaporkan kesalahan apa pun di sini.

2: baris kelas servlet di web.xml dapat memiliki jalur paket yang BENAR. Misalnya:

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

Stack Digunakan: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :


AppName.war Anda dan dengan demikian nama folder yang meledak tidak sesuai dengan nama yang Anda harapkan, misalnya ketika file perang Anda diversi seperti AppName-1.0-SNAPSHOT.war dan Anda mencoba / AppName /.
jla

0

Solusi untuk HTTP Status 404di NetBeans IDE: Klik kanan pada proyek Anda dan buka properti proyek Anda, lalu klik jalankan, lalu masukkan URL relatif proyek Anda seperti index.jsp.

  1. Proyek-> Properti
  2. Klik Jalankan
  3. URL Relatif: /index.jsp (Pilih URL root proyek Anda)

masukkan deskripsi gambar di sini


0

Masalah saya adalah bahwa metode saya kehilangan anotasi @RequestBody. Setelah menambahkan anotasi, saya tidak lagi menerima pengecualian 404.


0

Lakukan dua langkah berikut. Saya berharap, ini akan menyelesaikan masalah "404 not found" di server tomcat selama pengembangan aplikasi java servlet.

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

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


0

Saya menghapus perpustakaan web lama seperti perpustakaan kerangka pegas. Dan membangun jalur perpustakaan baru. Kemudian berhasil.


0

Utas lama, tetapi karena saya tidak menemukannya di tempat lain, berikut satu kemungkinan lagi:

Jika Anda menggunakan servlet-api 3.0+ , web.xml Anda TIDAK boleh menyertakan metadata-complete="true"atribut

masukkan deskripsi gambar di sini

Ini memberitahu kucing jantan untuk memetakan servlet menggunakan data yang diberikan web.xmlalih-alih menggunakan @WebServletpenjelasan.


0

Pertama-tama, jalankan IDE Anda sebagai Admin. Setelah itu, klik kanan folder project -> Project Facets dan pastikan Java Version sudah benar. Di PC saya. (Untuk Contoh 1.8) Sekarang seharusnya berfungsi.

Jangan hanya memulai server Anda, misalnya Wildfly, menggunakan cmd. Ini harus diluncurkan dalam IDE dan sekarang kunjungi URL localhost Anda. Contoh: http: // localhost: 8080 / HelloWorldServlet / HelloWorld


0

Perbaikan yang berhasil untuk saya adalah (jika Anda menggunakan Maven): Klik kanan proyek Anda, Maven -> Perbarui proyek. Ini mungkin memberi Anda beberapa kesalahan lain dengan JDK dan Pustaka lain (dalam kasus saya, konektor MySQL), tetapi setelah Anda memperbaikinya, masalah asli Anda harus diperbaiki!


0

Jika Anda ingin membuka servlet dengan javascript tanpa menggunakan tombol 'form' dan 'submit', berikut adalah kode berikut:

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

Kunci:

1) button-id: Tag 'id' yang Anda berikan ke tombol di file html / jsp Anda.

2) full-servlet-path: Path yang ditampilkan di browser saat Anda menjalankan servlet sendirian


0

Pemetaan di web.xml adalah apa yang telah saya lakukan: -

  1. Jika ada paket lain yang dibuat untuk program baru maka kami harus menyebutkan: -

packagename.filename antara membuka dan menutup tag kelas servlet dalam file xml.

  1. Jika Anda memetakan file Anda dalam xml dan file tersebut tidak berfungsi atau menampilkan kesalahan, maka komentari baris kode anotasi di file masing-masing.

Kedua metode tidak bekerja satu sama lain, jadi saya menggunakan metode anotasi dari file yang disebutkan ketika kami membuat servlet atau cara pemetaan, lalu saya menghapus atau mengomentari baris anotasi. Misalnya:

 <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>

Mengomentari baris kode anotasi di file masing-masing, jika pemetaan dalam xml selesai.

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

0

Jika ada seseorang di sini yang menggunakan MySQL dan merasa bahwa kodenya berfungsi pada hari sebelumnya dan sekarang tidak, maka saya kira Anda harus membuka MySQL CLI atau MySQL Workbench dan cukup buat koneksi ke database sekali. Setelah terhubung, database juga akan terhubung ke Aplikasi Java. Saya dulu mendapatkan kesalahan Dialek Hibernasi yang menyatakan ada yang salah dengan com.mysql.jdbc.Driver. Saya pikir MySQL di beberapa komputer memiliki masalah startup. Ini terpecahkan untuk saya.


0

Jika Anda seorang pelajar dan baru mengenal Java, mungkin ada beberapa masalah yang terjadi dengan file web.xml Anda.

  1. Coba hapus file web.xml.
  2. Kedua, periksa apakah variabel jalur Anda disetel dengan benar atau tidak.
  3. Restart server kucing jantan atau PC Anda.

Masalah Anda pasti akan terpecahkan.


-1

Harap periksa akar konteks tidak boleh kosong .

Jika Anda menggunakan eclipse:
klik kanan , pilih properti , lalu pengaturan proyek web . Periksa akar konteks tidak boleh kosong

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.