[Spring] MVC 기본개념
해당 내용은 김영한씨의 강의 및 스프링 프레임워크 공식 문서, 공식문서 번역을 참고하여 작성한 글입니다.
올바르지 않은 내용이 있다면 의견 남겨주세요. 언제든지 환영입니다.
1. DispatcherServlet
1-1. 개념
- SpringMVC 프레임워크에서 FrontController 패턴으로 만들어진 Servlet이다.
- doDispatch()
- mappedHandler = this.getHandler(processedRequest): 핸들러를 조회한다.
- HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()): 핸들러를 처리할 수 있는 어댑터이다.
- ha.handle(processedRequest, response, mappedHandler,getHandler()): 핸들러 어댑터 실행 후 ModelAndView를 반환한다.
- render(mv, request, response): 뷰 렌더링 호출한다.
1-2. 코드
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
// 1. 핸들러 조회
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 2. 핸들러 어댑터 조회 - 핸들러를 처리할 수 있는 어댑터
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통해 핸들러 실행 -> 5. ModelAndView 반환
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
// 뷰 렌더링 호출
render(mv, request, response);
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
View view;
String viewName = mv.getViewName();
// 6. 뷰 리졸버를 통해서 뷰 찾기, 7. View 반환
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 8. 뷰 렌더링
view.render(mv.getModelInternal(), request, response);
}
2. @RequetMapping
2-1. 개념
- 요청 정보 매핑 하며 방법이 2가지 존재한다.
- pathPattern : 스프링 5.3부터 MVC에서 사용할 수 있도록 설정된 방법으로 6.0에서는 기본적 사용가능하다.
- "/resources/ima?e.png" : 경로 세그먼트에서 한 문자 일치
- "/resources/*.png" : 경로 세그먼트에서 0개 이상의 문자와 일치합니다.
- "/resources/**" : 여러 경로 세그먼트 일치
- "/projects/{project}/versions" : 경로 세그먼트를 일치시키고 변수로 캡처합니다.
- "/projects/{project:[a-z]}/versions"+ : 변수를 정규 분포와 일치시키고 캡처합니다.
- antPathMatcher: 문자열 패턴이 정확하게 문자열 경로 일치했을 때 사용되는 방법이다. 효율성이 떨어진 단점이 있다.
- pathPattern : 스프링 5.3부터 MVC에서 사용할 수 있도록 설정된 방법으로 6.0에서는 기본적 사용가능하다.
- GET/POST 요청 둘다 허용된다.
2-2. 코드
@RestController
@RequestMapping("/persons")
class PersonController {
@GetMapping("/{id}")
public Person getPerson(@PathVariable Long id) {
// ...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// ...
}
}
https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html
Mapping Requests :: Spring Framework
A reflected file download (RFD) attack is similar to XSS in that it relies on request input (for example, a query parameter and a URI variable) being reflected in the response. However, instead of inserting JavaScript into HTML, an RFD attack relies on the
docs.spring.io
3. @Controller
3-1. 개념
- Controller임을 나타내며 @Component, 즉 spring의 빈으로 등록하기 위한 기본 어노테이션의 확장 형태이다. 그렇기에 @Controller만 작성해도 spring의 빈으로 등록되며 @RequestMapping 같이 사용해 특정 URL 요청 처리하는 핸들러 메서드를 정의한다.
- @Controller = @Component + @RequestMapping
3-2. ❓미해결
@Controller 없으면 dispatcher-servlet.xml로 설정 하는 과정이 개발자를 고단하게 만든다는 건 이해. 그러나 @Component + @RequestMapping으로 하면 굳이 @Controller가 왜 필요한지 이해 되지 않음. ChatGPT는 웹 컨트롤러를 좀 더 명확히 구분하고 Spring MVC 역할 표현하기 위해 생겼다는데 개발자가 명명규칙을 명확히 작성하는 것과 연관있는건가 싶음.
3-3. 💡@RestController vs @Controller
@RestController = @Controller + @ResponseBody이다. 그래서 클라이언트가 요청한 데이터를 JSON, XML등 형식으로 반환해야 하는 REST API에서 자주 사용된다. 만약 뷰를 반환하고 싶으면 @Controller, 그게 아니라면 @RestController 사용한다.
특성 | @Controller(Spring MVC) | REST API(Spring REST) |
기본목적 | HTML 포함한 웹 페이지 반환 | 데이터(보통 JSON 또는 XML)만 반환 |
HTTP 메서드 | GET, POST, PUT, DELETE등 | GET, POST, PUT, DELETE등 |
주로 사용되는 @ | @Controller, @RequestMapping | @RestController, @RequestMapping |
주요목적 | 웹 애플리케이션에서 사용자 인터페이스 렌더링 | RESTful API(REST API를 더 강조한 표현)의 서비스 데이터 처리 |
3-4. 코드
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* Alias for {@link Component#value}.
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
4. ModelAndView
4-1. 개념
- Model + View, 즉 모델과 뷰를 모두 담을 수 있는 객체다.
- ModelAndView mv = new ModelAndView("form") 으로 뷰 이름
modelAndView.addObject("user", user); 로 모델 데이터 담는다. - @Controller 사용시에 이용한다. @RestController는 ResponseEntity 또는 Java 객체 직접 반환한다.
5. RequestParam
5-1. 개념
- Http 요청 파라미터 받는 @이다.
- @RequestParam("username") 과 request.getParameter("username") 동일하다.