Programming/Spring

[Spring boot] SpringMVC(1) Controller 생성하기

byeong07 2021. 5. 23. 20:34

[Spring boot] SpringMVC(1) Controller 생성하기

 

 

1. MVC

▶ 개요

 - MVC(Model View Controller)란 하나의 디자인 패턴이다.

 - 스프링 MVC : 스프링이 제공하는 웹 어플리케이션 구축 전용 MVC 프레임워크.

 

1. 모델(Model) : 비즈니스 규칙을 표현 

2. 뷰(View) : 프레젠테이션을 표현

3. 컨트롤러(Controller) : 위 두가지를 분리하기 위하여 양측 사이에 배치된 인터페이스

 

2. Controller

▶ Controller란?

 - Controller에 대해 간단히 말하자면 MVC에서 C에 해당 하며 주로 사용자의 요청을 처리 한 후 지정된 뷰에 모델 객체를 넘겨주는 역할을 한다.

 

▶ Controller 관련 대표적인 Annotation을 알아보자

1)  @Controller

 - Controller의 역할을 수행 한다고 명시(해당 클래스를 Controller로 사용한다고 Spring FrameWork에 알린다.)

   필요한 비즈니스 로직을 호출하여 전달할 모델(Model)과 이동할 뷰(View) 정보를 DispatherServlet에 반환 한다.

 - Bean으로 등록

 - @Component의 구체화 된 어노테이션

 

2)  @RequestMapping

 - 요청에 대해 어떤 Controller, 어떤 메소드가 처리할지 맵핑하기 위한 어노테이션

 - 클래스나 메서드 선언부에 @RequestMapping과 함께 URL을 명시하여 사용한다.

 -  viewName 생략시 @RequestMapping의 path로 설정한 URL이 default viewName

RequestMapping 속성들

1) value(String[])  : URL 값

/* EX) */
@RequestMapping(value="/login")
@RequestMapping("/login") 

 

2) method (RequestMethod[]) : HTTP Request 메소드 값

 - GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE

/* EX1) */
@RequestMapping(value="/login", method=@RequestMethod.GET)
/* EX2) */
@RequestMapping(value="/login", method=@RequestMethod.POST)

※ Spring4.3 이후 ex1), ex2)는 다음과 같이 쓸수 있다.

ex1) @GetMapping("/login")

    == @RequestMapping("/login", method=@RequestMethod.GET)

ex2) @PostMapping("/login")

   == @RequestMapping("/login", method=@RequestMethod.POST)

 

3) params(String[]) : HTTP Request 파라미터

① @RequestParam : 사용자가 원하는 매개변수에 값을 매핑하기위해 사용한다.

/* EX1) */
@PostMapping("/member")
public String member(@RequestParam String name, @RequestParam Int age)

여기서 @ReauestParam은 생략 가능하다. 사용자가 입력한 key값과 매개변수의 이름을 비교하여 값을 넣어주기 때문이다. 결국 다음의 ex2)와 ex1)은 동일한의미다.

/* EX2) */
@PostMapping("/member")
public String member(String name, Int age)

 

② @PathVariable : url 경로를 변수화하여 사용할 수 있도록 해준다.

@RequestMapping("/member/{name}/{age}")
public String member(@PathVariable("name") String name, @PathVariable("age") String age)

=> RequestMapping의 {name}과 PathVariable 의 String name을 매핑 하여 준다.

 

그리고 잘 사용해보진 않지만 다음과 같은 속성도 존재 한다.

 

4) consumes(String[]) : Request Body에 담는 타입을 제한할 수 있다.

ex) @PostMapping("/login", consumes="application/json")

헤더에 application/json이 존재 해야 처리한다.

 

3. 스프링 부트 Controller 생성

이제부터 Test용 Controller 생성하여 서버를 띄워보도록 하자.

(이전 포스팅 까지 하여 Application, index.html을 생성 해두었다.)

▶ TestController 생성 (@Controller)

 - 일단 다음과 같이 테스트용으로 패키지 구조를 잡았다.

 - 원하는 패키지에 Controller.java 파일 생성한다.

 - 먼저 TestController.java 파일을 생성하여 다음과 같이 작성 하였다.

package com.god.bo.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TestController {

    @RequestMapping(value = "/home")
    public String home(){

        return "index.html";
    }

}

 

▶ View 생성 (INDEX 페이지 만들기)

 - src/main/resources/static 경로에 index.html 파일을 추가하고 다음 소스와 같이 코딩 하자.

(static 폴더는 정적 html 문서, 이미지, 영상 등 관리)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>
    <h1>Hello World!</h1>
</body>
</html>

 

▶ 실행하기

 - 이미 생성 해 두었던 Application 파일을 실행 시키고 설정한 URL로 접속해보자. 

 - 파일에서 우클릭 > Run '~~Aplication.main()' 클릭

 - 설정한 URL로 index.html에 접근한 가능한 것을 확인할 수 있다.

 - 추후 포스팅 예정이지만 내장 톰캣 대신 Jetty등 외부 서버를 사용할 수도 있다.

 - 혹시 이미 8080포트를 사용하고 있는 경우엔 포트 변경 하자.

/src/main/resources/application.properties 에 다음과 같이 작성하여 포트 변경한다. (ex 8000)

server.port = 8000

 

 @ResponseBody 로 객체 정보 전달 하기

 - view가 아닌 data를 반환해야 하는 경우라면 @ResponseBody를 사용하면 된다.

 - @ResponseBody 어노테이션을 통해 간단하게는 String, Map, JSON 등을 전달할 수 있고 다음 예제를 통해 간단한 Ajax 통신을 해보자.

package com.god.bo.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {
    @RequestMapping(value = "/home")
    public String home(){
        return "index.html";
    }

    @ResponseBody
    @RequestMapping("/valueTest")
    public String valueTest(){
        String value = "테스트 String";
        return value;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
        $.ajax({
            type: "GET",
            url: "/valueTest",
            success: (data) => {
            console.log(data);
            $('#contents').html(data);
            }
        });
    </script>
</head>
<body>
    <h1>Hello World!</h1>
    <div id="contents">
    </div>
</body>
</html>

 - 서버 재기동시 다음과 같이 값을 전달 받은 것을 확인 할 수 있다.

 @RestController 생성

 - Spring 4.0이상은 @Controller와 @ResponseBody 어노테이션을 추가하는 것 대신 @RestController을 제공하다.

 - @RestController를 사용하면 @ResponseBody를 추가 할 필요가 없고, @ResponseBody 어노테이션은 기본적으로 활성화되어 있다.

package com.god.bo.test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;9

@RestController
public class TestRestController {

    @RequestMapping(value="/testValue", method = RequestMethod.GET)
    public String getTestValue(){
        String TestValue = "레스트컨트롤러 테스트";
        return TestValue;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
        $.ajax({
            type: "GET",
            url: "/testValue",
            success: (data) => {
            console.log(data);
            $('#contents').html(data);
            }
        });
    </script>
</head>
<body>
    <h1>Hello World!</h1>
    <div id="contents">
    </div>
</body>
</html>

 - 서버 재기동 해보자. @Controller + @ResponseBody와 동일한 역할을 하는 것을 확인 할 수 있다.

 - @RestController를 디컴파일 해보면 @Controller와 @ResponseBody를 포함 하고 있는 것을 볼 수 있고 이때문에 위와 같은 기능을 사용할 수 있는 것이다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

스프링부트를 이용해 아주 간단히 Controller 설정을 했습니다.