구체적 질의
클라이언트가 서버에 요청을 보낼 때 포함되는 데이터를 다루는 객체
(WEB-INF는 보안 폴더라서 외부에서 접근이 안됨)
1. doGet()
: 데이터 조회
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getRequestURI();
System.out.println("path: " + path);
String method = req.getMethod();
System.out.println("method: " + method);
String queryStrimg = req.getQueryString(); // 구체적 질의 SQL
System.out.println("queryStrimg: " + queryStrimg);
String username = req.getParameter("username");
System.out.println("username: " + username);
String password = req.getParameter("password");
System.out.println("password: " + password);코드 | 설명 |
req.getRequestURI() | 요청한 경로(URI) 가져오기 |
req.getMethod() | HTTP 메서드(GET, POST 등) 가져오기 |
req.getQueryString() | URL의 쿼리 스트링(파라미터 포함된 문자열) 가져오기 |
req.getParameter("username") | username 파라미터 값 가져오기 |
req.getParameter("password") | password 파라미터 값 가져오기 |

2. doPost()
: 새로운 데이터 생성
2-1. BufferedReader 사용
String body = "";
BufferedReader br = req.getReader();
while (true) {
String line = br.readLine();
if (line == null) break;
body = body + line;
}
System.out.println("body: " + body);- BufferedReader를 사용하여 **요청 본문(Body)**의 내용을 읽어들입니다.
- req.getReader()는 POST, PUT 등에서 요청 본문에 포함된 데이터를 읽을 때 사용됩니다.
- 본문의 데이터를 문자열로 받아오기 위해서 각 줄을 읽고, 이를 하나의 문자열(body)에 계속 추가합니다.


2-2. getParameter 사용
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://localhost:8080/hello.do" method="post" enctype="application/x-www-form-urlencoded">
<input type="text" placeholder="Enter username" name="username">
<input type="text" placeholder="Enter password" name="password">
<button type="submit">전송</button>
</form>
</body>
</html>- HTML 코드 : 클릭 하면 데이터가 옮겨짐
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username: " + username);
System.out.println("password: " + password);- req.getParameter()는 쿼리 스트링 또는 폼 데이터에서 파라미터를 가져올 때 사용됩니다.
- 이 코드는 GET 또는 POST 요청에서 URL 파라미터 또는 폼 파라미터의 값을 가져오는 방식입니다.
ex) username=test&password=1234 같은 데이터를 가져올 때 사용됩니다.

3. jsp 파일을 요청했을 때 일어나는 일
@WebServlet("*.do")
public class FrontController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("common logic");
String path = req.getParameter("path");
if (path.equals("a")) {
req.getRequestDispatcher("a.jsp").forward(req, resp);
} else if (path.equals("b")) {
req.getRequestDispatcher("b.jsp").forward(req, resp);
} else if (path.equals("c")) {
req.getRequestDispatcher("c.jsp").forward(req, resp);
} else {
}
}
}<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>A view</h1>
</body>
</html><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>B view</h1>
</body>
</html><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>C view</h1>
</body>
</html>

4. JSP와 Servlet을 활용한 MVC 구현
package org.example.demo9;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
// http://localhost:8080/
@WebServlet("/") // 모든 요청이 여기로 몰린다. ex) /, /abc, /a/b/c
public class DemoServlet extends HttpServlet {
// http://localhost:8080?path=a
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// body -> path=값&name=값
// queryString -> ?path=값&name=값
String path = req.getParameter("path");
if (path.equals("a")) {
req.setAttribute("name", "ssar");
req.getRequestDispatcher(ViewResolver.viewName("a")).forward(req, resp);
} else if (path.equals("b")) {
req.setAttribute("age", 20);
req.getRequestDispatcher(ViewResolver.viewName("b")).forward(req, resp);
}
}
} - 모든 HTTP 요청을 받음 (@WebServlet("/") 설정).
- path 파라미터 값에 따라 다른 JSP 페이지로 포워딩.
- ?path=a → a.jsp 로 이동 (이름 전달)
- ?path=b → b.jsp 로 이동 (나이 전달)
package org.example.demo9;
public class ViewResolver {
private static final String prefix = "/WEB-INF/views/";
private static final String suffix = ".jsp";
public static String viewName(String filename) {
return prefix + filename + suffix;
}
}- ViewResolver.java (뷰 해석기)
- JSP 파일의 경로를 자동으로 만들어 줌.
- 예: ViewResolver.viewName("a") → "/WEB-INF/views/a.jsp"
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>a.jsp</h1>
<h3>내 이름은 : ${name}</h3>
</body>
</html><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>a.jsp</h1>
<h3>내 나이는 : ${age}</h3>
</body>
</html>

4-1. 실행 흐름
- 사용자가 http://localhost:8080?path=a 요청
- DemoServlet이 path=a를 감지하고 name="ssar" 설정
- ViewResolver를 통해 "a.jsp"로 이동
- a.jsp에서 "내 이름은 : ssar" 출력
5. 최종
package org.example.demo10;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.demo10.core.ComponentScan;
import org.example.demo10.core.RequestMapping;
import org.example.demo10.core.ViewResolver;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Set;
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
private Set<Object> controllers;
@Override
public void init(ServletConfig config) throws ServletException {
// 1. 컴포넌트 스캔
ComponentScan componentScan = new ComponentScan(config.getServletContext());
controllers = componentScan.scanClass("org.example.demo10.controller");
//System.out.println(controllers.size());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// localhost:8080/user.do?path=join
String path = req.getParameter("path");
// 2. 라우팅
String templatePath = route(path);
// 3. 리다이렉션
if (templatePath.contains("redirect")) {
String redirectpath = templatePath.replace("redirect:", "");
// resp.setStatus(302);
// resp.setHeader("Location", "?path=" + redirectpath);
resp.sendRedirect("?path=" + redirectpath);
return;
}
// 4. 이동
if (templatePath == null) {
resp.setStatus(404);
resp.getWriter().println("<h1>404 Not Found</h1>");
} else {
req.getRequestDispatcher(ViewResolver.viewName(templatePath)).forward(req, resp);
}
}
private String route(String path) {
for (Object instance : controllers) {
Method[] methods = instance.getClass().getMethods();
for (Method method : methods) {
RequestMapping rm = method.getAnnotation(RequestMapping.class);
if (rm == null) continue; // 다음 for문으로 바로 넘어감
if (rm.value().equals(path)) {
try {
return (String) method.invoke(instance);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
return null;
}
}package org.example.demo10.core;
public class ViewResolver {
private static final String prefix = "/WEB-INF/views/";
private static final String suffix = ".jsp";
public static String viewName(String filename) {
return prefix + filename + suffix;
}
}package org.example.demo10.core;
import jakarta.servlet.ServletContext;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
public class ComponentScan {
private final ServletContext servletContext;
public ComponentScan(ServletContext servletContext) {
this.servletContext = servletContext;
}
// 클래스를 스캔하는 메소드
public Set<Object> scanClass(String pkg) {
Set<Object> instances = new HashSet<>();
try {
// 톰캣의 webapps 폴더 내 WEB-INF/classes 경로 가져오기
String classPath = servletContext.getRealPath("/WEB-INF/classes/");
// C:\Program Files\Apache Software Foundation\Tomcat 11.0\webapps\ROOT\WEB-INF\classes\
File slashDir = new File(classPath);
File dotToSlashDir = new File(slashDir, pkg.replace(".", File.separator));
for (File file : dotToSlashDir.listFiles()) {
// System.out.println(file.getName());
String className = pkg + "." + file.getName().replace(".class", "");
// System.out.println(className);
//
try {
Class cls = Class.forName(className);
if (cls.isAnnotationPresent(Controller.class)) {
// System.out.println("Controller 어노테이션");
Object instance = cls.getDeclaredConstructor().newInstance();
instances.add(instance);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return instances;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}package org.example.demo10.controller;
import org.example.demo10.core.Controller;
import org.example.demo10.core.RequestMapping;
@Controller
public class UserController {
@RequestMapping("join")
public String join() {
System.out.println("UserController join");
return "join";
}
@RequestMapping("login")
public String login() {
System.out.println("UserController login");
return "login";
}
}package org.example.demo10.controller;
import org.example.demo10.core.Controller;
import org.example.demo10.core.RequestMapping;
@Controller
public class BoardController {
@RequestMapping("home")
public String home() {
return "home";
}
}package org.example.demo10.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Controller {
}package org.example.demo10.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestMapping {
String value();
}<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>join page</h1>
</body>
</html><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>login page</h1>
</body>
</html><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>home page</h1>
</body>
</html>

Share article