250122 TIL

2025. 1. 22. 18:11·TIL

Spring MVC

https://jjiyuuuuun.tistory.com/55# MVC(spring mvc)  model 1 vs model2 -1-11

Spring MVC는 Spring의 핵심 기능인 의존성 주입(Dependency Injection) 활용

 

📌 특징

▪️다양한 뷰 기술((JSP, Thymeleaf, FreeMarker 등) 지원, JSON, XML 등 데이터 반환 할 수 있어 RESTful API 구현에 적합

▪️Spring의 **의존성 주입과 AOP(Aspect-Oriented Programming)**를 통해 모듈화하고 관리

▪️애노테이션 기반의 설정을 통해 간단하게 컨트롤러를 구성

  ex) @Controller / @RestController / @RequestMapping

▪️초기 설정, 구성 및 배포가 간소화되어, 개발자가 비즈니스 로직에 더 집중할 수 있도록 도와줌

 

‼️mvc 패턴의 model1과 model 2 큰 차이점 ‼️

: 요청이 들어오는 입구를 단일화(Front Controller,DispatcherServlet )시켰다 (보안 측면 성능👍🏻)

  model 1은 여러개 요청이 들어오면 각 요청을 받는 서블릿(컨트롤러) 여러개

model1
model 2

 

 

📌Spring MVC 프레임워크에서 요청처리

1️⃣ Request : 모든 클라이언트 요청은 Dispatcher Servlet으로 들어옴

▪️DispatcherServlet : 모든 웹 요청의 진입점 역할, HTTPServlet을 상속 받음

✳️ URL Mapping : 클라이언트가 보낸 HTTP 요청(URL)을 서버에서 적절한 서블릿 또는 메서드로 매핑하는 작업

▶️Spring Boot에서는 이 URL 매핑을 자동으로 처리하도록 설정되어 있다

▫️Spring Boot에서는 application.properties 또는 application.yml 파일에서 톰캣, DispatcherServlet 등의 동작을 추가로 설정할 수 있다

@Configuration
public class CustomServletConfig {

    @Bean
    public ServletRegistrationBean<CustomServlet> customServlet() {
        ServletRegistrationBean<CustomServlet> servletBean =
                new ServletRegistrationBean<>(new CustomServlet(), "/custom/*");
        return servletBean;
    }
}

 spring boot는 모든 요청이 DispatcherServlet 하나로 받게 설정 되어 있다.

 

2️⃣ Handler Mapping : Dispatcher Servlet은 Handler Mapping을 사용하여 해당 요청을 처리할 적합한 컨트롤러(Handler)를 찾는다.

▪️RequestMappingHandlerMapping: 모든 URL 매핑과 관련된 메소드를 관리

애플리케이션 시작 시 모든 컨트롤러를 스캔하여 모든 매소드 매핑정보를 찾아 저장

 

3️⃣ Handler Adapter: 선택된 컨트롤러를 실행할 수 있게 함, 실제 컨트롤러가 실행되도록 중간에서 조정

 

4️⃣ Controller : 실제 비즈니스 로직을 처리하는 컨트롤러가 요청을 받아 처리, Repository, Service 계층 사용

 

5️⃣ Model : 컨트롤러가 처리 결과를 Model 객체에 담아 뷰에 전달함

✳️ 스프링은 다른 라이브러리에 종속되어있지 않아야한다. 내부에선 자바 API가 HttpServletRequest에 요청한 데이터를 담아서 뷰에 전달

 

6️⃣ View Resolver : 컨트롤러에서 반환된 뷰 이름을 바탕으로 실제 뷰 객체를 찾아냄

▫️다양한 뷰 기술(JSP, Thymeleaf 등)을 지원,

ThymeleafViewResolver : 반환된 뷰 이름에 해당하는 Thymeleaf 템플릿을 찾아 렌더링

InternalResourceViewResolver (JSP를 위한): 반환된 뷰 이름을 JSP 파일로 매핑하여 처리

@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    resolver.setOrder(1);
    return resolver;
}

@Bean
    public ThymeleafViewResolver thymeleafViewResolver() {
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    resolver.setTemplateEngine(templateEngine());
    resolver.setOrder(2);
    return resolver;
}

 

▫️ 컨트롤러에서 "home" 이라는 뷰 이름을 반환하는 경우

  1. DispatcherServlet 은 먼저InternalResourceViewResolver 에 이 이름을 전달
  2. 만약 /WEBINF/views/home.jsp파일이 존재한다면 이 파일을 뷰로 사용
  3. 존재하지 않는다면 다음 ViewResolver 인 ThymeleafViewResolver 에게 넘어감
  4. ThymeleafViewResolver는 해당 이름에 맞는 Thymeleaf 템플릿(home.html)을 찾아 렌더링을 시도
@Bean
public ThymeleafViewResolver thymeleafViewResolver(ISpringTemplateEngine templateEngine) {
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    resolver.setTemplateEngine(templateEngine);
    resolver.setCharacterEncoding("UTF-8");
    resolver.setOrder(1);
    resolver.setViewNames(new String[] {"*.html", "*.xhtml"});
    return resolver;
}

 

▫️setViewNames : 처리할 수 있는 뷰 이름의 패턴 지정 : html 과 .xhtml 확장자를 가진 파일을 Thymeleaf 템플릿으로 처리하도록 설정

 

▫️Thymeleaf 의존성 설정

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

 

자동으로 ThymeleafViewResolver가 Bean으로 등록됨

 

7️⃣ View : Model 데이터를 사용하여 사용자에게 보여질 최종적인 응답을 생성, 이 과정에서 HTML, JSON 등의 형태로 변환될 수 있음

✳️스프링의 View는 주로 jsp 사용 안하고 타임 리프 사용

 

8️⃣ Response : 최종적으로 생성된 뷰가 클라이언트에게 응답으로 반환됨.

 

 

📌 Spring Boot에서의 Spring MVC

▪️자동 설정 : Spring Boot는 자동으로 DispatcherServlet, Web MVC 설정 등을 구성. 사용자는 Model,View,Controller만 구현해 놓으면 Spring Boot Framework가 위의 과정을 내부에서 동작함

▪️자동 의존성 관리 : Spring Boot의 스타터 패키지를 사용하면 필요한 의존성을 쉽게관리할 수 있다. spring-boot-starter-web 은 Spring MVC, Tomcat 서버, Jackson 라이브러리 등 웹 애플리케이션 개발에 필요한 의존성을 모두 포함

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
}

▪️쉬운 변경 : application.properties 또는application.yml 파일을 통해 애플리케이션의 다양한 설정을 쉽게 변경

▪️내장 서버 : 내장 Tomcat, Jetty 또는 Undertow 서버를 사용하여 별도의 서버 설치 없이 애플리케이션을 실행할 수 있다


📌 Controller 메소드 파라미터

🔹Web 요청과 관련된 파라미터

▫️HttpServletRequest : 원시 서블릿 요청 객체에 접근.

- 클라이언트가 보낸 HTTP 요청 정보를 담고 있는 객체(클라이언트 IP 주소 등 알아낼 수 있음)

getParameter(String name) 요청 파라미터 값 가져오기 (query string, form)
getHeader(String name) 요청 헤더 값 가져오기
getRequestURI() 요청 URI 반환 (/example/test)
getMethod() HTTP 메서드 반환 (GET, POST 등)
getSession() 현재 요청의 세션 객체 반환
@GetMapping("/example")
public String handleRequest(HttpServletRequest request) {
    String param = request.getParameter("name"); // 요청 파라미터 'name'
    String userAgent = request.getHeader("User-Agent"); // 요청 헤더 'User-Agent'
    String uri = request.getRequestURI(); // 요청 URI

    return "Param: " + param + ", User-Agent: " + userAgent + ", URI: " + uri;
}

 

▫️ HttpServletResponse : 원시 서블릿 응답 객체에 접근.

- 서버가 클라이언트에게 보낼 HTTP 응답을 생성하고 조작할 수 있는 객체

setStatus(int statusCode) HTTP 상태 코드를 설정 (예: 200, 404 등)
setHeader(String name, String value) HTTP 응답 헤더 설정
addCookie(Cookie cookie) 응답에 쿠키 추가
getWriter() 응답 본문에 데이터를 쓰기 위한 출력 스트림 제공
@GetMapping("/response")
public void handleResponse(HttpServletResponse response) throws IOException {
    response.setStatus(HttpServletResponse.SC_OK); // HTTP 200 상태 설정
    response.setHeader("Content-Type", "text/plain"); // 응답 헤더 설정
    response.getWriter().write("This is the response body"); // 응답 본문 작성
}

 

▫️ HttpSession : HTTP 세션 객체에 접근할 수 있으며, 세션 데이터를 읽거나 수정할 수 있다.

ex) 로그인 사용자 정보, 장바구니 데이터 등 클라이언트 상태를 유지해야 할 때

setAttribute(String name, Object value) 세션에 데이터 저장
getAttribute(String name) 세션에서 데이터 가져오기
removeAttribute(String name) 세션에서 데이터 삭제
invalidate() 세션 무효화
@GetMapping("/session")
public String handleSession(HttpSession session) {
    session.setAttribute("username", "John Doe"); // 세션에 데이터 저장
    String username = (String) session.getAttribute("username"); // 세션에서 데이터 가져오기
    session.invalidate(); // 세션 무효화
    return "Username: " + username;
}

 🔹HTTP 요청 데이터를 메서드의 매개변수로 받기

▫️ @RequestParam : 요청 파라미터를 메소드 파라미터로 바인딩.

- 요청 예시 : /user?name=John&age=25

@GetMapping("/user")
public String getUser(@RequestParam String name, 
                      @RequestParam(defaultValue = "0") int age) {
    return "Name: " + name + ", Age: " + age;
}

 

▫️ @PathVariable : URI 경로의 변수 값을 메소드 파라미터로 바인딩.

- RESTful API 설계에서 자주 사용.

- 경로 템플릿 변수와 이름이 동일해야 함.

- 요청 예시/user/123

@GetMapping("/user/{id}")
public String getUserById(@PathVariable int id) {
    return "User ID: " + id;
}

 

▫️ @RequestBody : HTTP 요청 본문(JSON, XML 등)을 메소드 파라미터 객체로 변환.

- 주로 POST, PUT 요청에서 사용.

- Jackson 라이브러리를 통해 JSON 데이터를 객체로 변환.

@PostMapping("/user")
public String createUser(@RequestBody User user) {
    return "Created user: " + user.getName();
}

 

▫️ @ModelAttribute : 요청 파라미터를 객체에 바인딩.

- 주로 HTML 폼 데이터를 객체로 매핑할 때 사용.

@PostMapping("/user")
public String createUser(@ModelAttribute User user) {
    return "User created: " + user.getName() + ", Age: " + user.getAge();
}

 

▫️ @SessionAttribute : 세션에서 값을 가져와 메소드 파라미터로 바인딩.

@GetMapping("/session")
public String getSessionData(@SessionAttribute(name = "user") String user) {
    return "Session User: " + user;
}

🔹응답과 관련된 파라미터

▫️ Model : 뷰에 전달할 데이터를 설정할 수 있는 모델 객체

addAttribute(String key, Object value) 데이터를 키-값 쌍으로 추가.
addAllAttributes(Map<String, ?> map) 여러 데이터를 한 번에 추가.
containsAttribute(String key) 특정 키가 존재하는지 확인.
@Controller
public class ExampleController {

    @GetMapping("/greeting")
    public String greeting(Model model) {
        model.addAttribute("name", "John Doe"); // 데이터를 모델에 추가
        return "greeting"; // greeting.html로 이동
    }
}

 


✳️ Thymeleaf (타임리프)

  • Spring Boot에서 자주 사용하는 템플릿 엔진(Spring MVC와의 높은 호환성)
  • HTML 파일을 브라우저에서 바로 열어도 깨지지 않음.

📌템플릿 엔진 이란?

미리 만들어 놓은 HTML 틀(템플릿)에 서버 데이터를 넣어 동적인 웹 페이지를 만드는 도구

서버 사이드 템플릿 엔진  클라이언트 사이드 렌더링
서버에서 HTML을 완성해서 전달 서버에서 데이터만 전달하고, HTML은 브라우저에서 생성
속도가 빠름 (초기 페이지 로드 시) 대규모 인터랙티브 UI에 적합
대표: 타임리프, JSP, Freemarker 대표: React, Vue.js, Angular

 

1️⃣템플릿 파일: index.html

HTML 틀(템플릿)을 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>템플릿 엔진 예제</title>
</head>
<body>
    <h1>안녕하세요, <span th:text="${name}">이름</span>님!</h1>
    <ul>
        <li th:each="item : ${items}" th:text="${item}">아이템</li>
    </ul>
</body>
</html>

▫️xmlns:th="<http://www.thymeleaf.org>"

  • Thymeleaf에서 제공하는 속성(th:text, th:each 등)을 사용하기 위해 추가된 네임스페이스
  • 일반 HTML 파일에서는 무시되며, Thymeleaf 템플릿 엔진에서만 동작.

2️⃣Java 코드

서버에서 데이터 제공

@Controller
public class HomeController {
    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("name", "홍길동");
        model.addAttribute("items", List.of("사과", "바나나", "포도"));
        return "index"; // index.html 템플릿 사용
    }
}

 

3️⃣최종 HTML 출력

템플릿 엔진이 데이터를 끼워 넣어 최종 HTML 생성

<!DOCTYPE html>
<html>
<head>
    <title>템플릿 엔진 예제</title>
</head>
<body>
    <h1>안녕하세요, 홍길동님!</h1>
    <ul>
        <li>사과</li>
        <li>바나나</li>
        <li>포도</li>
    </ul>
</body>
</html>

📌 Spring MVC 응답 방식

▪️ Redirect (리다이렉트)

▪️ Forward (포워드)

'TIL' 카테고리의 다른 글

250124 TIL  (2) 2025.01.24
250123 TIL  (2) 2025.01.24
250121 TIL  (1) 2025.01.22
250120 TIL  (4) 2025.01.21
250117 TIL  (1) 2025.01.17
'TIL' 카테고리의 다른 글
  • 250124 TIL
  • 250123 TIL
  • 250121 TIL
  • 250120 TIL
Jiyuuuuun
Jiyuuuuun
  • Jiyuuuuun
    Hello, World!
    Jiyuuuuun
  • 전체
    오늘
    어제
    • 분류 전체보기 (112)
      • TIL (56)
      • CS (17)
        • Network (4)
        • Algorithm (10)
      • JAVA (5)
      • Project (10)
        • HakPle (3)
        • JUSEYO (4)
      • Spring (2)
      • C (3)
      • C++ (16)
      • Snags (2)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    react
    nginx
    my_favorite_place
    springboot
    front-end
    javascript
    SQL
    Kubernetes
    CSS
    db
    부트캠프
    node.js
    멋쟁이사자처럼
    HTML
    juseyo
    java
    back-end
    Docker
    JPA
    hakple
    JDBC
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Jiyuuuuun
250122 TIL
상단으로

티스토리툴바