10 ๋ถ„ ์†Œ์š”

๐Ÿ’กRefferecne [์™ธ๋ถ€ ๋งํฌ]์Šคํ”„๋ง MVC 1ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ•ต์‹ฌ ๊ธฐ์ˆ 

  1. Spring MVC 1 - Servlet

1. ๊ฐœ์š”

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์—†๋˜ ์‹œ์ ˆ๋กœ ๋Œ์•„๊ฐ€์„œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ ํŽ˜์ด์ง€๋ฅผ ์ฐพ์•„๋‚ด๊ณ  ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ(Payload) ๋ฅผ ๊ฐ€๊ณตํ•˜์—ฌ ์ฒ˜๋ฆฌ, ์‘๋‹ตํ•˜์˜€๋Š”์ง€ ์•Œ์•„๋ณด์ž. ๋˜ํ•œ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์˜ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํ˜•ํƒœ์˜ ๋‚˜๋งŒ์˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ง์ ‘ ์ œ์ž‘ํ•ด๋ณด์ž.

2. Servlet

์šฐ์„  ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์šฉ์–ด๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ๋„˜์–ด๊ฐ€์ž.

  • Web Server
    • ์ •์  ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์„ ์ œ๊ณต
    • ์ž˜ ๋‹ค์šด๋˜์ง€ ์•Š๊ณ  ๋น„์šฉ์ด ์ ์Œ
    • Nginx, Apache ๋“ฑ
  • WAS (Web Application Server)
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์„ ์ด์šฉํ•˜์—ฌ ๋™์ ์ธ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜ (์ •์  ๋ฆฌ์†Œ์Šค๋„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Œ)
    • ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ (JAVA์˜ ๊ฒฝ์šฐ Servlet)
    • ๋‹ค์šด ๋นˆ๋„๊ฐ€ ๋†’๊ณ  ๋น„์šฉ์ด ๋น„์Œˆ
    • Tomcat, Jetty ๋“ฑ

[Servlet ์ด๋ž€?]

์›๋ž˜๋Œ€๋กœ๋ผ๋ฉด ๊ฐœ๋ฐœ์ž๋Š” HTTP ํ†ต์‹ ์„ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…๋“ค์„ ํ•ด์•ผ ํ•œ๋‹ค.

  • ์†Œ์ผ“ ์—ฐ๊ฒฐ
  • ์ „๋ฌธ ํŒŒ์‹ฑ
  • ํ—ค๋” ํ™•์ธ
  • ์ž์› ์œ„์น˜ ํ™•์ธ
  • ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ์‹คํ–‰
  • ์‘๋‹ต ์ „๋ฌธ ์ƒ์„ฑ
  • ์†Œ์ผ“ ์ข…๋ฃŒ

ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •๋“ค์„ ๋ชจ๋“  ํ†ต์‹ ๋งˆ๋‹ค ์ง€์—ฝ์ ์œผ๋กœ ๊ด€๋ฆฌ/๋ฐ˜๋ณต ํ•ด์ฃผ๋Š” ๊ฒƒ์€ ์ƒ์‚ฐ์„ฑ์ด ๋งค์šฐ ๋–จ์–ด์ง€๋Š” ์ž‘์—…์ด ๋  ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ์œ„ํ•ด Servlet ์—์„œ๋Š” ์š”์ฒญ๊ณผ ์‘๋‹ต์„ Request ์™€ Response ๋กœ ์ถ”์ƒํ™” ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ์ž์ฒด์— ์ง‘์ค‘ํ•˜๋„๋ก ๋„์™€์ค€๋‹ค.

์•ž์„œ WAS๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์— ๋Œ€ํ•ด ๋™์ ์œผ๋กœ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ํ•˜์˜€๋‹ค. ์ด ๋•Œ JAVA ๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์— ์‘๋‹ตํ•˜๊ธฐ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ”๋กœ Servlet ์ด๋‹ค.

ํ•˜๋‚˜์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์š”์ฒญ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ (ํšŒ์›๊ฐ€์ž… ์š”์ฒญ, ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ์š”์ฒญ ๋“ฑ) ๋ณต์ˆ˜ ๊ฐœ์˜ ์„œ๋ธ”๋ฆฟ์„ WAS ์— ๋“ฑ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ๋ณต์ˆ˜์˜ ์„œ๋ธ”๋ฆฟ์„ ์ˆ˜์šฉํ•˜๋ฉฐ ์ง€์›ํ•˜๋Š” ํ†ฐ์บฃ๊ณผ ๊ฐ™์€ WAS ๋ฅผ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•œ๋‹ค.

ํ†ฐ์บฃ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ

์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํ•˜๋Š” ์ž์„ธํ•œ ์—ญํ• ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๊ฐ ์š”์ฒญ์— ๋Œ€ํ•œ ์“ฐ๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ
  • ์š”์ฒญ๋ฐ›์€ ์ž์› ์œ„์น˜์™€ ์„œ๋ธ”๋ฆฟ ๋งคํ•‘ (URL ๋งคํ•‘)
  • ์„œ๋ธ”๋ฆฟ ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ (์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌ ๋จ)

์—ฌ๊ธฐ์„œ ์„œ๋ธ”๋ฆฟ์˜ ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž๋ฉด, ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ํŠน์ • ์„œ๋ธ”๋ฆฟ์˜ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•ด๋‹ฌ๋ผ๋Š” ์š”์ฒญ์„ ๋ฐ›๊ณ  ๋‚œ ๋’ค ํ•ด๋‹น ์„œ๋ธ”๋ฆฟ์ด ์ดˆ๊ธฐํ™”(์ธ์Šคํ„ด์Šค ์ƒ์„ฑ) ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด init() ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๊ณ , ์ด๋ฏธ ์ƒ์„ฑ ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด ์„œ๋ธ”๋ฆฟ์˜ service() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

์ด ๋•Œ ์„œ๋ธ”๋ฆฟ ๋‚ด์—์„œ ์–ด๋–ค HTTP ๋ฉ”์†Œ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ• ์ง€ ๋ถ„๊ธฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒ์„ฑ ๋œ ์„œ๋ธ”๋ฆฟ์€ ์ž„์˜๋กœ ์ข…๋ฃŒํ•˜์ง€ ์•Š์œผ๋ฉด ํ†ฐ์บฃ์ด ์ข…๋ฃŒ๋  ๋•Œ destroy() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ข…๋ฃŒํ•œ๋‹ค.

[Servlet ์ƒ๋ช…์ฃผ๊ธฐ]

Servlet Lifecycle

์„œ๋ธ”๋ฆฟ์— ๋Œ€ํ•œ ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜๋ฉด ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๋Š” ์šฐ์„  ํ•ด๋‹น ์„œ๋ธ”๋ฆฟ์ด ์ƒ์„ฑ(์ธ์Šคํ„ด์Šค ํ™”) ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

์ƒ์„ฑ ๋œ ์„œ๋ธ”๋ฆฟ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด init() ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์„œ๋ธ”๋ฆฟ์€ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด์— ๋งŒ๋“ค์–ด์ง„ ์„œ๋ธ”๋ฆฟ์ด ์กด์žฌํ•œ๋‹ค๋ฉด service() ๋ฉ”์†Œ๋“œ๋กœ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๋งŒ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๋งŒ๋“ค์–ด์ง„ ์„œ๋ธ”๋ฆฟ๋“ค์€ ํ†ฐ์บฃ ์ข…๋ฃŒ ์‹œ destroy() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ข…๋ฃŒํ•œ๋‹ค.

[Servlet ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ธฐ]

์ด์ œ๋ถ€ํ„ฐ ์„œ๋ธ”๋ฆฟ์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์— ์‘๋‹ตํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด๋ณด์ž. ์šฐ์„  start.spring.io Spring Web ๋ฐ Lombok ์ •๋„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ธํŒ…ํ•œ๋‹ค. (gradle, Java 11, Spring 2.7.x, war)

SpringBoot ์—์„œ๋Š” ๋ฉ”์ธ ์‹คํ–‰ ์ง€์ ์˜ @SpringBootApplication ์• ๋…ธํ…Œ์ด์…˜ ์œ„์— @ServletComponentScan ์• ๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ์„œ๋ธ”๋ฆฟ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•œ๋‹ค.

1
2
3
4
5
6
7
@ServletComponentScan
@SpringBootApplication
public class FrameworkApplication {
	public static void main(String[] args) {
		SpringApplication.run(FrameworkApplication.class, args);
	}
}

์ฒซ๋ฒˆ์งธ ์„œ๋ธ”๋ฆฟ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด @WebServlet ์• ๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ  HttpServlet ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„œ๋ธ”๋ฆฟ์˜ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ์‹คํ–‰๋ถ€์ธ service() ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜์—ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•œ๋‹ค.

์šฐ์„  ๊ฐ„๋‹จํ•˜๊ฒŒ ์š”์ฒญ๊ณผ ์‘๋‹ต ์ •๋ณด, ์ฟผ๋ฆฌ์ŠคํŠธ๋ง ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋„๋ฅผ ์ถœ๋ ฅํ•ด๋ณด์ž. ์„œ๋ธ”๋ฆฟ์— ์‘๋‹ต์„ ์ „๋‹ฌํ• ๋•Œ์—๋Š” response ๊ฐ์ฒด์— ์ง์ ‘ ์‘๋‹ต ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Slf4j
@WebServlet(name = "hello", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        log.info("HelloServlet.service");
        log.info("request : {}", request);
        log.info("response: {}", response);

        String parameter = request.getParameter("parameter");
        log.info("parameter : {}", parameter);

        response.setContentType("text/plain");
        response.setCharacterEncoding("utf-8");
        response.getWriter().write("response :" + parameter);
    }
}
1
2
3
4
2023-10-19 14:43:07.538  INFO 7851 --- [nio-8080-exec-3] me.jwjung.framework.basic.HelloServlet   : HelloServlet.service
2023-10-19 14:43:07.538  INFO 7851 --- [nio-8080-exec-3] me.jwjung.framework.basic.HelloServlet   : request : org.apache.catalina.connector.RequestFacade@7d506757
2023-10-19 14:43:07.538  INFO 7851 --- [nio-8080-exec-3] me.jwjung.framework.basic.HelloServlet   : response: org.apache.catalina.connector.ResponseFacade@17537908
2023-10-19 14:43:07.539  INFO 7851 --- [nio-8080-exec-3] me.jwjung.framework.basic.HelloServlet   : parameter : hello

3. Servlet ํ™œ์šฉ

์ด์ œ๋ถ€ํ„ฐ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์„œ๋ธ”๋ฆฟ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ํšŒ์›๊ฐ€์ž… ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด ๋ณผ ์˜ˆ์ •์ด๋‹ค. ์„œ๋ธ”๋ฆฟ์€ MVC ํŒจํ„ด์—์„œ ์ปจํŠธ๋กค๋Ÿฌ ์—ญํ• ์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋„๋ฉ”์ธ์„ ๋‹ด๋‹นํ•  ํšŒ์›๊ณผ ํšŒ์›๊ฐ์ฒด์— ๋Œ€ํ•œ ์ €์žฅ์†Œ๋ฅผ ๋จผ์ € ๊ตฌํ˜„ํ•ด๋ณด์ž.

  • ํšŒ์› ๊ฐ์ฒด
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Getter
@EqualsAndHashCode
public class Member {

    private long id;
    private String name;
    private int age;

    private Member() {};

    public Member(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

์•„์ด๋””, ์ด๋ฆ„, ๋‚˜์ด๋ฅผ ๊ฐ€์ง„ ๊ฐ„๋‹จํ•œ ํšŒ์› ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ ํ–ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์ €์žฅ, ์กฐํšŒ์ •๋„๋ฅผ ์ง€์›ํ•˜๋Š” ์ €์žฅ์†Œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MemberRepository {

    private static Map<Long, Member> store = new ConcurrentHashMap<>();
    private static AtomicLong sequence = new AtomicLong(0L);

    @Getter
    private static MemberRepository instance = new MemberRepository();

    public void save(Member member) {
        setIdWithReflection(member);
        store.put(member.getId(), member);
    }

    private void setIdWithReflection(Member member) {
        
        try {
            Class<Member> memberClass = Member.class;
            Field id = memberClass.getDeclaredField("id");
            id.setAccessible(true);
            id.set(member, sequence.incrementAndGet());
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalStateException("Reflection Exception", e);
        }
    }

    public Member findById(Long id) {
        return store.get(id);
    }

    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }

    public void clearStore() {
        store.clear();
    }
}

๋’ท๋‹จ์˜ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ด ์™„์„ฑ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ด์ œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ง์ ‘ ํ˜ธ์ถœ ํ•  view ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค.

์šฐ์„ ์€ HTML ์„ ์ด์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ํผ์„ ํ†ตํ•ด ๊ฐ€์ž…์„ ์ฒ˜๋ฆฌ ํ•  ์˜ˆ์ •์ด๋ฏ€๋กœ HTML Form ์„ ์ œ๊ณตํ•˜๋Š” ์„œ๋ธ”๋ฆฟ์„ ์ž‘์„ฑํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Slf4j
@WebServlet(name = "memberFormServlet", urlPatterns = "/servlet/members/new-form")
public class MemberFormServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        PrintWriter w = response.getWriter();
        StringBuilder htmlBuilder = new StringBuilder();
        String html = htmlBuilder
                .append("<!DOCTYPE html>\n")
                .append("<html>\n")
                .append("<head>\n")
                .append("    <meta charset=\"UTF-8\">\n")
                .append("    <title>Title</title>\n")
                .append("</head>\n")
                .append("<body>\n")
                .append("<form action=\"/servlet/members/save\" method=\"post\">\n")
                .append("    username: <input type=\"text\" name=\"username\" />\n")
                .append("    age:      <input type=\"text\" name=\"age\" />\n")
                .append(" <button type=\"submit\">์ „์†ก</button>\n")
                .append("</form>\n")
                .append("</body>\n")
                .append("</html>\n").toString();
        w.write(html);
    }
}

๋จผ์ € ์ž‘์„ฑํ•ด ๋ณธ ์„œ๋ธ”๋ฆฟ๊ณผ ๋™์ผํ•˜๊ฒŒ html ๋‚ด์šฉ์„ ๋ฌธ์ž์—ด๋กœ ์ž‘์„ฑํ•˜์—ฌ response ๊ฐ์ฒด์— ๋ฐ˜ํ™˜ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

๋‹ค์Œ์œผ๋กœ form ์˜ post ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ด ์ค„ ์„œ๋ธ”๋ฆฟ๋„ ํ•˜๋‚˜ ์ž‘์„ฑํ•˜์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@WebServlet(name = "memberSaveServlet", urlPatterns = "/servlet/members/save")
public class MemberSaveServlet extends HttpServlet {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));

        Member member = new Member(username, age);
        memberRepository.save(member);

        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter w = response.getWriter();

        StringBuilder htmlBuilder = new StringBuilder();
        String html = htmlBuilder
                .append("<!DOCTYPE html>\n")
                .append("<html>\n")
                .append("<body>\n")
                .append("์„ฑ๊ณต\n")
                .append("<ul>")
                .append("    <li>id=" + member.getId() + "</li>\n")
                .append("    <li>username=" + member.getName() + "</li>\n")
                .append(" <li>age=" + member.getAge() +  "</li>\n")
                .append("</ul>\n")
                .append("</body>\n")
                .append("</html>").toString();
        w.write(html);
    }
}
memberFormServlet ์‘๋‹ต
memberSaveServlet ์‘๋‹ต

์ด๋กœ์จ Servlet ์„ ํ™œ์šฉํ•œ ์šฐ๋ฆฌ์˜ ์ฒซ๋ฒˆ์งธ ๋ณต์žกํ•œ(?) ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ด ์™„์„ฑ๋˜์—ˆ๋‹ค. ๐ŸŽ‰

[๋ฌธ์ œ์ ๋“ค]

์„œ๋ธ”๋ฆฟ์„ ํ†ตํ•ด ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ HTTP ์ŠคํŽ™์„ ์ถ”์ƒํ™” ํ•˜์—ฌ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ• ์ˆ˜๋Š” ์žˆ๊ฒŒ ๋˜์—ˆ์ง€๋งŒ, ์„œ๋ธ”๋ฆฟ ํ•˜๋‚˜์— ํ™”๋ฉด๊ณผ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ด ํ†ตํ•ฉ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ง€์†์ ์ธ ๊ฐœ๋ฐœ์— ๋ถˆํŽธํ•œ ์ ๋“ค์ด ๋ช‡๊ฐ€์ง€ ์กด์žฌํ•œ๋‹ค.

  1. Java ๋ฌธ์ž์—ด ํƒ€์ž…์œผ๋กœ HTML ์„ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ๋™์ ์ธ HTML ์„ ๊ทธ๋ฆฌ๊ธฐ๊ฐ€ ํž˜๋“ค๋‹ค.
  2. ํ™”๋ฉด์„ ๋ณ€๊ฒฝํ•˜๋Š”๋ฐ ์„œ๋น„์Šค ๋กœ์ง์ด ์ƒˆ๋กœ ๋นŒ๋“œ๋˜๊ฑฐ๋‚˜, ์„œ๋น„์Šค ๋กœ์ง์„ ๋ณ€๊ฒฝํ•˜๋Š”๋ฐ ํ™”๋ฉด๋„ ๊ฐ™์ด ๋นŒ๋“œ๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.
  3. ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ์–ด์ง„๋‹ค.

๊ฒฐ๊ตญ ์ด๋Š” ํ™”๋ฉด(View)๊ณผ ์„œ๋น„์Šค(Service)์˜ ์ฑ…์ž„์ด ๋ถ„๋ฆฌ๋˜์ง€ ์•Š์•„์„œ ๋ฐœ์ƒํ•˜๋Š” ์ผ๋กœ, ์ด๋ฅผ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ…œํ”Œ๋ฆฟ ์—”์ง„ ์„ ์‚ฌ์šฉํ•œ๋‹ค. ์ตœ๊ทผ์—๋Š” ์Šคํ”„๋ง ์ง„์˜์—์„œ ๋Œ€ํ‘œ์ ์ธ ํ…œํ”Œ๋ฆฟ ์—”์ง„์œผ๋กœ ํƒ€์ž„๋ฆฌํ”„๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋‹น์‹œ์—๋Š” JSP ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜์˜€์œผ๋ฏ€๋กœ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋„ JSP ๋ฅผ ์ด์šฉํ•ด๋ณด์ž.

4. JSP

์šฐ์„  Spring Boot ํ”„๋กœ์ ํŠธ์—์„œ JSP ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” build.gradle ์— ๋‹ค์Œ ์˜์กด์„ฑ๋“ค์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

1
2
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper' 
implementation 'javax.servlet:jstl'

๊ทธ๋ฆฌ๊ณ ๋Š” ์œ„์—์„œ ๋ฌธ์ž์—ด๋กœ ๊ด€๋ฆฌํ–ˆ๋˜ HTML ์†Œ์Šค๋ฅผ JSP ํŒŒ์ผ๋กœ ์˜ฎ๊ฒจ๋ณด์ž.

  • ํšŒ์›๊ฐ€์ž… ์–‘์‹
1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/jsp/members/save.jsp" method="post">
    username: <input type="text" name="username"/>
    age: <input type="text" name="age"/>
    <button type="submit">์ „์†ก</button>
</form>
</body>
</html>
  • ํšŒ์›๊ฐ€์ž… ์™„๋ฃŒ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<%@ page import="me.jwjung.framework.basic.domain.member.MemberRepository" %>
<%@ page import="me.jwjung.framework.basic.domain.member.Member" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    //request, response ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    MemberRepository memberRepository = MemberRepository.getInstance();
    String username = request.getParameter("username");
    int age = Integer.parseInt(request.getParameter("age"));
    Member member = new Member(username, age);
    System.out.println("member = " + member);
    memberRepository.save(member);
%>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
์„ฑ๊ณต
<ul>
    <li>id=<%=member.getId()%></li>
    <li>username=<%=member.getName()%></li>
    <li>age=<%=member.getAge()%></li>
</ul>
</body>
</html>

ํ•ด๋‹น jsp ํŒŒ์ผ๋“ค์„ main/webapp/ ํ•˜์œ„ ๊ฒฝ๋กœ์— ์œ„์น˜์‹œํ‚ค๊ณ  ํ™•์žฅ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ) localhost:8080/jsp/members/new-form.jsp

5. MVC ํŒจํ„ด

[๋“ฑ์žฅ ๋ฐฐ๊ฒฝ]

jsp ํŒŒ์ผ์— HTML ์ฝ”๋“œ ๋ฐ ๋ช‡๊ฐ€์ง€ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ์ด๊ด€ํ•œ ๊ฒฐ๊ณผ ๋™์ ์œผ๋กœ HTML ์„ ๊ทธ๋ฆฌ๋Š” ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋Œ€์ƒ์ด servlet ์ฝ”๋“œ์—์„œ jsp ๋กœ ์˜ฎ๊ฒจ์™”์„ ๋ฟ HTML ์ฝ”๋“œ์™€ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง, ํŠนํžˆ ์ €์žฅ์†Œ๋ฅผ ์˜ค๊ณ ๊ฐ€๋Š” ๋กœ์ง๊นŒ์ง€ ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ํ•œ์ชฝ(JSP) ์—์„œ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์€ ์—ฌ์ „ํžˆ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๋‹ค.

  1. ์—ฌ์ „ํžˆ ํ•œ ์ชฝ์˜ ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์„ ๋ฟ๋”๋Ÿฌ, ์—ฐ๊ด€ ์—†๋Š” ๋ ˆ์ด์–ด์˜ ์ฝ”๋“œ๋“ค์ด ํ˜ผ์žฌํ•ด์žˆ๋‹ค.
  2. View ์™€ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์˜ ๋ณ€๊ฒฝ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ์ด ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋Š” ์ ์ด๋‹ค. ๋ฐ”๊ฟ” ๋งํ•˜์ž๋ฉด ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ฃผ๊ธฐ์™€ ํ™”๋ฉด์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ์ฃผ๊ธฐ๊ฐ€ ์™„์ „ํžˆ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
  3. ๋ฐ์ดํ„ฐ๋ฅผ ๋™์ ์œผ๋กœ ์ถœ๋ ฅํ•˜๋Š” ๋ฐ์— ํŠนํ™”๋˜์–ด ์žˆ๋Š” ๊ฒƒ์ด ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด์ง€๋งŒ ๋•Œ๋ฌธ์— ๊ฐ์ž ์ž˜ํ•˜๋Š” ๊ธฐ๋Šฅ๋งŒ ๋งก์•„์„œ ํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ์กฐ์  ๊ฐœ์„  ๋ฐฉ์•ˆ์œผ๋กœ MVC ํŒจํ„ด์ด ๋“ฑ์žฅํ•˜๊ฒŒ ๋œ๋‹ค.

[MVC ํŒจํ„ด ๊ตฌ์กฐ]

MVC ํŒจํ„ด์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์š”์†Œ๋“ค์ด ํ•„์š”ํ•˜๋‹ค.

Controller
HTTP ํ†ต์‹ ์˜ ์ฐฝ๊ตฌ๊ฐ€ ๋˜๋ฉฐ, ํ™”๋ฉด์— ์ „๋‹ฌํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•œ๋‹ค. ์ด๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ์กฐํšŒํ•˜๋Š” ๋“ฑ์˜ ๋ณต์žกํ•œ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์€ ์—ญํ• ์„ ๋‹ค์‹œ ๋ถ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋น„์Šค ๋ ˆ์ด์–ด์— ์œ„์ž„ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ๋Š” Model ์— ์‘๋‹ต ํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜์—ฌ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ๋งŒ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

View
์•ž์„œ JSP ์™€ ๊ฐ™์ด Model ์„ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์ด ๋•Œ, ๋™์ ์œผ๋กœ ํ™”๋ฉด์„ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ…œํ”Œ๋ฆฟ ์—”์ง„์—์„œ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค.

Model
Controller ์™€ View ์‚ฌ์ด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๊ธฐ ์œ„ํ•œ ๋งค๊ฐœ์ฒด ์—ญํ• ์„ ํ•œ๋‹ค.

MVC ํŒจํ„ด ์ด์ „์˜ ํ˜ธ์ถœ ๊ตฌ์กฐ
MVC ํŒจํ„ด ์ ์šฉ ํ›„ ํ˜ธ์ถœ๊ตฌ์กฐ

[MVC ํŒจํ„ด ์ ์šฉ]

์•ž์„œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋“ค์„ MVC ํŒจํ„ด์— ๋งž์ถฐ ๋ณ€๊ฒฝํ•ด๋ณด์ž. ์šฐ์„  MemberFormServlet ์„ MVC ์—ญํ• ์— ๋งž๊ฒŒ ๋ทฐ์™€ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค. ์ด๋•Œ, ์ƒˆ๋กœ ๋งŒ๋“ค jsp ํ…œํ”Œ๋ฆฟ์€ WEB-INF ํ•˜์œ„ ๊ฒฝ๋กœ์— ์œ„์น˜์‹œ์ผœ์ค€๋‹ค. WEB-INF ํ•˜์œ„ ์ž์›๋“ค์€ ๊ธฐ์กด์ฒ˜๋Ÿผ ๊ฒฝ๋กœ๋งŒ ์ž…๋ ฅํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ๋ฌด์กฐ๊ฑด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด ๋ฐ˜ํ™˜๋˜์–ด์•ผ ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
@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 {

        String viewPath = "/WEB-INF/views/new-form.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }
}

์„œ๋ธ”๋ฆฟ์€ ์ด์ œ view ์˜ ๊ฒฝ๋กœ๋งŒ dispatcher ๋ฅผ ํ†ตํ•ด ๋„˜๊ฒจ์ค€๋‹ค. dispatcher.forward() ๋ฉ”์†Œ๋“œ๋Š” redirect ์™€ ๋‹ค๋ฅด๊ฒŒ ์„œ๋ฒ„ ๋‚ด์—์„œ ์žฌํ˜ธ์ถœ์ด ์ผ์–ด๋‚˜๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ˜ธ์ถœ์ด ๋ณ€๊ฒฝ๋œ ๊ฒƒ์„ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค.

๋‹ค์Œ์œผ๋กœ ๊ธฐ์กด์˜ /members/new-form.jsp ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ด์„œ WEB-INF ํ•˜์œ„์˜ ์ ๋‹นํ•œ ๊ฒฝ๋กœ๋กœ ์˜ฎ๊ฒจ์ฃผ๊ณ , Form ํƒœ๊ทธ ๋‚ด์˜ action ์†์„ฑ ๊ฒฝ๋กœ๋ฅผ ์ ˆ๋Œ€๊ฒฝ๋กœ๋กœ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ํ˜„์žฌ url ๊ฒฝ๋กœ์—์„œ ๊ณ„์ธต ๊ฒฝ๋กœ๋ฅผ ์œ ์ง€ํ•œ์ฑ„ ๋งˆ์ง€๋ง‰ ์ž์› ์œ„์น˜๋งŒ ๋ณ€๊ฒฝ๋œ๋‹ค.

  • ๊ธฐ์กด Url: /servlet-mvc/members/new-form
  • ์ด๋™ Url: /servlet-mvc/members/save
1
2
3
4
5
<form action="save" method="post">
    username: <input type="text" name="username"/>
    age: <input type="text" name="age"/>
    <button type="submit">์ „์†ก</button>
</form>

๋‹ค์Œ์œผ๋กœ ์ €์žฅ์„ ์‹ค์ œ๋กœ ์‹คํ–‰ํ•˜๋Š” ์„œ๋ธ”๋ฆฟ๋„ MVC ํŒจํ„ด์„ ์ ์šฉํ•ด๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));

        Member member = new Member(username, age);
        System.out.println("member = " + member);
        memberRepository.save(member);

        //Model ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ ์ €์žฅ
        request.setAttribute("member", member);

        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher("viewPath");
        dispatcher.forward(request, response);
    }
}

์„œ๋ธ”๋ฆฟ์ด ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๋งŒ์„ ๋“ค๊ณ ๊ฐ€๊ณ  ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ Model ์„ ํ†ตํ•ด view ๋กœ ๋„˜๊ธฐ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ view ์—์„œ๋Š” ๋„˜์–ด์˜จ model ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹จ์ˆœํžˆ ๋ Œ๋”๋ง ํ•˜๋Š” ์—ญํ• ๋งŒ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋œ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ณด์ž

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body> ์„ฑ๊ณต
<ul>
    <li>id=${member.id}</li>
    <li>username=${member.username}</li>
    <li>age=${member.age}</li>
</ul>
<a href="/index.html">๋ฉ”์ธ</a>
</body>
</html>

model ์˜ ๊ฐ’์„ el ํ‘œํ˜„์‹์œผ๋กœ ๊ฐ€์ ธ์™€ ๋ Œ๋”๋ง ํ•ด์ฃผ๋Š” ์ •๋„ ์ด์™ธ์˜ ๋กœ์ง์€ ์ „๋ถ€ ์ œ๊ฑฐ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

[ํ•œ๊ณ„]

MVC ํŒจํ„ด์„ ์ ์šฉํ•จ์œผ๋กœ์จ ์ดˆ๊ธฐ ๋ฌธ์ œ์˜€๋˜ ์—ญํ• ์ด ๋ถ„์‚ฐ๋˜์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์–ด๋Š์ •๋„ ํ•ด๊ฒฐํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ง ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ์ ๋“ค์ด ๋‚จ์•„์žˆ๋‹ค.

  1. ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋“ค
    • dispatcher.forward() ํ˜ธ์ถœ์ด๋‚˜, viewPath ์„ ์–ธ ๋“ฑ, ์ปจํŠธ๋กค๋Ÿฌ๋ณ„๋กœ ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋“ค์ด ์—ฌ์ „ํžˆ ๋งŽ์ด ๋‚จ์•„์žˆ๋‹ค.
  2. viewPath ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ์‹
    • ์ „์ฒด๊ฒฝ๋กœ์™€ ํ™•์žฅ์ž๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์— jsp ํŒŒ์ผ์„ ์ด๋™์‹œํ‚ค๊ฑฐ๋‚˜, ํ…œํ”Œ๋ฆฟ ํ™•์žฅ์ž๋ฅผ html ์ด๋‚˜ ๋‹ค๋ฅธ ํŒŒ์ผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  3. request ๊ฐ์ฒด์™€ response ๊ฐ์ฒด ์„ ์–ธ์ด ๊ฐ•์ œ
    • request, response ๊ฐ์ฒด๋ฅผ ์ƒ์‹œ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ๋ฐ ์„ ์–ธ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค. ์ด๋กœ ์ธํ•ด ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑ๋“ฑ๋„ ์–ด๋ ค์›Œ์ง„๋‹ค.
  4. ๊ณตํ†ต์ฒ˜๋ฆฌ์˜ ์–ด๋ ค์›€
    • ๊ฐ ์ปจํŠธ๋กค๋Ÿฌ๋“ค์ด ๊ณตํ†ต์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•„์ ธ๋„ ๊ฐ๊ฐ์˜ ์„œ๋ธ”๋ฆฟ(์ปจํŠธ๋กค๋Ÿฌ)์— ์ฒ˜๋ฆฌํ•ด์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ ๊ณตํ†ต๊ธฐ๋Šฅ์„ ๋ฌถ๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.

๋‹ค์Œ ์‹œ๊ฐ„์—๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์„ ์ ์šฉํ•œ ๋‚˜๋งŒ์˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ์ž‘ํ•ด๋ณด๋ฉด์„œ ํ•ด๊ฒฐํ•ด๋ณด๊ณ , ์Šคํ”„๋ง์ด ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜์˜€๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

ํƒœ๊ทธ: ,

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ: