스프링 | MVC 패턴 이론

Salt·2023년 5월 27일

스프링 MVC 패턴

웹 어플리케이션을 개발하기 위한 스프링 프레임워크

뷰 - 컨트롤러 - 모델

→ UI / 비즈니스 로직 분리한 설계


JPA 세팅 방법

5강 - Request Handling

부하 테스트하는 법

아틸러리를 활용한 스트레스 테스트

프로젝트 성과 측정에 써먹자.

config:
  target: http://localhost:8080
  phases:
    - duration: 60
      arrivalRate: 1
    - duration: 120
      arrivalRate: 300
      name: test case
scenarios:
  - flow:
      - get:
          url: "/hello"

MVC 패턴의 실행 흐름

  1. 클라이언트의 요청이 DispatcherServlet으로 들어온다.
  2. DispatcherServlet은 HandlerMapping을 이용하여 어떤 Controller가 요청을 처리할지 결정한다.
  3. 선택된 Controller는 클라이언트의 요청에 대한 비즈니스 로직을 실행하고, 결과를 반환한다.
  4. Controller가 반환한 결과는 ViewResolver를 통해 적절한 View로 변환된다.
  5. 변환된 View는 클라이언트에게 응답으로 반환된다.

요청 → DispatcherServlet Controller 선택 (HandlerMapping) → Controller 비즈니스 로직 실행 → ViewResolver View로 변환 → 응답

package com.spring.mvc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MvcApplication {

	public static void main(String[] args) {
		SpringApplication.run(MvcApplication.class, args);
	}

}
@Controller
public class MVCController01 {

    // 특정 주소로 접속했을 때 처리할 로직을 작성한다.
    // localhost:8080 이 기본주소이고, 뒤에 /hello를 붙여 접속시 실행
    @RequestMapping("/hello")
    public String hello() {
        System.out.println("/hello 접속 감지!!!");

        // 어떤 .jsp 파일과 연동할지 return 구문에 문자열로 파일 이르믈 적어줌
        // prefix 였던 /WEB_INF/view와 suffix였던 .jsp를 앞 뒤로 붙여서
        // 최종적으로 열리는 파일은 /WEB-INF/view/hello.jsp
        return "hello";
        }

        @GetMapping("/getreq")
        public String getReq() {
            System.out.println("get방식 요청을 감지했습니다!");
            return "reqview";
        }
        @PostMapping("/postreq")
        public String getPost() {
            System.out.println("post방식 요청을 감지했습니다!");
            return "reqview";
        }
    }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    <h1>결과 화면 도착!</h1>

</body>
</html>


HTTP 요청 메서드

GET : HTTP 요청 메시지에 데이터를 포함하여 서버에 전송, URL에 남음, 메시지 캐싱, 노출O

POST : 요청 메시지 body 안에 데이터 넣어서 전송, ****URL에 노출안돼서 보안성O 캐싱X 주로 데이터 추가, 수정, 삭제에 사용된다.

어떤 방식을 쓰고 있는지 확인하려면 f12, 네트워크, 페이로드에서 확인하면 된다.

Query String을 이용하여 HTTP 파라미터에서 정보 받기

Getter, Setter, 생성자 필요함!

import lombok.*;

@Getter @Setter
@ToString @NoArgsConstructor
public class GameDTO {
    private String gameName;
    private int price;
    private int sales;
}
@RequestMapping("game")
    public String game(GameDTO game) {
        System.out.println("Game 정보 : " + game);
        return "";
    }

FORM에 입력받기

데이터를 보낼 때는 http 뒤에 파라미터로 전달하지 않고, 당연히 입력 폼에 넣어 서버에 전달한다.

GET / POST 방식으로 지정해줄 수 있다.

@RequestMapping("/catform")
    public String catForm() {
        System.out.println("고양이를 등록할 수 있는 폼으로 연결해드립니다.");

        // /WEB-INF/views/chap01/catform.jsp
        return "/chap01/catform";
    }
@GetMapping("/cat")
    public String cat(String name, int age, String kind) {
        System.out.println("등록할 고양이 이름 : " + name);
        System.out.println("등록할 고양이 나이 : " + age);
        System.out.println("등록할 고양이 품종 : " + kind);

        return "/chap01/catreg";
    }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    <h1>고양이 정보 등록하기</h1>

    <form action = "http://localhost:8080/cat" method = "GET">
        고양이이름 : <input type = "text" name = "name"><br/>
        고양이나이 : <input type = "number" name = "age"><br/>
        고양이품종 : <input type = "text" name = "kind"><br/>
        <input type = "submit" value = "제출">
    </form>

</body>
</html>

JSP로 응답데이터 전달하기 (중요)

@Controller
@RequestMapping("/chap02")
public class MVCController02 {

@RequestMapping("hobbies")
    public String hobbies(**Model** model) {
        String name = "룰루";

        List<String> hobbies = List.of("밥먹기", "낮잠자기", "쥐잡기");

        model.**addAttribute**("n", name);
        model.**addAttribute**("hList", hobbies);

        return "/chap02/hobbies";
    }
}
@GetMapping("/hobbies2")
    public ModelAndView hobbies2() {
        //.jsp파일(view단)으로 보내고 싶은 자료 설정
        String name = "참참이";
        List<String> hList = List.of("전깃줄에서 꾸벅꾸벅 졸기", "쌀 주워먹기", "짹짹 소리 내기");

        // 목적지 뷰 이름 적기(포워딩 방식)
        String viewName = "chap02/hobbies";

        // ModelAndView 객체 생성 및 세팅하기
        ModelAndView mv = new ModelAndView();
        mv.setViewName(viewName);
        mv.addObject("n", name);
        mv.addObject("hList", hList);

        return mv;
    }
<h1> ${n}의 취미 목록 </h1>
    <p> ${hList} </p>
    <ol>
        **<c:forEach var="h" items="${hList}">
            <li> ${h}입니다. </li>
        </c:forEach>**
    </ol>

키오스크 만들기 예제

@Controller
@RequestMapping("/chap03")
public class MVCController03 {

    // 폼으로 넘겨주는 메서드
    @RequestMapping("/foodform")
    public String foodform() {
        return "chap03/foodform";
    }

    // 폼에서 날려준 데이터를 view단으로 넘겨주는 메서드
    @RequestMapping("/orderresult")
    public ModelAndView orderresult(String name, int tableNum, String orderMenu) {

        // view 객체 생성
        ModelAndView mv = new ModelAndView();

        // 데이터 적재
        mv.addObject("name", name);
        mv.addObject("tableNum", tableNum);
        mv.addObject("orderMenu", orderMenu);

        // 결과 view파일 지정
        mv.setViewName("chap03/orderresult");

        return mv;
    }

}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    <form action = "http://localhost:8181/chap03/orderresult" method = "POST">
        주문자명 : <input type = "text" name = "name"><br/>
        주문테이블번호 : <input type = "number" name = "tableNum"><br/>
        주문할수있는음식 : <input type = "text" name = "orderMenu"><br/>
        <input type = "submit" value = "제출">
    </form>

</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>

      <h1> ${name} 님의 주문 결과입니다. </h1>
      <p> ${tableNum} 번 테이블에 </p>
      <p> ${orderMenu} 음식을 갖다드리겠씁니다. </p>

    </body>
    </html>

리다이렉트 걸기

포워딩은 내가 갖고 있는 서버 내에서 가능하고, 리다이렉트는 외부 서버를 걸어줄 때 사용한다.

리다이렉트는 foodform jsp파일로 포워딩하지 않고, http주소/목적메서드로 보낸다.

포워딩은 foodform.jsp 파일로 적재 데이터 보내는 방식이다.

@RequestMapping("/goFoodform")
    public String goFoodForm(Model model) {
        model.addAttribute("title", "음식 주문 키오스크");
        **return "redirect:/foodform";** 
        return "/chap03/foodform";
    }

그럼, 리다이렉트는 데이터 전달이 불가능 할까?

GET 방식은 URL에 쿼리스트링을 붙여서 데이터를 전송하기 때문에

리다이렉트 타겟 URL에 쿼리 스트링을 붙여 리다이렉트를 걸면 전달이 가능하다.

0개의 댓글