[39일차]Spring MVC, Controller, Handler Method, Response Entity

유태형·2022년 6월 23일
0

코드스테이츠

목록 보기
39/77

오늘의 목표

  1. Spring MVC
  2. Spring MVC 구성요소
  3. Handler Method
  4. Response Entity



내용

Spring MVC

Spring MVC는 스프링의 처리 과정을 3단계로 나누어서 처리한다는 계념입니다. Spring MVC프레임 워크라고도 부릅니다.

MVC = Model + View + Controller로 각각 하는 업무가 다릅니다.



Model

Model은 작업의 결과물을 클라이언트에 반환하기 위한 역할을 합니다. 즉 비즈니스 로직에서의 처리 결과를 담는 역할을 수행합니다.



View

ViewModel데이터를 활용하여 클라이언트 애플리케이션의 화면에 보여지는 리소스(Resource)를 제공하는 역할을 수행합니다.

View는 여러가지 형태로 클라이언트에게 Model값을 반환할 수 있는데 대표적으로 2가지가 존재합니다.

  • HTML : 클라이언트에게 보여질 화면 정보를 전달합니다.
  • JSON : 클라이언트에게 단순히 결과값을 반환합니다.


Controller

Controller는 클라이언트 측의 요청을 직접적으로 전달 받는 엔드포인트(Endpoint)로써 Model과 View의 중간에서 상호 작용을 해주는 역할을 합니다.

비즈니스 로직으로부터 Model데이터를 받아 View에게 전달하는 역할을 수행합니다.

@RestController
@RequestMapping(path = "경로1")
public class 컨트롤러{
	
    @GetMapping("경로2/{동적주소}")
    public 객체 핸들러메서드1(@PathVariable("동적주소") 매개변수){
    }
    
    @PostMapping("경로3")
    public 객체 핸들러메서드2(){
    }
}

@GetMapping, @PostMapping등 HTTP메서드, uri 등을 통하여 헨들러 메서드를 실행할 수 있습니다.

핸들러메서드1은 주소창에 경로1/경로2/{동적주소}, 핸들러메서드2는 주소창에 경로1/경로2 를통해 접근할 수 있습니다.

@RequestMapping("공통경로") 애너테이션은 컨트롤러내의 핸들러메서드들이 공통으로 앞에 거쳐야 할 주소를 지정할 수 있습니다.

{동적주소}@PathVariable("동적주소")동적주소는 둘 모두 동일해야 하며 해당 값을 매개변수로 메서드에서 사용할 수 있습니다.

이외에도 다양한 HTTP메서드들을 사용할 수 있습니다.




Spring MVC 구성요소

모듈설명
DispatcherServlet여러 모듈들에게 권한을 위임하고 업무를 요청하는 역할을 수행합니다. 가장 앞에서 클라이언트의 요청을 받아 들이며, 클라이언트에게 응답을 전달합니다.
Handler MappingDispatcherServlet으로 부터 요청을 받아 핸들러 메서드를 탐색하여 어느 Controller에 있는지 찾아냅니다.
Handler AdapterContoller를 호출하고, Model데이터 View정보를 DispatcherServlet을 반환합니다.
Controller비즈니스 로직에 따라 요청을 처리하고 Model데이터 View정보를 반환합니다.
ViewResolver뷰를 탐색하여 해당하는 뷰를 DispatcherServlet에게 반환합니다.
View응답 데이터를 생성하여 DispatcherServlet에게 반환합니다.


Spring MVC 실행 순서

  1. 클라이언트가 요청을 전송하면 DispatcherServlet이라는 클래스에 요청이 전달됩니다.
  2. DispatcherServlet은 클라이언트의 요청을 처리할 Controller에 대한 검색을 HandlerMapping 인터페이스에게 요청합니다.
  3. HandlerMapping은 클라이언트 요청과 매핑되는 Controller 정보를 다시 DispatcherServlet에게 리턴해줍니다.
  4. 요청을 처리할 Controller 클래스를 찾았으니 이제는 실제로 클라이언트 요청을 처리할 Handler 메서드를 찾아서 호출해야 합니다. DispatcherServlet은 Handler 메서드를 직접 호출하지 않고, HandlerAdpater에게 Handler 메서드 호출을 위임합니다.
  5. HandlerAdapter는 DispatcherServlet으로부터 전달 받은 Controller 정보를 기반으로 해당 Controller의 Handler 메서드를 호출합니다.
  6. Controller의 Handler 메서드는 비즈니스 로직 처리 후 리턴 받은 Model 데이터를 HandlerAdapter에게 전달합니다.
  7. HandlerAdapter는 전달받은 Model 데이터와 View 정보를 다시 DispatcherServlet에게 전달합니다.
  8. DispatcherServlet은 전달 받은 View 정보를 다시 ViewResolver에게 전달해서 View 검색을 요청합니다.
  9. ViewResolver는 View 정보에 해당하는 View를 찾아서 View를 다시 리턴해줍니다.
  10. DispatcherServlet은 ViewResolver로부터 전달 받은 View 객체를 통해 Model 데이터를 넘겨주면서 클라이언트에게 전달할 응답 데이터 생성을 요청합니다.
  11. View는 응답 데이터를 생성해서 다시 DispatcherServlet에게 전달합니다.
  12. DispatcherServlet은 View로부터 전달 받은 응답 데이터를 최종적으로 클라이언트에게 전달합니다.



Handler Method

HandlerMethod는 위의 Controller와 MVC구조를 살펴보면 짐작이 가능할 것입니다. URI로 접근 가능한 Controller 클래스 내에 정의된 비즈니스 로직의 결과물을 반환하는 메서드로 줄여볼 수 있겠습니다.

@PathVariable("동적주소")로 변화하는 주소에 맞게 해당 주소의 값을 가질 수 도있습니다. 또 @RequestParam("파라미터") 매개변수를 이용하여 클라이언트로 부터 입력값을 전달 받을 수도 있습니다.

핸들러 메서드는 문자열과 객체를 반환할 수 있는데, 문자열 반환시 해당 이름을 가진 뷰가 존재하는지 찾고 없으면 문자열 그대로 반환합니다.

@RestController
@RequestMapping(value = "공통경로", produces = {MediaType.APPLICATION_JSON_VALUE})
public class 컨트롤러{
	@PostMapping("/{동적주소}")
    public String 핸들러메서드(@RequestParam("파라미터1") 매개변수1,
    						@RequestParam("파라미터2") 매개변수2,
                            @PathVariable("동적주소") 매개변수3){
                            
    	String response =
        		"{\"" + 
                   "email\":\""+email+"\"," + 
                   "\"phone\":\"" + phone+ 
                "\"}";
        return response;
   	}

}

produces = {MediaType.APPLICATION_JSON_VALUE} : 반환값의 타입을 JSON으로 정의합니다. 없을시 보통의 문자열로 인식합니다.
@RequestParam("파라미터") 매개변수 : 클라이언트의 파라미터에 존재하는 값을 매개변수에 저장합니다.
response : JSON을 반환하므로 JSON형식의 문자열입니다.




ResponseEntity

Spring은 핸들러 메서드가 반환할때 보다 편리하게 클라이언트에게 결과를 되돌려 주기 위해서 ResponseEntity를 제공합니다.

@RestController
@RequestMapping(value = "공통경로")
public class 컨트롤러{
	@PostMapping("/{동적주소}")
    public ResponseEntity 핸들러메서드(@RequestParam("파라미터1") 매개변수1,
    						@RequestParam("파라미터2") 매개변수2,
                            @PathVariable("동적주소") 매개변수3){
                            
    	Map<String,Object> map = new HashMap<>();
        map.put("파라미터1",매개변수1);
		map.put("파라미터2",매개변수2);
        map.put("파라미터3",매개변수3);
        
        return new ResponseEntity<>(map,[HttpHeaders,] HttpStatus.CREATED);
   	}
}

ResponseEntity를 사용하게되면 String을 반환하는것이 아닌 ResponseEntity를 반환하게 됩니다. 따라서 문자열을 어떤 반환값으로 인식할 것인가 지정하는 produces속성이 필요없게 됩니다.

또 개발자가 임의적으로 JSON형식의 문자열을 반환해야 했던것에 비해 단순히 MAP을 만들어 ResponseEntity에 포함시켜주기만 하면 됩니다,

ResponseEntity에는 3가지를 넣을 수 있습니다. 반환값인 Map객체, 헤더에 포함시킬 헤더객체, HTTP상태 코드를 담을 수 있습니다.

HttpStatus.Created : 201, 생성완료
HttpStatus.OK : 200, 완료
HttpStatus.NO_CONTENT : 400, 제거




후기

Controller에 대해서 익혔습니다. 내용이 많아서 아직 정리가 잘 되지는 않습니다. 다른 자료들도 보면서 이해의 폭을 넓혀가야 겠습니다.




GitHub

https://github.com/ds02168/CodeStates_Spring/tree/main/section3-week1-apply

profile
오늘도 내일도 화이팅!

0개의 댓글