서블릿 클래스를 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;
@WebServlet("/servlet")
public class YourServlet extends 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"
>
</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>
</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 인스턴스화 오류
그리고 서버 로그에서 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:8080
WAR이 컨텍스트 경로 /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 오류의 다른 경우 :