인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

zangsu_님의 프로필 이미지
zangsu_

작성한 질문수

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

MVC 패턴 적용 중 404 에러가 납니다. (/servlet-mvc/members/new-form)

작성

·

2.3K

0

강의 정보

MVC 패턴 - 적용 (04 : 14)

에러 내용

http://localhost:8080/servlet-mvc/members/new-form 로 접근하니 다음과 같이 404 에러가 납니다.

MvcMemberFormServlet 클래스는 오타가 있을 경우를 대비해 오류 발생 이후에는 강의 자료의 내용을 복사하여 가져왔습니다.

MvcMemberFormServlet 클래스 내의 service 메서드가 실행되는지 확인하기 위해 System.out.println("MvcMemberFormServlet.service"); 명령어를 사용하였는데, 터미널에서는 출력되지 않습니다.

접근 url도 index.html에서의 링크로 접근을 해서 오타는 없을 것 같습니다.

http://localhost:8080/servlet-mvc/members/new-form 을 제외한 다른 url들은 전부 접근이 잘 되고 있습니다.

아래는 프로젝트 환경과 소스 코드, 터미널 출력입니다!

프로젝트 환경

프로젝트 구조

소스 코드

  • webapp/WEB-INF/views/new-form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 상대경로 사용, [현재 URL이 속한 계층 경로 + /save] -->
<form action="save" method="post">
    username: <input type="text" name="username" />
    age: <input type="text" name="age" />
    <button type="submit">전송</button>
</form>
</body>
</html>
  • java/hello/servlet/web/servletmvc/MvcMemberFormServlet

package hello.servlet.web.servletmvc;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "mvcMemberFormServlet", urlPatterns = "/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("MvcMemberFormServlet.service");
		String viewPath = "/WEB-INF/views/new-form.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
		dispatcher.forward(request, response);
	}
}
  • 터미널 출력

"C:\Program Files (x86)\Java\jdk-17.0.2\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\lib\idea_rt.jar=57706:C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\User\source\BackEnd\study\스프링MVC1\servlet\servlet\build\classes\java\main;C:\Users\User\source\BackEnd\study\스프링MVC1\servlet\servlet\build\resources\main;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.projectlombok\lombok\1.18.26\8f8cf0372abf564913e9796623aac4c8ea44025a\lombok-1.18.26.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-web\2.7.9\e745a069e2b7ca51e378fcbc397d14dd82178199\spring-boot-starter-web-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-jasper\9.0.71\7ea76096eda4d1847fd50d985b1d26fa36a9822a\tomcat-embed-jasper-9.0.71.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\javax.servlet\jstl\1.2\74aca283cd4f4b4f3e425f5820cda58f44409547\jstl-1.2.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-json\2.7.9\671b3611eeb2fb315281ae17242ef082666e4262\spring-boot-starter-json-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter\2.7.9\19f855d327f68690cf630698e4e41c3afe134a83\spring-boot-starter-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-tomcat\2.7.9\a1076e6ffa1d771d3ccd18e72280317a152323e8\spring-boot-starter-tomcat-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-webmvc\5.3.25\62a8258bcc4f7a58dd69af5140481b64653c90\spring-webmvc-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-web\5.3.25\c69815e7931cd3ce7f19cc8028fd1c36626120d6\spring-web-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-core\9.0.71\adaed61b4eaa5b52448336c0881fcd828fd51a2f\tomcat-embed-core-9.0.71.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-el\9.0.71\8fe43848c27ec921c8c5d6dcbd8b959076d7bf99\tomcat-embed-el-9.0.71.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.eclipse.jdt\ecj\3.26.0\4837be609a3368a0f7e7cf0dc1bdbc7fe94993de\ecj-3.26.0.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jsr310\2.13.5\8ba3b868e81d7fc6ead686bd2353859b111d9eaf\jackson-datatype-jsr310-2.13.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.module\jackson-module-parameter-names\2.13.5\a401a99e7a45450fd3ef76e82ba39005fd1a8c22\jackson-module-parameter-names-2.13.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jdk8\2.13.5\1278f38160812811c56eb77f67213662ed1c7a2e\jackson-datatype-jdk8-2.13.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.13.5\aa95e46dbc32454f3983221d420e78ef19ddf844\jackson-databind-2.13.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-autoconfigure\2.7.9\849b238dd024101cad8d107b4a8b0906f75003d5\spring-boot-autoconfigure-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\2.7.9\788d60e73e0f7bbbf11b30c3fb0a9cbaa073446b\spring-boot-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-logging\2.7.9\4b1afa6083581924606c7cc892933b63ec5810d3\spring-boot-starter-logging-2.7.9.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\jakarta.annotation\jakarta.annotation-api\1.3.5\59eb84ee0d616332ff44aba065f3888cf002cd2d\jakarta.annotation-api-1.3.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-core\5.3.25\85382e86321227506bf7f97ed80e2ab88bce25f0\spring-core-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.30\8fde7fe2586328ac3c68db92045e1c8759125000\snakeyaml-1.30.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-websocket\9.0.71\987b6460af04b08bc9914788d2762080afb09541\tomcat-embed-websocket-9.0.71.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-context\5.3.25\268a70ce4f44333ce0f13304c5f8c53b3df5f5f4\spring-context-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-expression\5.3.25\d681cdb86611f03d8ef29654edde219fe5afef1d\spring-expression-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aop\5.3.25\722e30759b29331726f9deed76f80b22345ee627\spring-aop-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-beans\5.3.25\b3aeae036b4ea1abfa1f9604d452e19664efe5f6\spring-beans-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.tomcat\tomcat-annotations-api\9.0.71\898ad20682cb807f734e600ba224d6a3eecaedbc\tomcat-annotations-api-9.0.71.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.13.5\136f77ab424f302c9e27230b4482e8000e142edf\jackson-annotations-2.13.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.13.5\d07c97d3de9ea658caf1ff1809fd9de930a286a\jackson-core-2.13.5.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.2.11\4741689214e9d1e8408b206506cbe76d1c6a7d60\logback-classic-1.2.11.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-to-slf4j\2.17.2\17dd0fae2747d9a28c67bc9534108823d2376b46\log4j-to-slf4j-2.17.2.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.slf4j\jul-to-slf4j\1.7.36\ed46d81cef9c412a88caef405b58f93a678ff2ca\jul-to-slf4j-1.7.36.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jcl\5.3.25\2e65a986dc7f98b40faed8df1d50db77c0b96c61\spring-jcl-5.3.25.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.2.11\a01230df5ca5c34540cdaa3ad5efb012f1f1f792\logback-core-1.2.11.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.36\6c62681a2f655b49963a5983b8b0950a6120ae14\slf4j-api-1.7.36.jar;C:\Users\User\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.17.2\f42d6afa111b4dec5d2aea0fe2197240749a4ea6\log4j-api-2.17.2.jar hello.servlet.ServletApplication
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.9)

2023-03-10 21:21:23.566  INFO 20752 --- [           main] hello.servlet.ServletApplication         : Starting ServletApplication using Java 17.0.2 on LAPTOP-O321EMIC with PID 20752 (C:\Users\User\source\BackEnd\study\스프링MVC1\servlet\servlet\build\classes\java\main started by User in C:\Users\User\source\BackEnd\study\스프링MVC1\servlet\servlet)
2023-03-10 21:21:23.569  INFO 20752 --- [           main] hello.servlet.ServletApplication         : No active profile set, falling back to 1 default profile: "default"
2023-03-10 21:21:24.462  INFO 20752 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-03-10 21:21:24.472  INFO 20752 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-03-10 21:21:24.472  INFO 20752 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.71]
2023-03-10 21:21:24.743  INFO 20752 --- [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2023-03-10 21:21:24.758  INFO 20752 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-03-10 21:21:24.758  INFO 20752 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1120 ms
2023-03-10 21:21:24.965  INFO 20752 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: ServletContext resource [/index.html]
2023-03-10 21:21:25.085  INFO 20752 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-03-10 21:21:25.094  INFO 20752 --- [           main] hello.servlet.ServletApplication         : Started ServletApplication in 1.889 seconds (JVM running for 2.506)
2023-03-10 21:21:37.051 DEBUG 20752 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer      : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [0]
2023-03-10 21:21:37.051 DEBUG 20752 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer      : Received [GET /servlet-mvc/members/new-form HTTP/1.1
Host: localhost:8080
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: JSESSIONID=E3785888BB25462DB7B183BFA52FDD63

]
2023-03-10 21:21:37.079  INFO 20752 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-03-10 21:21:37.079  INFO 20752 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-03-10 21:21:37.080  INFO 20752 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-03-10 21:21:37.174 DEBUG 20752 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer      : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [809]
2023-03-10 21:21:37.174 DEBUG 20752 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer      : Received []
2023-03-10 21:21:37.174 DEBUG 20752 --- [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@48295e2e:org.apache.tomcat.util.net.NioChannel@3716c58c:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8080 remote=/[0:0:0:0:0:0:0:1]:57719]], Status in: [OPEN_READ], State out: [OPEN]
  • build.gradle

plugins {
	id 'java'
	id 'war'
	id 'org.springframework.boot' version '2.7.9'
	id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	//JSP
	implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
	implementation 'javax.servlet:jstl'
	//JSP
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

 

답변 1

1

안녕하세요. zangsu_님, 공식 서포터즈 OMG입니다.
.

코드 조각 일부만 올리셔서 정상적으로 작동하는 프로젝트 코드에

올리신 코드들(new-form.jsp, FormServlet, build.gradle)을 복사하여 확인해보았을 때 정상 실행된것으로 보아 올리신 코드 문제는 아닌 것 같습니다.

올리신 캡쳐 화면 중 ServletApplication이 파랗게 표기된걸로 보아 코드 변경이 있는 것 같은데 아래의 코드가 등록되어 있을까요?

@ServletComponentScan // 서블릿 자동 등록
@ServletComponentScan // 서블릿 자동 등록
@SpringBootApplication
public class ServletApplication
{

    public static void main(String[] args)
    {
        SpringApplication.run(ServletApplication.class, args);
    }

}

코드 작성여부 확인해보시고, 인텔리제이 재 실행했을 때도 동일하게 문제가 발생한다면 프로젝트 코드를 확인해봐야 알 것 같습니다.


.
감사합니다.

zangsu_님의 프로필 이미지
zangsu_
질문자

세상에, 해결 됐습니다!!

강의 진행 도중 몇번의 오류가 있어 프로젝트가 두어번 바뀌었는데, 그 때 코드가 누락되었나 보네요!!

이렇게 간단하게 해결하시다니, 대단하십니다,,!

저런식으로 자바 클래스가 초록색, 파란색인 것은 어떤 차이가 있는건가요??

주말에도 고생 많으십니다, 감사합니다!!!

image

파랗거나 초록색이 표현되는 건 git으로 관리하는 코드들의 상태를 표시해주는 건데요,

우선 올리신 코드 상에 특이점이 없었고

@ServletComponentScan이 없을 때 오류가 발생한다는 것을 알고 있는 상태에서 문제의 원인이지 않을까 싶어서 확인 요청드렸습니다.

zangsu_님의 프로필 이미지
zangsu_
질문자

아하, 클래스들의 색이 오류를 유추하는 단서는 아니었군요...!

아무쪼록 감사합니다!! 덕분에 강의 계속해서 진행할 수 있게 되었네요!!

앞으로도 잘 부탁드립니다 ㅎㅎ

강의 수강 중 강의 관련하여 궁금한 사항은 언제든 질문 남겨주세요 ^^

zangsu_님의 프로필 이미지
zangsu_

작성한 질문수

질문하기