Servlet döndürür " HTTP durumu 404 istenen kaynak (/servlet) kullanılamaz"

WebContent/jsps klasörümde bir JSP dosyasında bir HTML formum var. src klasöründeki varsayılan paketimde servlet.java servlet sınıfı var. web.xml /servlet olarak eşlenir .

HTML formunun action özniteliğinde birkaç URL denedim:

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

ama bunların hiçbiri işe yaramadı. Hepsi Tomcat 6/7/8'de aşağıdaki gibi bir HTTP 404 hatası döndürmeye devam ediyor:

HTTP durumu 404 - / servlet

Açıklama : istenen kaynak (/servlet) mevcut değildir.

veya Tomcat 8.5/9:

HTTP durumu 404 - bulunamadı

' : /servlet

Açıklama : Kaynak sunucusu hedef kaynak için geçerli bir temsil bulamadı veya

var olduğunu ifşa etmeye istekli değil

neden çalışmıyor?

61
tarihinde sordu BalusC 2012-07-31 04:02:45
kaynak

3 ответов

servlet sınıfını a package

her şeyden önce, servlet sınıfını bir Java package içine koyun . her zaman bir pakette yeniden kullanılabilir Java sınıfları koymalısınız, aksi takdirde sunucunun kendisi gibi bir pakette olan sınıflara görünmez olurlar. Bu şekilde potansiyel çevreye özgü sorunları ortadan kaldırır. Packageless servlets yalnızca belirli Tomcat+JDK kombinasyonlarında çalışır ve bu asla güvenilmemelidir üzerine.

bir" düz " IDE projesi durumunda, sınıfın "Java Resources" klasörü içindeki paket yapısına yerleştirilmesi gerekir ve böylece "WebContent" değil, bu JSP gibi web dosyaları içindir. Aşağıda, varsayılan bir Eclipse dinamik Web projesi klasör yapısının bir örneği Navigator görünümünde görüldüğü gibi:

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

bir Maven projesi durumunda, sınıf main/java ve böylece değil örneğin main/resources içinde paket yapısına yerleştirilmelidir, bu sınıf dışı dosyalar içindir . Aşağıda Eclipse'in Navigator görünümünde görüldüğü gibi varsayılan Maven webapp projesinin klasör yapısının bir örneği verilmiştir:

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

/jsps alt klasörünün kesinlikle gerekli olmadığını unutmayın. Hatta onsuz yapmak ve doğrudan JSP dosyasını koyabilirsiniz webcontent / webapp kök, ama ben sadece bu senin sorundan devralıyorum.

set servlet URL in url-pattern

servlet URL servlet eşleme "URL deseni" olarak belirtilir. Servlet sınıfının classname/filename tanımına göre kesinlikle değil. URL deseni @WebServlet ek açıklama değeri olarak belirtilmelidir.

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

gibi yol parametrelerini desteklemek istiyorsanız /servlet/foo/bar , daha sonra /servlet/* yerine bir URL deseni kullanın. Ayrıca Bkz. Servlet ve /xyz/{value}/test gibi yol parametreleri, web'de nasıl eşleştirilir.xml?

@WebServlet sadece Servlet 3.0 veya daha yeni

üzerinde çalışır

@WebServlet kullanmak için , yalnızca web.xml dosyanızın, varsa (Servlet 3.0'dan bu yana isteğe bağlı), Servlet 3.0+ sürüm ve dolayısıyla değil, örneğin 2.5 sürümü veya daha düşük . Aşağıda bir Servlet 3.1 uyumlu olanı (Tomcat 8+, WildFly 8+, GlassFish 4+, vb.Ile eşleşen).

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1"
>
    <!-- Config here. -->
</web-app>

veya Servlet 3.0 + ' da olmamanız durumunda (Tomcat 7 veya daha yeni değil, Tomcat 6 veya daha eski değil), @WebServlet ek açıklamasını kaldırın.

package com.example;

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

ve web.xml yerine servlet kayıt şöyle:

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

not böylece her iki yolu da kullanmamalısınız. Kullanın ya da ek açıklama tabanlı yapılandırma configuarion veya XML tabanlı. Her ikisine de sahip olduğunuzda, XML tabanlı yapılandırma ek açıklama tabanlı yapılandırmayı geçersiz kılar.

yapı/dağıtım doğrulama

Eclipse ve / veya Maven gibi bir yapı aracı kullanıyorsanız, derlenmiş servlet sınıf dosyasının /WEB-INF/classes klasöründe paket yapısında bulunduğundan emin olmanız gerekir savaş dosyası üretildi. package com.example; public class YourServlet durumunda, /WEB-INF/classes/com/example/YourServlet.class yer almalıdır . Aksi takdirde, @WebServlet de 404 hatası veya <servlet> durumunda aşağıdaki gibi bir HTTP 500 hatası ile karşı karşıya kalacaksınız:

HTTP durumu 500

hata örneği servlet sınıf com.örnek.YourServlet

ve sunucu log a java.lang.ClassNotFoundException: com.example.YourServlet bulmak, sırayla bir java.lang.NoClassDefFoundError: com.example.YourServlet izledi ardından javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet .

servlet'in doğru bir şekilde derlenmiş olup olmadığını ve classpath'e yerleştirildiğini doğrulamak için kolay bir yol, yapı aracının bir savaş dosyası üretmesine izin vermektir (örn. rightclick project, ihracat > savaş dosyası Eclipse'de) ve içeriğini bir ZİP aracıyla inceleyin. Servlet sınıfı /WEB-INF/classes de eksikse, proje kötü bir şekilde yapılandırılır veya bazı IDE / proje yapılandırma varsayılanları yanlışlıkla geri döndürülür (örneğin Project > Build Automatically Eclipse'de devre dışı bırakıldı). Hiçbir ipucu varsa, en iyi sıfırdan yeniden başlatın ve herhangi bir IDE/proje yapılandırma varsayılan dokunmayın etmektir.

servlet test

, sunucunun localhost:8080 üzerinde çalıştığı ve savaşın /contextname (IDE proje adına varsayılan olarak büyük / küçük harf duyarlı olan) bir bağlam yolunda başarıyla dağıtıldığı şartıyla!) ve servlet başarısız olmadı başlatma (herhangi bir dağıtım/servlet başarı/başarısız mesajlar ve gerçek bağlam yolu ve servlet eşlemesi için sunucu günlüklerini okuyun), daha sonra /servlet URL desenli bir servlet http://localhost:8080/contextname/servlet de kullanılabilir .

sadece bunu test etmek için tarayıcının adres çubuğuna doğrudan girebilirsiniz. doGet() düzgün geçersiz ve uygulanırsa, çıktısını tarayıcıda göreceksiniz. Veya herhangi bir doGet() yoksa veya yanlış çağırırsa super.doGet() , daha sonra bir " HTTP 405: HTTP yöntemi GET bu URL tarafından desteklenmiyor " hatası gösterilecek ( 405 olarak 404'ten hala daha iyi olan servlet'in kendisinin aslında bulunduğunun kanıtıdır).

ve service() , bir MVC çerçevesini yeniden icat etmediğiniz sürece kötü bir uygulamadır-bu, sadece servlet'lerle başlamanız ve mevcut soruda açıklanan problemle ilgili clueless olması pek olası değildir;) Ayrıca bakınız tasarım desenleri web tabanlı uygulamalar .

ne olursa olsun, servlet zaten test edildiğinde 404 döndürüyorsaevcut olarak, bunun yerine bir HTML formuyla denemek tamamen anlamsız. Mantıken, bu nedenle, bir servletten 404 hatayla ilgili sorulara herhangi bir HTML formunu eklemek de tamamen anlamsızdır.

HTML servlet URL referans

servlet'in iyi çalıştığını doğruladıktan sonra tek tek çağrıldığında, HTML'ye ilerleyebilirsiniz. HTML formuyla ilgili somut sorununuza gelince, <form action> değerinin geçerli bir URL olması gerekir. Aynı <a href> için de geçerlidir . Mutlak / göreli URL'lerin nasıl çalıştığını anlamanız gerekir. Bir URL, webbrowser adres çubuğuna girebileceğiniz/görebileceğiniz bir web adresidir. Göreli bir URL'yi form eylemi olarak belirtiyorsanız, yani http:// şeması olmadan, geçerli URL'sine göre olur WebBrowser adres çubuğunda gördüğünüz gibi. Bu nedenle, sunucunun savaş klasör yapısındaki JSP/HTML dosya konumuna göre kesinlikle pek çok yeni başlayanlar gibi görünüyor.

yani , HTML formuna sahip JSP sayfasının http://localhost:8080/contextname/jsps/page.jsp ile açıldığını varsayarsak ve http://localhost:8080/contextname/servlet de bulunan bir servlet'e göndermeniz gerekir , burada birkaç vaka vardır ( <form action> ile <a href> yerine güvenle geçebileceğinizi unutmayın):

  • form eylemi, önde gelen bir eğik çizgi ile bir URL'ye gönderir.

    <form action="/servlet">
    

    önde gelen eğik çizgi / URL'yi etki alanına göre yapar, böylece form

    e gönderir
    http://localhost:8080/servlet
    

    ancak bu muhtemelen yanlış bağlamda olduğu için 404 ile sonuçlanacak.


  • form eylemi, önde gelen bir çizgi olmadan bir URL'ye gönderir.

    <form action="servlet">
    

    bu, URL'yi geçerli URL'nin geçerli klasörüne göre yapar, böylece form

    e gönderir
    http://localhost:8080/contextname/jsps/servlet
    

    ancak bu muhtemelen yanlış klasörde olduğu için 404 ile sonuçlanacaktır.


  • form eylem bir klasör Yukarı gider bir URL gönderir.

    <form action="../servlet">
    

    bu (tam olarak yerel disk dosya sistemi yollarında olduğu gibi) bir klasör Yukarı gidecek!), böyle form

    e gönderilecektir
    http://localhost:8080/contextname/servlet
    

    bu işe yaramalı!


  • kanonik yaklaşım, ancak, JSP dosyalarını başka bir klasöre taşıdığınızda URL'leri bir kez daha düzeltmeniz gerekmeyecek şekilde URL etki alanı göreli yapmaktır.

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

    bu

    üretecek
    <form action="/contextname/servlet">
    
    Böylece her zaman olacak

    doğru URL'ye gönderin.


HTML

düz tırnak kullanın

action="..." veya action='...' ve değil kıvırcık tırnaklar gibi action=”...” veya action=’...’ gibi HTML özniteliklerinde düz tırnak kullandığınızdan emin olmanız gerekir. Kıvırcık tırnak HTML desteklenmez ve onlar sadece değerin bir parçası haline gelecektir.

Ayrıca bakınız:

HTTP durumu 404 hata diğer durumlar:

97
cevap BalusC 2017-11-13 09:47:31
kaynak
NetBeans IDE'DE HTTP Status 404 için

çözümü: Projenize sağ tıklayın ve proje özelliklerinize gidin, ardından Çalıştır'a tıklayın, ardından index.jsp gibi proje göreli URL'sini girin .

  1. Proje- > Özellikler
  2. Çalıştır'a tıklayın
  3. göreli URL: / ındex.JSP (proje kök URL'NİZİ seçin)

enter image description here

0
cevap O R Imon 2018-06-25 14:43:21
kaynak

Senaryo #1: sen yanlışlıkla komut satırından yeniden dağıtıldı tomcat zaten çalıştırırken .

kısa cevap: Tomcat'ı Durdur, hedef klasörü sil , mvn paketi, daha sonra

yeniden dağıtın

Senaryo # 2: isteği.getRequestDispatcher (" MİS_SPELLED_FİLE_NAME .jsp")

kısa cevap: kontrol dosya adı yazım , durumda doğru olduğundan emin olun.


Senaryo # 3: Sınıf Bulunamadı Özel Durumlar (Cevap buraya koydu çünkü: soru # 17982240 ) ( ).dil.Eclipse ile Tomcat içinde servlet için ClassNotFoundException ) (olarak işaretlendi çoğaltın ve beni buraya yönlendirin)

kısa cevap # 3.1: web.xml, servlet sınıfı etiketinde yanlış paket yolu vardır.

kısa cevap #3.2: java dosyası yanlış ithalat deyimi vardır.


aşağıda senaryo için daha fazla detay verilmiştir #1:


1: Durak-Tomcat

  • seçenek 1: terminalde CTRL+C ile.
  • Seçenek 2: (tomcat hala çalışırken Terminal kapalı)
  • ------------ 2.1: basın: Windows + R - > türü: " hizmetleri.msc "
  • ------------ 2.2: "Apache Tomcat" I Bulun.# Tomcat # " listenin adı sütununda.
  • ------------ 2.3: sağ tıklayın -- > " stop "

2: "hedef" klasörünü silin. (mvn temiz olmaz buraya yardım et)

3: mvn paketi

4: YOUR_DEPLOYMENT_COMMAND_HERE

(Mine: java-jar target / dependency/ webapp-runner.jar -- port 5190 hedef/*.savaş )

Full Back Story:


yanlışlıkla yeni bir git-bash penceresi açtı ve bir dağıtmaya çalıştı .heroku projem için savaş dosyası:

java-jar hedef / bağımlılık / webapp-runner.jar -- port 5190 hedef/*.savaş

dağıtmak için bir başarısızlıktan sonra, iki git-bash pencerem olduğunu fark ettim, ve önceki dağıtım durdurmak için CTLR+C kullanmamıştı.

ile tanıştım:

HTTP durumu 404 – bulunamadı türü Durum Raporu

mesajı / ıf-öğrenci testi.jsp

açıklama kaynak sunucusu geçerli bir temsil bulamadı hedef kaynak için veya bunu ifşa etmeye istekli değil oluyor.

Apache Tomcat/8.5.31

aşağıda Senaryo # 3 için daha fazla ayrıntı:


senaryo 3.1: Servlet sınıfı paket yolu yanlış ağında.xml dosyası.

paketi eşleşmelidir üstte açıklama java servlet sınıfından.

dosya: my_stuff/ MyClass.java :

   package my_stuff;

dosya: PRJ_ROOT / src / main/webapp/ WEB-İNF / web.xml

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

senaryo 3.2:

yanlış " paketi " ifadesini koydunuz en tepesinde.java dosyası.

örneğin:

dosya: /my_stuff "klasör

yanlışlıkla yazmak:

package com.my_stuff

bu zor çünkü:

1: maven build (mvn paketi) burada herhangi bir hata bildirmeyecektir.

2: web'deki servlet sınıfı hattı.xml doğru paket yolu olabilir. E. g:

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

Yığın Kullanılmış: Not Defteri++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :

0
cevap J.M.I. MADISON 2018-07-27 03:26:22
kaynak