
Get
select (get요청)
request의 핵심 method
주소에 붙이는 데이터 -> where에 걸린다
➡ localhost:8080/good.do 의 Request Header에 있는 “User-Agent” 와 “Host” 확인해보기
DemoServlet
package org.example.demo6;
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;
@WebServlet("*.do")
public class DemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// select (get요청)
// request의 핵심 method
// 주소에 붙이는 데이터 -> where에 걸린다
String method = req.getHeader("User-Agent");
System.out.println("User-Agent:" + method);
String Host = req.getHeader("Host");
System.out.println("Host:" + Host);
}

✅ 출력 결과

➡ localhost:8080/demo.do?username=ssar&password=1234 를 입력했을 때
path, method, queryString, username, password 가 어떻게 나오는지 확인해보기
DemoServlet
package org.example.demo6;
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;
// localhost:8080/demo.do?username=ssar&password=1234
@WebServlet("*.do")
public class DemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// select (get요청)
// request의 핵심 method
// 주소에 붙이는 데이터 -> where에 걸린다
String path = req.getRequestURI();
System.out.println("path: " + path);
String method = req.getMethod();
System.out.println("method: " + method);
String queryString = req.getQueryString(); // 구체적 질의를 하기 위해 필요 = sql where
System.out.println("queryString: " + queryString);
String username = req.getParameter("username"); // 키값을 꺼내서 값을 얻을때
System.out.println("username: " + username);
String password = req.getParameter("password"); // 키값을 꺼내서 값을 얻을때
System.out.println("password: " + password);
}
✅ 출력 결과

➡
Request
에 있는 정보 확인해보기DemoServlet
package org.example.demo6;
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;
import java.util.Enumeration;
@WebServlet("*.do")
public class DemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = req.getHeader(headerName);
System.out.println(headerName + ": " + headerValue);
}
}
✅ 출력 결과
⬇
Request
에 들어있는 정보host: localhost:8080
connection: keep-alive
sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"
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/134.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: none
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
accept-encoding: gzip, deflate, br, zstd
accept-language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Post
DemoServlet
// insert
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String body = "";
BufferedReader br = req.getReader();
while (true) {
String line = br.readLine();
if (line == null) break;
body = body + line;
}
System.out.println("body: " + body);
}
}
➡ Postman에서 text로 입력해보기

✅ 출력 결과
⬇ body에 text가 그대로 담긴다

➡ Postman에서 x-www-formurlencoded로 key, value 넣기

- username=ssar 과 password=1234 가 &로 결합되어 ‘username=ssar&password=1234’ 로 전송
➡ ‘username=ssar&password=1234’ 라고 들어오면
getParameter()
로 파싱이 가능해짐✅ 출력 결과

DemoServlet
// insert
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username: " + username);
System.out.println("password: " + password);
index.html
<!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>

✅ 출력 결과

HomeServlet
package org.example.demo7;
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;
@WebServlet("/home.jsp")
public class HomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Content-Type", "text/html");
String name = "홍길동";
String body = """
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Home Page</h1>
<hr>
${name}
</body>
</html>
""".replace("${name}", name);
resp.getWriter().println(body);
}
}
home.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Home Page</h1>
<hr>
<%
String name = "홍길동";
%>
<%=name%>
</body>
</html>

C - V patton (Controller - View)

FrontController
package org.example.demo8;
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;
// localhost:8080/hello.do?path=a
@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");
String name = "ssar";
if (path.equals("a")) {
req.setAttribute("name", name);
req.getRequestDispatcher("a.jsp").forward(req, resp);
} else if (path.equals("b")) {
req.setAttribute("name", name);
req.getRequestDispatcher("b.jsp").forward(req, resp);
} else if (path.equals("c")) {
req.setAttribute("name", name);
req.getRequestDispatcher("c.jsp").forward(req, resp);
} else {
}
}
}
a.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>A view</h1>
<%
String name = (String) request.getAttribute("name"); // object -> String (다운캐스팅)
%>
<h3>값: <%=name%>
</h3>
</body>
</html>
✅ 출력 결과


b.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>B view</h1>
<h3>${name}</h3>
</body>
</html>
✅ 출력 결과


c.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>C view</h1>
<h3>${name}</h3>
</h3>
</body>
✅ 출력 결과


⚠ But, 파일명으로도 찾는 게 가능하다 → Common Logic을 타지 않음



WEB-INF 폴더(보안폴더) 내의 파일 찾기
무조건 단일진입벽(Controller)을 통해 찾는다 → Common Logic 수행
DemoServlet
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);
}
}
}
ViewResolver
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;
}
}
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>
✅ 출력 결과


b.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>b.jsp</h1>
<h3>내 나이는: ${age}</h3>
</body>
</html>
✅ 출력 결과


DispatcherServlet
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 == 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;
}
}
ComponentScan
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);
}
}
}
ViewResolver
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;
}
}
UserController
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";
}
}
BoardController
package org.example.demo10.controller;
import org.example.demo10.core.Controller;
@Controller
public class BoardController {
}
Annotation / @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.TYPE)
public @interface Controller {
}
Annotation / @RequestMapping
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();
}
join.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>join page</h1>
</body>
</html>
✅ 출력 결과

login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>login page</h1>
</body>
</html>
✅ 출력 결과

templatePath == null
➡ path가 ‘join’ 이나 ‘login’ 이 아니면
resp.setStatus(404);
resp.getWriter().println("<h1>404 Not Found</h1>");
✅ 출력 결과

Redirection
DispatcherServlet
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. redirection
// localhost:8080/user.do?path=login
if (templatePath.contains("redirect:")) {
String redirectPath = templatePath.replace("redirect:", ""); // home
// 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;
}
}
home.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>home page</h1>
</body>
</html>
➡ http://localhost:8080/hello.do?path=login 입력하면?

➡ http://localhost:8080/hello.do?path=home 으로 redirect





BoardController
package org.example.hello.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class BoardController {
// localhost:8080/detail
@GetMapping("/detail")
public String detail() {
return "detail";
}
// localhost:8080/home
@GetMapping("/home")
public String home() {
return "home";
}
}
UserController
package org.example.hello.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class UserController {
// 줄게 -> 회원가입 정보
// localhost:8080/join
// body : username=ssar
// header : Content-Type : application/x-www-form-urlencoded
@PostMapping("/join")
public String join(String username) {
// 1. DB insert
System.out.println("username: " + username);
// 2. 응답
return "redirect:/home";
}
// 줘 -> 회원가입 페이지
@GetMapping("/join-form")
public String joinForm() {
return "join-form";
}
}
join-form.mustache
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>회원가입 페이지</h1>
<form action="/join" method="post">
<input type="text" name="username" placeholder="Enter username">
<button type="sumit">회원가입</button>
</form>
</body>
</html>

⬇ input tag에 ‘ssar’을 입력하면?

⬇ redirection 되서 home 으로 이동


home.mustache
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>홈 페이지</h1>
</body>
</html>

detail.mustache
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>상세보기 페이지</h1>
</body>
</html>

M - C - V patton (Model - Controller - View)

Share article