ACHO.pk devlog

[Springboot] 스프링 웹 개발 기초(정적, MVC, 템플릿 엔진, API) 본문

프레임워크/Springboot

[Springboot] 스프링 웹 개발 기초(정적, MVC, 템플릿 엔진, API)

Acho 2023. 1. 16. 22:42

인프런 김영한 강사님의 "스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술"의 강의를 듣고 학습하였습니다.


  • @RequestParam
  • @ResponseBody

에 대한 내용..


정적 컨텐츠

서버에서 하는 것 없이 파일을 그대로 웹브라우저에 띄우는 것

스프링 부트 정적 컨텐츠 기능

    https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html#boot-features-spring-mvc-static-content

 

Spring Boot Features

Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and Servlet-based web applications. It occurs as part of closing the application context and is performed in the earliest

docs.spring.io

 

 

resources/static/stu-static.html

<!DOCTYPE HTML>
<html>
<head>
 <title>static content</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
정적 컨텐츠 입니다.
</body>
</html>

 

 

▹결과화면

 

웹브라우저에서 url 요청을 보내고, 내장 톰캣 서버에서 이 요청을 받은 후, 스프링에 넘긴다.

스프링 컨테이너에서 먼저 Controller에 요청에 대한 내용이 있나 살펴보고, 매핑이 된 Controller가 없으면 static 하위에 해당 파일명을 찾는다.

 

 

localhost:8080/stu-static.html을 입력하여 실행결과를 확인해보자.

stu-static 관련 Controller가 있고

 

stu-static.html이 static 폴더 하위에 한 개 존재하고, templates 폴더 하위에 한 개 존재한다.

 

stu-static 관련 Controller가 존재할 경우, templates하위에 있는 hello-static.html을 찾아간다. 하지만 해당 내용과 관련된 Controller가 없으면 static/hello-static을 찾아간다.

 

 

▹결과화면

 

여기서!!

Controller에 GetMapping에서 stu-static.html이 아닌 stu-static일 경우,, localhost:8080/stu-static.html을 입력하면 static/stu-static.html로 이동한다.


MVC와 템플릿 엔진

    ▸MVC: Model, View, Controller

 

 

Controller

@Controller
public class stuController {
    
    @GetMapping("stu-mvc")
    public String stuMvc(@RequestParam("name") String name, Model model) {
        model.addAttribute("name", name);
        return "stu-template";
    }
}

중요한 코드를 살펴보자.

 

public String stuMvc(@RequestParam("name") String name, Model model) {

@RequestParam으로 화면단의 name값을 지정하여 String name 파라미터에 바인딩 시킬 수 있다.

 

 

예를 들어, 

<input type="text" id="name" name="name">
<button type="submit">submit</button>

name(좌)이 name(우)인 input 태그에 "acho"를 입력한다면, submit을 했을 때 서버에서 @RequestParam의 value에 name를 지정한 string name에 "acho"값이 들어간다.

 

model.addAttribute("name", name);

파라미터로 넘어온 name을 넘겨준다. "name"(좌)가 key 값이고, name(우)가 그냥 name이다.

model(key, value) 

 

 

 

View

resources/templates/stu-template.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>

model의 key값이 name인 것에서 값을 꺼내서 ${name} 자리에 치환한다.

 

 

 

여기서!!

WARN 10764 --- [nio-8080-exec6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved[org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'name' for method parameter type String is not present]

name에 값을 줘야하는데 주지 않아서 발생한 경고다. 이거 때문에 서버에서 에러 페이지가 뜬다.

 

 

▹결과화면

 

이렇게 HTTP Get 방식으로 name 파라미터 값을 넘겨주게 되면, 지정한 name 값으로 결과물을 볼 수 있다.

  


API

 

@ResponseBody 문자 반환 / Controller

@Controller
public class stuController {

    @GetMapping("stu-string")
    @ResponseBody
    public String stuString(@RequestParam("name") String name) {
        return "stu " + name;
    }
}

@ResponseBody 

    ▹HTTP에 헤더 부분과 바디 부분이 있을 때 바디 부분에 return 값을 직접 반영한다.

    ▹대신에 HTTP의 BODY에 문자 내용을 직접 반환(HTML BODY TAG를 말하는 것이 아니며, 보통 JSON으로 결과가 적힌다)

    ▹@ResponseBody 를 사용하면 viewResolver를 사용하지 않고, 경로라는 개념이 없다.

 

 

 

▹결과화면

페이지 소스 보기

 

 

 

@ResponseBody 객체 반환 / Controller

@Controller
public class stuController {

    @GetMapping("stu-api")
    @ResponseBody
    public Study studyApi(@RequestParam("name") String name) {
        Study stu = new Study();   //객체 생성
        stu.setName(name);
        return stu;  //return에 객체를 넘김
    }
    static class Study {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}

@ResponseBody 를 사용하고, 객체를 반환하면 객체가 JSON(key:value로 이루어진 구조)으로 변환됨

윈도우에서 Alt + Insert 하면 바로 사용할 수 있다.

 

 

▹결과화면

페이지 소스 보기

 

 

@ResponseBody 사용 원리

HTTP의 BODY에 문자 내용을 직접 반환, 객체일경우 문자로 바꾸는 작업이 필요함

viewResolver 대신에 HttpMessageConverter 가 동작

기본 문자처리: StringHttpMessageConverter  (StringConverter 동작)

기본 객체처리: MappingJackson2HttpMessageConverter  (JsonConverter 동작)

byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음

 

 

★ 추가 공부해보기 !!!!

웹 브라우저에서 url 요청을 하면 내장 톰캣 서버가 스프링에 알려준다. 스프링은 Controller에 해당 요청에 대한 메서드가 존재하는지 확인한다. 여기서 ResponseBody 어노테이션이 붙어있으므로 HTTP 응답에 그대로 데이터를 넘긴다. (ResponseBody 어노테이션이 없다면 viewReslover가 요청에 맞는 template를 찾아준다.) 문자라면 HTTP에 그대로 넘기겠지만, 객체일경우 JSON 방식으로 데이터를 만들어서 HTTP 응답에 넘긴다. ResponseBody 어노테이션이 있을 때에는 HttpMessageConverter가 동작을 한다. 문자일경우 StringConverter 동작하고, 객체일경우 JsonConverter가 동작한다.

 

 

 

 

Comments