서블릿이 "HTTP 상태 404 요청한 리소스 (/ servlet)를 사용할 수 없습니다."를 반환합니다.


98

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

설명 : 원본 서버가 대상 리소스에 대한 현재 표현을 찾지 못했거나 존재 여부를 공개하지 않습니다.

왜 작동하지 않습니까?

답변:


130

서블릿 클래스를 package

우선 서블릿 클래스를 Java에 넣으십시오 package. 당신은해야한다 항상 그렇지 않으면 같은 서버 자체와 같은 패키지에있는 클래스에 보이지 않는, 패키지에 공개적으로 재사용 가능한 자바 클래스를 넣어. 이렇게하면 잠재적 인 환경 관련 문제를 최소화 할 수 있습니다. 패키지없는 서블릿은 특정 Tomcat + JDK 조합에서만 작동하며 절대로 신뢰할 수 없습니다.

"일반"IDE 프로젝트의 경우 클래스는 "Java Resources"폴더 내의 패키지 구조에 배치되어야하며 따라서 "WebContent"가 아닌 JSP와 같은 웹 파일 용입니다. 다음은 네비게이터 보기에 표시 되는 기본 Eclipse 동적 웹 프로젝트 의 폴더 구조 예제입니다 .

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

Maven 프로젝트의 경우 클래스는 패키지 구조 내부에 배치되어야합니다. main/java 따라서 예를 들어 클래스가 아닌 파일에 대한 것이 아닙니다main/resources . 다음은 Eclipse의 Navigator 보기 에서 볼 수있는 기본 Maven 웹앱 프로젝트의 폴더 구조 예입니다 .

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 패턴"으로 지정됩니다. 정의에 따라 서블릿 클래스의 클래스 이름 / 파일 이름은 절대 아닙니다. URL 패턴은 @WebServlet어노테이션 값으로 지정됩니다 .

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 Servlet 3.0 이상에서만 작동합니다.

사용하려면 @WebServlet, 당신은 당신 있는지 확인해야합니다 web.xml어떤이 (가 서블릿 3.0 이후 옵션의) 경우, 선언 된 파일이 서블릿 3.0 버전을 준수 하므로 하지 예를 들어 2.5 버전을 준수 이하 . 아래는 Servlet 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>

또는 아직 Servlet 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. 그렇지 않으면 @WebServlet404 오류가 발생하거나 <servlet>아래와 같은 HTTP 500 오류가 발생합니다.

HTTP 상태 500

서블릿 클래스 com.example.YourServlet 인스턴스화 오류

그리고 서버 로그에서 a java.lang.ClassNotFoundException: com.example.YourServlet, a 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:8080WAR이 컨텍스트 경로 /contextname(기본값은 IDE 프로젝트 이름, 대소 문자 구분) 에 성공적으로 배포되었으며 서블릿이 초기화에 실패하지 않은 경우 (배포 / 서블릿 성공 / 실패 메시지와 실제 컨텍스트 경로 및 서블릿 매핑) URL 패턴이있는 서블릿 /servlet은에서 사용할 수 있습니다 http://localhost:8080/contextname/servlet.

브라우저의 주소 표시 줄에 직접 입력하여 개별적으로 테스트 할 수 있습니다. 그것의 경우 doGet()제대로 오버라이드 (override) 및 구현, 당신은 브라우저에서 출력을 볼 수 있습니다. 또는 이 URL이 없거나doGet() 잘못 호출 super.doGet()하는 경우 " HTTP 405 : HTTP 메서드 GET이이 URL에서 지원되지 않습니다. "오류가 표시됩니다 (405가 서블릿이 있다는 증거이므로 404보다 낫습니다. 그 자체가 실제로 발견됩니다).

오버 라이딩 service()은 MVC 프레임 워크를 재창조하지 않는 한 나쁜 습관입니다. 서블릿으로 시작하고 현재 질문에 설명 된 문제에 대해 단서가없는 경우에는 가능성이 거의 없습니다.) Design Patterns web based applications를 참조하십시오 .

그럼에도 불구하고 서블릿이 개별적으로 테스트했을 때 이미 404를 반환했다면 HTML 양식을 대신 사용해 보는 것은 전혀 의미가 없습니다. 따라서 논리적으로 서블릿의 404 오류에 대한 질문에 HTML 양식을 포함하는 것은 전적으로 의미가 없습니다.

HTML에서 서블릿 URL 참조

서블릿이 개별적으로 호출 될 때 제대로 작동하는지 확인한 다음 HTML로 이동할 수 있습니다. HTML 양식의 구체적인 문제와 관련하여 <form action>값은 유효한 URL이어야합니다. 에도 동일하게 적용됩니다 <a href>. 절대 / 상대 URL이 어떻게 작동하는지 이해해야합니다. 알다시피 URL은 웹 브라우저의 주소 표시 줄에 입력하거나 볼 수있는 웹 주소입니다. 즉, http://스키마 없이 양식 작업으로 상대 URL을 지정하는 경우 웹 브라우저의 주소 표시 줄에 표시 되는 현재 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가 발생할 가능성이 있습니다.


  • 양식 작업은 한 폴더 위로 이동하는 URL로 제출됩니다.

      <form action="../servlet">
    

    이것은 한 폴더 위로 올라갈 것입니다 (정확히 로컬 디스크 파일 시스템 경로에서와 같습니다!), 양식은

      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에서 지원되지 않으며 단순히 값의 일부가됩니다. 블로그에서 코드 스 니펫을 복사하여 붙여 넣을 때주의하십시오! 일부 블로그 엔진, 특히 Wordpress는 기본적으로 소위 "스마트 따옴표"를 사용하는 것으로 알려져 있습니다. 따라서 이러한 방식으로 코드 스 니펫의 따옴표도 손상됩니다. 반면에 코드를 복사하여 붙여 넣는 대신 코드 위에 직접 입력 해보십시오. 실제로 두뇌와 손가락을 통해 코드를 얻는 또 다른 이점은 장기적으로 코드를 훨씬 더 잘 기억하고 이해할 수 있고 더 나은 개발자가 될 수 있다는 것입니다.

또한보십시오:

HTTP 상태 404 오류의 다른 경우 :


1
glassfish를 사용하여 web-app version = "3.1"을 사용하면 web.xml과 주석에 매핑이있을 때 서블릿을 개별적으로 테스트 할 수있었습니다. 최신 버전이 있으므로 매핑을 제거하고 주석을 남겼지 만 404 오류가 발생합니까?
SallyRothroat

1
이는 서블릿 라이브러리를 제공하기 위해 대상 런타임에 의존하는 대신 웹앱 자체에 서블릿 2.5 또는 이전 라이브러리를 포함하는 경우 발생할 수 있습니다.
BalusC

@xdola : 요청 URI에 의존하기 때문에 실제로 부서지기 쉽습니다. 문제에 대한 설명과 올바른 접근 방식에 대한 답변을 읽으십시오.
BalusC 2011

4

시나리오 # 1 : 당신은 accidentially 다시 배치 바람둥이 동안 명령 줄에서 이미 실행 .

짧은 답변 : Tomcat을 중지하고 대상 폴더 , mvn 패키지를 삭제 한 다음 다시 배포하십시오.


시나리오 # 2 : request.getRequestDispatcher ( " MIS_SPELLED_FILE_NAME .jsp")

짧은 답변 : 파일 이름 철자 를 확인하고 대소 문자 가 올바른지 확인하세요 .


시나리오 # 3 : 클래스를 찾을 수 없음 예외 (Answer put here because : Question # 17982240) ( java.lang.ClassNotFoundException for servlet in tomcat with eclipse ) (중복으로 표시되고 여기로 안내했습니다)

짧은 답변 # 3.1 : web.xml의 servlet-class 태그에 잘못된 패키지 경로가 있습니다.

짧은 답변 # 3.2 : Java 파일에 잘못된 import 문이 있습니다.


다음은 시나리오 # 1에 대한 자세한 내용입니다.


1 : Tomcat 중지

  • 옵션 1 : 터미널에서 CTRL + C를 통해.
  • 옵션 2 : (톰캣이 실행되는 동안 터미널이 닫힘)
  • ------------ 2.1 : 누르기 : Windows + R- > type : " services.msc "
  • ------------ 2.2 : 목록의 이름 열에서 "Apache Tomcat #. # Tomcat #"을 찾습니다.
  • ------------ 2.3 : 오른쪽 클릭-> " stop "

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

배포에 실패한 후 두 개의 git-bash 창이 열려 있고 CTLR + C를 사용하여 이전 배포를 중지하지 않았 음을 깨달았습니다 .

나는 만났다 :

HTTP 상태 404 – 찾을 수 없음 유형 상태 보고서

/if-student-test.jsp 메시지

설명 원본 서버가 대상 자원에 대한 현재 표현을 찾지 못했거나 존재 여부를 공개하지 않습니다.

Apache Tomcat / 8.5.31

다음은 시나리오 # 3에 대한 자세한 내용입니다.


시나리오 3.1 : web.xml 파일에서 servlet-class 패키지 경로가 잘못되었습니다.

자바 서블릿 클래스 맨 위에있는 패키지 문과 일치해야합니다.

파일 : 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-1.0-SNAPSHOT.war과 같이 버전이 지정되고 / AppName /을 시도하는 경우 AppName.war 및 확장 된 폴더 이름이 예상 이름과 일치하지 않습니다.
jla

0

HTTP Status 404NetBeans IDE의 솔루션 : 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 프로젝트 속성으로 이동 한 다음 실행을 클릭 한 다음 index.jsp.

  1. 프로젝트-> 속성
  2. 실행을 클릭하십시오.
  3. 상대 URL : /index.jsp (프로젝트 루트 URL 선택)

여기에 이미지 설명 입력


0

내 문제는 내 메서드에 @RequestBody 주석이 없다는 것입니다. 주석을 추가 한 후 더 이상 404 예외를받지 못했습니다.


0

다음 두 단계를 수행하십시오. 자바 서블릿 애플리케이션을 개발하는 동안 바람둥이 서버에서 "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

스프링 프레임 워크 라이브러리와 같은 오래된 웹 라이브러리를 제거했습니다. 그리고 라이브러리의 새로운 경로를 구축하십시오. 그런 다음 작동합니다.


0

오래된 스레드이지만 다른 곳에서 찾지 못했기 때문에 여기에 한 가지 더 가능성이 있습니다.

servlet-api 3.0+를 사용하는 경우 web.xml에 속성이 포함 되지 않아야metadata-complete="true" 합니다.

여기에 이미지 설명 입력

이것은 주석 web.xml을 사용하는 대신에 제공된 데이터를 사용하여 서블릿을 매핑하도록 tomcat에 지시 합니다 @WebServlet.


0

우선 IDE를 Admin으로 실행하십시오. 그 후 프로젝트 폴더-> 프로젝트 패싯을 마우스 오른쪽 버튼으로 클릭하고 Java 버전이 올바르게 설정되었는지 확인하십시오. 내 PC에서. (예 1.8의 경우) 이제 작동합니다.

cmd를 사용하여 Wildfly와 같은 서버를 시작하지 마십시오. IDE 내에서 실행해야하며 이제 localhost URL을 방문하십시오. 예 : http : // localhost : 8080 / HelloWorldServlet / HelloWorld


0

나를 위해 일한 수정 사항은 (Maven을 사용하는 경우) : 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 Maven-> 프로젝트 업데이트입니다. 이로 인해 JDK 및 기타 라이브러리 (제 경우에는 MySQL 커넥터)에 다른 오류가 발생할 수 있지만 일단 수정하면 원래 문제가 해결되어야합니다!


0

'form'및 'submit'버튼을 사용하지 않고 자바 스크립트로 서블릿을 열려면 다음 코드가 있습니다.

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

0

여기에 MySQL을 사용하는 누군가가 있고 코드가 전날 작동한다고 느꼈지만 지금은 작동하지 않는다고 생각했다면 MySQL CLI 또는 MySQL Workbench를 열고 데이터베이스에 한 번만 연결해야합니다. 연결되면 데이터베이스도 Java 응용 프로그램에 연결됩니다. com.mysql.jdbc.Driver에 문제가 있다는 Hibernate Dialect 오류가 발생했습니다. 일부 컴퓨터의 MySQL에는 시작 문제가 있다고 생각합니다. 이것은 나를 위해 해결되었습니다.


-1

체크하시기 바랍니다 컨텍스트 루트는 비워 둘 수 없습니다 .

eclipse를 사용하는 경우 :을
마우스 오른쪽 버튼으로 클릭 하고 속성 을 선택한 다음 웹 프로젝트 설정 합니다 . 확인 비워 둘 수 없습니다 컨텍스트 루트를

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.