본문 바로가기
Tech Interview/Backend(Spring)

스프링 기술 면접 대비 - 스프링 MVC

by ggyongi 2022. 1. 26.
반응형

잊지 말아야 할 기본사항 : 스프링 MVC 패턴의 목적은 결국 HTTP 요청을 처리하고 HTTP 응답 메시지를 만들기 위함이다. 


Q) MVC 패턴이 무엇인가요?
A) 컨트롤러와 뷰라는 영역으로 역할을 나눈 패턴입니다.
컨트롤러는 HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행합니다. 그리고 뷰에 전달할 데이터를 모델에 담습니다.
모델은 뷰에 전달할 데이터를 담아두었다가 뷰에 전달해줍니다.
뷰는 모델에 담겨있는 데이터를 사용해서 화면을 구성합니다.
이렇게 역할을 나누게 되면 각자 할 일에만 집중하면 되므로 코드도 확실히 구분해놓을 수 있고 깔끔해집니다.
+) 일반적으로 비즈니스 로직까지 컨트롤러에서 처리하면 너무 많은 역할을 담당하게 되므로, 서비스라는 계층을 새로 만들어 이곳에서 비즈니스 로직을 처리합니다. 컨트롤러는 이 서비스를 호출하는 역할을 하게됩니다. 


Q) 스프링 MVC 패턴은 어떠한 구조로 이루어져 있나요?
A) 스프링 MVC 패턴에서는 Dispatcher Servlet이 핵심이 됩니다.
1. HTTP 요청이 들어오게 되면, Dispatcher Servlet은 가장 먼저 요청 URL에 매핑된 핸들러(컨트롤러)를 조회합니다.
2. 그리고 이 핸들러를 실행할 수 있는 핸들러 어댑터를 조회합니다. 어댑터가 필요한 이유는 스프링 MVC에서는 다양한 방식의 핸들러를 제공하기 때문에, 이들이 유연하게 사용되기 위해서는 어댑터가 필요합니다.
3. 핸들러 어댑터를 통해 어댑터가 실행되고, 모델-뷰를 Dispatcher Servlet에게 반환해줍니다.
4. Dispatcher Servlet은 이 모델뷰와 뷰 리졸버를 통해 뷰 객체를 반환받습니다.
5. 뷰를 통해 뷰를 렌더링합니다.
+) 쉽게 말하자면, 요청이 들어오면 url에 매핑된 핸들러(컨트롤러)를 찾는데, 이미 알다시피 컨트롤러의 반환 값은 String이 될 수도 있고, 객체가 될 수도 있고 굉장히 다양함. 심지어 파라미터마저 아주 다양함. 이렇게 각기 다른 컨트롤러를 처리해줄 수 있는 어댑터가 필요하다는 것임. 이 어댑터를 통해서 MAV를 잘 만들어서 뷰에 넘겨주는 방식임.


Q) @Controller와 @RequestMapping, @PathVariable은 각각 무엇인가요?
A) @Controller가 있으면 컴포넌트 스캔 대상이 되어 스프링 빈으로 자동 등록이 되며, 컨트롤러로 인식하게 됩니다. 
@RequestMapping은 요청 정보를 매핑할 때 사용되며 해당 URL이 호출되면 이 메서드가 실행됩니다.
@PathVariable은 경로 변수 값을 받아올 수 있습니다.

 


Q) 요청 데이터가 전달되는 방식에는 어떤 것들이 있나요?
A) 총 세 가지 방식이 있습니다.
첫 번째로, GET 요청 시에 쿼리 파라미터로 데이터가 전달되는 방식입니다.
두 번째로, POST 요청 시에 메시지 바디에 HTML Form 데이터를 전달하는 방식입니다.
세 번째는, HTTP body에 직접 데이터를 담아 전송하는 방식입니다. API에서 주로 사용하며 JSON형식을 많이 사용합니다.
이때 메서드는 POST, PUT, PATCH가 될 수 있습니다.


Q) 각각의 경우 어떻게 요청 파라미터를 조회할 수 있나요?
A) 
1, 2 )
첫 번째와 두 번째 방법으로 요청 파라미터가 넘어오는 경우는, 동일한 방법으로 대응할 수 있습니다.
우선 HttpServletRequest가 제공하는 방식인 request.getParameter()를 통해 데이터 조회가 가능합니다.
또 @RequestParam("username")과 같은 방법을 사용하면 좀 더 편리하게 값을 꺼낼 수 있습니다. 괄호는 파라미터 이름을 동일하게 맞추면 생략할 수 있습니다. 
모든 파라미터를 받고 싶으면 Map<String, Object>을 사용해서 한 번에 다 받아올 수 있습니다. 
@ModelAttribute("item") Item item을 사용하면 객체를 생성하고 프로퍼티에 데이터를 자동으로 입력해줍니다. 
뿐만 아니라 Model에 이 객체를 자동으로 넣어주기 때문에 .addAttribute()를 생략할 수 있습니다.
3)
HTTP body로 직접 데이터가 넘어오는 경우는 단순 텍스트가 오는 경우, JSON 형태로 오는 경우로 다시 나눌 수 있습니다.
단순 텍스트의 경우 @RequestBody String messageBody와 같은 방법으로 쉽게 읽을 수 있습니다.
JSON의 경우 @RequestBody Data data와 같이 객체로 받아올 수 있습니다.  
또는 ObjectMapper를 사용해서 객체로 변환할 수도 있습니다.
또는 RequestEntity를 사용하는 방법도 있습니다.


Q) 응답 데이터를 만드는 방식에는 어떤 것들이 있나요?
A) 세 가지 방식이 있습니다.
첫 번째로, 정적 리소스를 사용하여 정적 HTML, CSS, JS를 넘겨줄 수 있습니다.
두 번째로, 뷰 템플릿을 사용하여 동적 HTML을 넘겨줄 수 있습니다.
세 번째로, HTTP 메시지 바디에 JSON과 같은 형태로 데이터를 직접 넘겨줄 수 있습니다.


Q) 각각의 경우 어떻게 응답 데이터를 넘겨주나요?
정적 리소스의 경우 src/main/resources/static 경로에 html 파일을 올려놓으면, http://localhost:8080/basic/hello-form.html 접속 시 바로 정적 리소스를 반환해줍니다.
동적 HTML의 경우 MAV에 addObject로 데이터를 넣어 넘겨줘도 되지만, 반환으로 String 형태의 경로를 넘겨줄 수 도 있습니다. 그럼 뷰 리졸버가 실행되어 뷰를 찾고 렌더링됩니다. (주의할 점은 이때 @ResponseBody가 달려있으면 body에 직접 그 String이 입력됩니다.)
메시지 바디에 직접 입력하는 경우 크게 두가지 경우가 있습니다.
단순 텍스트를 넘겨 주는 경우에는 ResponseEntity를 사용해서 메시지를 넘겨주거나 @ResponseBody를 사용하여 string을 바로 전달합니다.
JSON 형식을 넘겨주는 경우 ResponseEintity에 객체를 담아 전달할 수도 있고, @ResponseBody를 사용하고 객체를 바로 반환해줘도 됩니다.
+) @RestController를 사용하면 해당 컨트롤러에 모두 @ResponseBody가 적용됩니다.


Q) PRG는 어떻게 구현할 수 있나요?
A) 리턴 값으로 "redirect/..."을 직접 넘길 수도 있지만 URL에 변수를 더해주는 경우 ex) + item.id() 에는 인코딩이 안되 위험할 수 있습니다. 그래서 RedirectAttributes를 사용할 수 있습니다. addAttribute를 통해 PathVariable이나 쿼리 파라미터까지 처리할 수 있습니다. 

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글