MVC 패턴
MVC : Model, View, Controller
- Appilcation을 개발할 때 사용하는 디자인 패턴이다.
- 애플리케이션의 개발 영역을 구분하여 개발할 수 있어 개발과 유지보수가 용이하다.
‣ Spring MVC 동작 원리
![](https://velog.velcdn.com/images/gabriela/post/2abd12f5-9987-4f9b-b675-699327a4d682/image.png)
![](https://velog.velcdn.com/images/gabriela/post/a7ddb3bc-8bd5-45c6-bdbe-4c8184bec38e/image.png)
• DispatcherServlet
- 스프링 프레임워크의 핵심 서블릿
web.xml
에 관련 정보 작성
- 기본적으로
servlet-context.xml
설정 파일을 읽어서 스프링 프레임워크를 구동함
• servlet-context.xml
<annotation-driven />
@Controller Annotation
을 활성화
- Spring MVC에서 Controller에게 요청하기 위해 필요한 HandlerMapping과 HandlerAdapter를 자동으로 bean으로 등록
HandlerMapping
@Controller
가 적용된 객체를 컨트롤러하고 함
- HandlerMapping은 요청을 처리할 컨트롤러를
@RequestMapping
값을 이용해서 검색함
HandlerAdapter
- 요청을 처리할 컨트롤러의 메소드를 실행함
- 메소드 실행 결과를 ModelAndView 객체로 변환한 뒤 DispatcherServlet에게 반환함
• <resources>
태그
<resources mapping="/resources/**" location="/resources/">
- 웹 구성 요소 중에서 정적 자원(css, js, image 등)의 경로와 주소를 관리하는 태그
- 정적 자원 : 멀티미디어 데이터(이미지, 오디오, 비디오 등), CSS, JS 등
mapping="/resources/**"
: 주소(URL)가 /resources
로 시작하는 경우
/resources/**
: *
이 두개 들어간 경우의 해석은 하위 경로가 여러개를 거칠 수 있다는 의미
location="/resources/"
: /resources/
디렉터리로 연결하라는 의미
• 뷰 리졸버
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- HandlerAdapter에 의해서 반환된 ModelAndView 객체에 저장된 뷰 정보를 처리함
• <context:component-scan base-package="com.spring.app" />
- base-package에 지정된 패키지에 저장된 클래스들을 스캔하고 자동으로 bean을 생성함
@Component
, @Controller
, @Service
, @Repository
등의 Annotation이 추가된 클래스를 bean으로 등록함
- Spring MVC Project의 top-level package와 동일해야 함
‣ Spring MVC 주요 Annotation
Annotation | 의미 | 사용 |
---|
@Controller | 스프링 MVC의 컨트롤러 객체임을 명시 | 클래스 |
@RequestMapping | 특정 RequestURI에 매핑되는 컨트롤러(클래스)나 메소드임을 명시 | 클래스, 메소드 |
@RequestParam | 요청에서 특정 파라미터의 값을 가져올 때 사용 | 파라미터 |
@RequestHeader | 요청에서 특정 HTTP헤더 정보를 가져올 때 사용 | 파라미터 |
@ModelAttribute | 파라미터를 처리한 객체를 뷰까지 전달 | 메소드, 파라미터 |
@Component | Bean으로 만들어 둬야 할 객체임을 명시 | 클래스 |
@Service | 서비스 객체에 추가하는 @Component | 클래스 |
@Repository | DAO 객체에 추가하는 @Component | 클래스 |
@PathVariable | RequestURI에 포함된 값을 가져올 때 사용 | 파라미터 |
@RequestBody | 요청 본문에 포함된 데이터가 파라미터로 전달 | 파라미터 |
@ResponseBody | 반환 값이 HTTP 응답 메시지로 전송 | 메소드, 리턴타입 |
@CookieValue | 쿠키가 존재하는 경우 쿠키 이름을 이용해서 쿠키 값을 가져올 때 사용 | 파라미터 |
@SessionAttribute | Model의 정보를 세션에서 유지할 때 사용 | 클래스 |
‣ Controller
@Controller
가 적용된 클래스
@RequestMapping
을 이용해 요청 URL 및 요청 메소드 파악
- 메소드 단위로 요청을 처리
- 메소드는 결과를 출력할 뷰 이름을 반환
![](https://velog.velcdn.com/images/gabriela/post/d761869e-cf8a-4ce2-b0ce-03a6733ac7ef/image.png)
• Controller Method 반환 타입
- 컨트롤러는 하나의 요청을 하나의 메소드로 처리함
- Spring MVC Pattern에서는 메소드의 반환 타입을
String
또는 void
로 설정할 수 있음
- String : 응답할 Jsp의 이름을 반환한다.
- void : 컨트롤러가 호출한 서비스에서 직접 응답한다. 요청 주소를 Jsp 이름으로 인식한다.
- 기타 : 비동기 통신에서 데이터를 응답한다.
![](https://velog.velcdn.com/images/gabriela/post/04b8abc2-7389-4390-a306-e35ea98fdd71/image.png)
메소드명
매개변수
- HttpServletRequest를 선언해서 사용할 수 있다.
- HttpServletResponse를 선언해서 사용할 수 있다.
- Model을 선언해서
forward
할 정보를 저장할 수 있다.
- HttpSession을 선언해서 사용할 수 있다.
(request로 받아오지 않고 session을 선언해서 사용할 수 있다.)
요청(@RequestMapping)
- 메소드 :
GET
, POST
- URL : 요청 주소
‣ @RequestMapping
- 요청 URL과 요청 메소드를 인식할 수 있는 Annotation
- 요청 메소드에 따라서
@GetMapping
, @PostMapping
등으로 변경할 수 있음
(스프링 버전4 부터 적용)
• @RequestMapping 주요 기능
구분 | 예시 | 의미 |
---|
value | @RequestMapping(value="/") | "/" 요청 |
| @RequestMapping(value={"/", "index"}) | "/"와 "index" 요청 |
| @RequestMapping(value="/member/*.do") | "/member" 로 시작하고 ".do"로 끝나는 요청 |
method | @RequestMapping(method=RequestMethod.GET) | GET 방식(조회) |
| @RequestMapping(method=RequestMethod.POST) | POST 방식(삽입) |
| @RequestMapping(method=RequestMethod.PUT) | PUT 방식(수정) |
| @RequestMapping(method=RequestMethod.DELETE) | DELETE 방식(삭제) |
content type | @RequestMapping(consumes="application/json") | 요청 컨텐트가 JSON임 |
| @RequestMapping(produces="application/json") | 응답 컨텐트가 JSON임 |
‣ web.xml의 기본 URL Pattern
- 기본 Pattern은 컨텍스트 패스(Context Path)로 되어 있음
- 다른 Pattern으로 수정하면 전체 URL이 다르게 설정됨
![](https://velog.velcdn.com/images/gabriela/post/48f3c80b-570b-4ce7-bd81-a4433d3e4d3d/image.png)
• @RequestMapping(value="members") 처리 방식
‣ Encoding Filter
web.xml
에 CharacterEncodingFilter를 추가
request.setCharacterEncoding("UTF-8")
을 대체할 수 있는 필터
![](https://velog.velcdn.com/images/gabriela/post/3d14b49e-840c-4cdb-b568-59de646e2a4d/image.png)
<filter-name>
은 동일해야 한다.
![](https://velog.velcdn.com/images/gabriela/post/a330e066-b9f9-4da2-9762-d7835d91c792/image.png)
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
: 스프링에서 만들어놓은 Char Encoding
필터
‣ Model 인터페이스
- 뷰가 응답 화면을 구성할 때 필요로하는 데이터를 전달하는 인터페이스이다.
(Spring에서 forward
할 정보를 저장하는 곳)
![](https://velog.velcdn.com/images/gabriela/post/693a3b12-aa14-4adf-b2fd-72d61613afbd/image.png)
- jsp로 값을 전달할 때 사용한다.
(JSP/Servlet에서는 request를 이용해서 데이터를 전달하였으나, 스프링에서는 model을 이용하여 데이터를 전달)
![](https://velog.velcdn.com/images/gabriela/post/49dc2d8a-537f-4856-8090-d4efa572249e/image.png)
메소드
addAttribute
: Model에 속성을 추가하는 메소드
(Model Attribute를 사용해서 forward하는 정보를 Model에 저장하는 것이 권고사항이나,
실제 내부 로직(동작)은 request를 이용해서 attribute가 저장된다.)
• @ModelAttribute
- 커맨드 객체를
model
로 전달할 때 이름을 변경하고자 하는 경우에 사용
@ModelAttribute
에서 지정한 이름으로 뷰까지 전달함
‣ 요청 파라미터
• 스프링의 요청 파라미터 처리 방식
- HttpServletRequest의
getParameter()
메소드
@RequestParam
애너테이션
- 커맨드 객체
• HttpServletRequest
- Java EE 표준 방식이다. (사용 권장)
- 요청을 처리하는 HttpServletRequest 인터페이스이다.
- 파라미터로 전달된 값을
getParameter()
메소드를 이용해서 처리한다.
- 파라미터뿐만 아니라
HttpSession session
, String contextPath
와 같은 정보도 꺼낼 수 있으므로 여전히 강력한 도구이다.
(요청 ip등 많은것을 알 수 있는 방식)
![](https://velog.velcdn.com/images/gabriela/post/647f0856-7435-480c-91ea-dde391e889a3/image.png)
• @RequestParam
- 파라미터를 인식하고 변수에 저장하는 애너테이션
- 파라미터의 개수가 적은 경우에 유용
@RequestParam
애너테이션을 생략하고 변수명만 작성할 수 있음
@RequestParam(value="blogNo") int blogNo == int blogNo
주요 메소드
value
: 요청 파라미터의 이름 작성
required
: 요청 파라미터의 필수 여부 지정
(디폴트 true
- 요청 파라미터가 없으면 오류(500번대) 발생)
defaultValue
: 요청 파라미터가 없는 경우에 사용할 문자열 기본값
• 커맨드 객체
- 요청 파라미터를 필드로 가지고 있는 객체를 커맨드 객체라고 한다.
- 요청 파라미터를 필드에 저장할 때
Setter
가 사용된다.
- 요청 파라미터가 많은 경우에 유용하다. (
insert
등)
- 커맨드 객체는 자동으로
Model
에 저장된다.
- 저장될 때 객체명이 아닌 클래스명으로 저장된다.
(클래스명을 LowerCamelCase
로 바꿔서 저장한다.)
- 별도로
model.addAttribute()
를 처리할 필요가 없음
![](https://velog.velcdn.com/images/gabriela/post/d8e891b6-b892-4d2a-9366-1542097c593b/image.png)
‣ Session
• SessionAttributes
@SessionAttributes()
- 클래스 레벨 애너테이션
- 지정한 이름과 동일한 이름을 HttpSession에 저장한다.
{}
로 여러 값(value
)의 저장이 가능하다.
• 세션에 저장하기
@SessionAttributes("title")
@Controller
public class MyController04 {
- HttpServletRequest로부터 HttpSession 얻기
@GetMapping("/article/add.do")
public String articleAdd(HttpServletRequest request) {
HttpSession session = request.getSession();
session.setAttribute("title", request.getParameter("title"));
return "article/result";
}
@GetMapping("/article/add.do")
public String add2(HttpSession session, HttpServletRequest request) {
session.setAttribute("title", request.getParameter("title"));
return "article/result";
}
- @SessionAttributes 예제
- 클래스 레벨의 annotation이다.
Model
에 값을 저장하면 HttpSession에 함께 저장된다.
@GetMapping("/article/add.do")
public String add3(HttpServletRequest request, Model model) {
model.addAttribute("title", request.getParameter("title"));
return "article/result";
}
• 세션 정보 삭제하기
- HttpSession의 invalidate() 메소드
@GetMapping("/article/main.do")
public String main(HttpSession session) {
session.invalidate();
return "index";
}
- SessionStatus의 setComplet() 메소드
@GetMapping("/article/main.do")
public String main2(SessionStatus sessionStatus) {
sessionStatus.setComplete();
return "index";
}
• 세션 정보 확인하기
- HttpSession의 getAttribute() 메소드
@GetMapping("/article/confirm.do")
public String confirm(HttpSession session) {
String title = (String)session.getAttribute("title");
System.out.println(title);
return "index";
}
@GetMapping("/article/confirm.do")
public String confirm2(@SessionAttribute("title") String title) {
System.out.println(title);
return "index";
}
‣ Redirect
- 컨트롤러의 반환값이
"redirect:"
으로 시작하면 리다이렉트로 이동함
response.sendRedirect()
를 대체하는 스프링의 방식
"redirect:"
뒤에는 새로운 요청 URL이 오기 때문에 특정 URLMapping값을 작성해야 함
(뷰이름을 작성하는 것이 아님!)
• Redirect 하는 방법
public String add(){
return "redirect:/list.do";
}
public void add(HttpServletResponse response){
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("location.href='이동경로'");
out.println("</script>");
}
redirect 이동경로
- 반드시 URLMapping 값을 작성한다.
- 이동할 JSP 경로를 작성할 수 없다.
• 응답
forward
는 Model
에 값을 저장해서 전달한다.
redirect
는 redirectAttributes
로 값을 전달할 수 있다.
redirect
는 addFlashAttribute
(주의❕)
| 저장 | 방식 |
---|
select | Model 사용 | forward |
insert / update / delete | RedirectAttributes 사용 | redirect |
짚어보기
base-package
경로가 올바르게 되는지 확인❗중요❗
- RESTful : 메소드에 따라 구분하는 방식
- forword는
jsp
로 이동
- redirect는
mapping
(주소)로 이동
- redirect는
Model
의 전달이 없음(원래 없음)
![](https://velog.velcdn.com/images/gabriela/post/bdcd3dc2-d019-4e62-b808-3276f24b66c7/image.png)