HTTP 에러 — 404와 500은 왜 다를까

브라우저에 빨간 에러 화면이 뜨는 순간은 개발자에게 가장 중요한 신호입니다. 숫자가 다르면 의심해야 할 지점도 달라집니다. 직접 눌러서 차이를 느껴봅시다.

상태코드 한눈에

코드의미언제 발생누가 고쳐야 함
200 OK · 정상 요청 처리 성공 -
404 Not Found Controller에 매핑 안 된 URL로 접속 라우팅 추가하거나 주소 오타 확인
400 Bad Request 요청 파라미터가 서버 규칙과 맞지 않음 프론트가 form 필드명/타입 점검
500 Internal Server Error 서버 코드 안에서 예외(Exception)가 터짐 백엔드가 stacktrace 추적

시뮬레이터 — 눌러서 직접 재현해보기

login.jsp

로그인

아이디와 비밀번호를 입력하세요.

404가 났다 — 무엇을 의심해야 할까

"이 URL을 처리할 Servlet이 없다"는 뜻입니다. 서버는 잘 살아있고요. Tomcat이 등록된 @WebServlet 어노테이션 표를 뒤져봐도 매칭되는 게 없으면 404를 돌려줍니다.

주의 — 함정 하나: 만약 어떤 Servlet에 @WebServlet("/") 를 붙여놨다면, 그건 "default servlet" 이 되어서 매칭 안 된 URL까지 전부 그리로 끌려옵니다. 즉, /loign 오타를 쳐도 404가 안 나고 메인 페이지가 떠버려요. 이 경우엔 그 IndexServlet 안에서 path를 검사해서 직접 resp.sendError(404) 를 호출해줘야 합니다.

Servlet에서 명시적으로 404 던지는 코드 (필요할 때만)

// 예: IndexServlet이 @WebServlet("/")로 default servlet 역할일 때
String path = req.getRequestURI().substring(req.getContextPath().length());
if (!path.equals("/") && !path.isEmpty()) {
  resp.sendError(HttpServletResponse.SC_NOT_FOUND);  // 404
  return;
}
// 정상이면 메인 화면으로 안내
resp.sendRedirect("main.jsp");

web.xml로 전용 404 페이지 연결하기

Tomcat의 기본 404 페이지 대신 우리 프로젝트 디자인에 맞는 JSP를 보여주려면 web.xml<error-page> 를 등록해주면 됩니다.

<error-page>
  <error-code>404</error-code>
  <location>/error/404.jsp</location>
</error-page>

500이 났다 — 무엇을 의심해야 할까

"주소는 맞게 왔는데, 그 안에서 내 코드가 터졌다"는 뜻입니다. Controller 또는 Service/DAO 안에서 NullPointerException, DB 연결 실패, SQL 문법 오류 같은 예외가 발생하면 Tomcat이 500을 돌려줍니다.

디버깅 시작점: 500이 나면 Eclipse의 Console 탭(또는 Tomcat log)에 반드시 stacktrace가 찍혀 있습니다. 빨간 글씨 중에서 Caused by: 라인을 먼저 읽으세요. 거기에 진짜 원인이 있습니다. 첫 줄의 500만 보고 포기하면 안 됩니다.

실제 서버 콘솔에서 보는 stacktrace 예시

SEVERE: Servlet.service() for servlet [LoginServlet] threw exception
java.lang.RuntimeException: Failed to obtain JDBC Connection
    at com.edu.service.LoginService.login(LoginService.java:42)
    at com.edu.controller.LoginServlet.service(LoginServlet.java:25)
    ...
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost'
    at org.mariadb.jdbc.Driver.connect(Driver.java:89)

→ 이 경우 원인은 "코드가 이상해서"가 아니라 DB 접속 계정이 틀렸다는 겁니다. 500이 떴다고 Java 코드부터 뒤지면 시간 낭비입니다. Caused by를 읽는 습관이 중요합니다.

한 문장 요약

404는 "매칭되는 Servlet이 없어서" 나는 에러입니다. Servlet 코드는 실행되지 않았고 stacktrace도 없어요. 어노테이션 오타나 파일 누락을 의심하세요.
500은 "Servlet은 실행됐는데 그 안에서 예외가 던져진" 에러입니다. stacktrace가 있고 Caused by: 줄에 진짜 원인이 있어요. DB 연결, SQL 오류, NPE 같은 게 흔한 원인입니다.
이 구분이 디버깅의 출발점입니다.