[Spring Boot] 4. Request 객체

김미숙's avatar
Mar 20, 2025
[Spring Boot] 4. Request 객체
notion image

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); }
notion image
출력 결과
notion image
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); }
출력 결과
notion image
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로 입력해보기
notion image
출력 결과
⬇ body에 text가 그대로 담긴다
notion image
Postman에서 x-www-formurlencoded로 key, value 넣기
notion image
  • username=ssar 과 password=1234 가 &로 결합되어 ‘username=ssar&password=1234’ 로 전송
➡ ‘username=ssar&password=1234’ 라고 들어오면 getParameter()로 파싱이 가능해짐
출력 결과
notion image

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>
notion image
출력 결과
notion image
 

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

notion image
<%@ 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>
notion image

C - V patton (Controller - View)

notion image

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

Web-inf → 보안폴더 / 외부에서 접근 불가
Web-inf → 보안폴더 / 외부에서 접근 불가
<%@ 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>
출력 결과
notion image
notion image

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>
출력 결과
notion image
notion image

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>
출력 결과
notion image
notion image

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

notion image
notion image
notion image

WEB-INF 폴더(보안폴더) 내의 파일 찾기

‼️
파일을 바로 찾는 것불가능http://localhost:8080/a.jsp (❌)
무조건 단일진입벽(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

notion image
<%@ 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>
출력 결과
notion image
notion image

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>
출력 결과
notion image
 
notion image

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>
출력 결과
notion image

login.jsp

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

templatePath == null

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

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>
notion image
http://localhost:8080/hello.do?path=home 으로 redirect
notion image
 
notion image
notion image
notion image
notion image

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>
notion image
input tag에 ‘ssar’을 입력하면?
notion image
redirection 되서 home 으로 이동
notion image
notion image

home.mustache

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

detail.mustache

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

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

notion image
 
Share article

parangdajavous