※ 스프링 MVC 프레임워크
스프링이 제공하는 트랜잭션 처리나 DI, AOP 등을 손쉽게 사용할 수 있다
스프링은 디스패처 서블릿, 핸들러 매핑, 컨트롤러, 뷰 리졸버로 요청을 전달함
▶ FrontController
클라이언트의 모든 요청을 한 곳으로 집중 시키기 위해서 사용하는 디자인 패턴
▶ 스프링 MVC의 주요 구성 요소
▷ DispatcherServlet : 클라이언트의 요청을 전달받는다. 컨트롤러에게 클라이언트의 요청을 전달하고,
컨트롤러가 리턴한 결과값을 view 에게 전달하여 알맞은 응답을 생성하도록 함
▷ HandlerMapping : 클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지를 결정함
▷ Controller : 클라이언트의 요청을 처리한 뒤, 그 결과를 DispatcherServlet에 알려줌.
▷ ModelAndView : 컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담는다
▷ ViewResolver : 컨트롤러의 처리 결과를 생성할 뷰를 결정함
▷ View : 컨트롤러의 처리 결과화면을 생성함
▶ 스프링 MVC의 처리 흐름
- 99% 면접질문 출제

1. 클라이언트의 요청이 DispatcherServlet 에 전달됨
2. DispatcherServlet 은 HandlerMapping 을 사용하여 클라이언트의 요청을 처리할 컨트롤러 객체를 구함
3. DispatcherServlet 은 컨트롤러 객체를 이용해서 클라이언트의 요청을 처리함
4. 컨트롤러는 클라이언트의 요청 처리 결과 정보를 담은 ModelAndView 객체를 리턴함
5. DispatcherServlet 은 ViewResolver 로부터 응답 결과를 생성할 뷰 객체를 구함
6. 뷰는 클라이언트에 전송할 응답을 생성함
=> 개발자가 직접 개발해야 할 부분
– 클라이언트의 요청을 처리할 컨트롤러와 클라이언트에 응답 결과 화면을 전송할 jsp 등의 뷰 코드임
나머지, DispatcherServlet 이나 HandlerMapping, ViewResolver 등은 스프링이 기본적으로 제공하는 구현 클래스를 사용
▶ 스프링 MVC의 적용 절차
1. web.xml 파일에 DispatcherServlet 등록
2. 클라이언트의 요청에 대한 Controller 작성
3. Spring 설정 파일에 HandlerMapping, Controller, ViewResolver 등록
4. jsp 작성
HandlerMapping
- SpringMVC에서의 Controller 클래스는 Spring에서 제공되는 Controller 인터페이스를 구현한 클래스를 의미함
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.do">helloController</prop>
</props>
</property>
</bean>
= > "/hello.do" 라는 요청에 대해서 "helloController" 라는 이름의 Controller 가 요청 을 처리한다
Controller
<bean id="helloController"
class="com.springweb.test.controller.HelloController" />
= > 앞서 작성한 HelloController를 Bean 으로 등록하면 됨
HandlerMapping에 설정한 Controller 이름과 동일한 id 속성값으로 등록해야 함
ViewResolver
- ModelAndView 객체가 리턴한 View 의 이름을 이용하여 사용자에게 보여줄 뷰(jsp)를 결정하는 역할을 함
=> InternalResourceViewResolver : 접두사(prefix)와 접미사(suffix)를 적절히 지정하면
이 설정을 이용해서 실행할 View 정보를 완성하게 됨
ex ) ModelAndView 에서 View 이름을 "loginResult" 라고 설정했다면,
InternalResourceViewResolver 에 의해 완성된 View 정보는 "/WEB-INF/view/loginResult.jsp" 가 됨
- prefix 와 suffix 가 설정되어있으니까 !
▶ SpringMVC Framework의 Controller 클래스
SpringMVC에서의 Controller 클래스는 Spring에서 제공되는 Controller 인터페이스를 구현한 클래스를 의미함
기본으로 사용자의 요청 하나당 하나의 Controller 클래스가 매핑되므로 다수의 Controller 클래스를 작성해야 함
@ 어노테이션(Annotation, Metadata)
- 컴파일러에게 정보를 알려주거나
- 컴파일할 때와 설치(deployment) 시의 작업을 지정 하거나
- 실행할 때 별도의 처리가 필요할 때 사용함
▷ @Controller
- Controller 클래스를 Controller Bean 으로 인식시키기 위해 사용되는 @Controller 어노테이션
- @Controller 어노테이션이 적용된 클래스는 어떤 Controller 인터페이스 클래스도 상속할 필요가 없음
▷ @RequestMapping
- 클라이언트의 요청방식(GET/POST)에 따라서 수행될 메서드를 다르게 설정할 수 있음
- 기존에 클래스 단위 매핑 => 메서드단위 매핑으로 변경됨
@RequestMapping(contextPath 제외한 절대참조) 를 사용하면 메서드 단위로 매핑을 설정할 수 있다
그럼이제 빈등록만 하면되는거임 !
- @RequestMapping 어노테이션에 method 속성을 설정하지 않을 경우,
get, post 등 모든 http 전송 방식을 처리하게 됨
@Controller
public class LoginController {
@RequestMapping("/login.do")
public ModelAndView login(HttpServletRequest request,
HttpServletResponse response) {
}
}
- 메서드에 @RequestMapping는 필수이며
클래스에 @RequestMapping는 선택이다.
[1] @RequestMapping : 클라이언트가 get방식으로 입력 폼을 요청하는 경우
= 입력 화면을 보여주고, 입력화면에서 submit 버튼을 클릭하여 post 방식으로 요청할 경우의 처리 방법
@Controller
public class LoginController {
@RequestMapping(value="/login.do", method=RequestMethod.GET)
public String loginView(HttpServletRequest request,
HttpServletResponse response) {
}
@RequestMapping(value="/login.do", method=RequestMethod.POST)
public String login(HttpServletRequest request,
HttpServletResponse response) {
}
}
• /login.do 요청에 대해서 GET방식으로 요청이 들어오면 loginView() 메서드를 실행하여 로그인 화면을 보여줌
• /login.do 요청에 대해서 POST 방식으로 요청이 들어오면 login()메서드를 실행하여 로그인 처리 작업 수행하도록함
[2] @RequestMapping : 클라이언트의 요청이 동일한 URL을 사용할 경우
@Controller
@RequestMapping("/login.do")
public class LoginController {
@RequestMapping(method=RequestMethod.GET)
public String loginView(HttpServletRequest request,
HttpServletResponse response) {
}
@RequestMapping(method=RequestMethod.POST)
public String login(HttpServletRequest request,
HttpServletResponse response) {
}
}
• 동일한 /login.do 요청에 대해서 GET방식으로 요청이 들어오면 loginView() 메서드를 실행하여 로그인 화면을 보여줌
• POST 방식으로 요청이 들어오면 login()메서드를 실행하여 실질적인 로그인 처리 작업을 수행하도록 함
▶ 클라이언트 요청 처리
[1] 클라이언트에게 정보 받아서 post 방식으로 보내기
- id , password 라는 name 에 담아져서 보내짐
<form name="frm1" method="post" action="/login.do">
아이디 : <input type="text" name="id"><br>
비밀번호 : <input type="password" name="password"><br>
<input type="submit" value="전송">
</form>
[2-1] 컨트롤러에서 보내진 정보를 request 를 이용하여 받아 db작업하기
- request.getParameter 로 전달된 id, password 를 받아 변수에 저장하고 db작업
@Controller
public class LoginController {
@RequestMapping("/login.do")
public String login(HttpServletRequest request) {
String id = request.getParameter("id");
String password = request.getParameter("password");
UserVO vo = new UserVO();
vo.setId(id);
vo.setPassword(password);
int n = userService.insertUser(vo);
}
}
[2-2] @RequestParam 을 이용하여 이렇게 처리할 수도 있음
- (@RequestParam String id, @RequestParam String password)
@Controller
public class LoginController {
@RequestMapping("/login.do")
public String login(@RequestParam String id, @RequestParam String password)
throws Exception {
UserVO vo = new UserVO();
vo.setId(id);
vo.setPassword(password);
int n = userService.insertUser(vo);
}
}
@RequestParam : 파라미터하나하나 읽어오는 것
- 실제 타입에 따라서 알맞게 타입 변환을 수행함
requestParam 이 적용된 것은 기본적으로 필수 파라미터이다
필수파라미터가 보내지지않는다면 400에러가 발생한다.
따라서 필수가 아닌 경우에는 required 속성값을 false 로 지정 !
필수가 아닌 요청 파라미터의 값이 존재하지 않을 경우 = null
파라미터를 받는 변수가 null 을 못받는 경우에는 타입에러 발생 ( 에러 : null 을 기본 데이터 타입으로 변환할 수 없음 )
= > defaultValue 속성을 이용해서 기본값을 지정
@RequestMapping("/search/external.do")
public ModelAndView searchExternal(@RequestParam(value="query", required=false) String query,
@RequestParam(value = "p", defaultValue = "1") int pageNumber) {
System.out.println("query=" + query + ",pageNumber=" + pageNumber);
return new ModelAndView("search/external");
}
[2-3] 와 미쳤네 이렇게 바로 VO로 넣을수도 있음
- 복잡하고 길게 작성되는 login() 메서드를 자바빈을 이용해서 구현하면 간단하게 구현할 수 있음
- (@ModelAttribute UserVO vo)
@Controller
public class LoginController {
@RequestMapping("/login.do")
public String login(@ModelAttribute UserVO vo) throws Exception {
int n = userService.insertUser(vo);
}
}
login() 메서드의 매개변수로 사용자가 입력한 값을 매핑할 수 있는 자바빈을 등록하면 (손을 벌렸다)
Spring 컨테이너가 자바빈을 생성하여 넘겨줌 (스프링이 넣어준다)
- 이때 사용자가 입력한 값을 자바빈의 property에 자동으로 채워주기까지 함
- 그니까 UserVO 에 name 이 id와 password 인 것을 자동으로 set 해주는 거임
(입력폼에서 name="id"라는 input 박스에 입 력한 값은 UserVO객체의 id변수에 자동으로 저장됨)
=> 사용자가 입력한 값 추출과 자바빈 생성 및 값 설정 과정을 컨테이너에 의해서 자동으로 처리할 수 있는데,
이런 자바빈을 Command 객체라고 함
▶ Command 객체
- Command 객체로 설정된 값을 view 로 forward 하면 해당 view에서도 쓸 수 있다
jsp 에서 Command 객체 활용
@moldeAttribute : 사용자입력을 왕창받아와서 VO에 셋팅하는것
@RequestMapping("/login.do")
public String login(@ModelAttribute UserVO user)
throws Exception {
}
=> input name 으로 넘긴값은 모두 UserVO 에 셋팅된다.
VO 안의 값을 가져오려면 ${} EL 구문을 사용하자 !
<body>
<h3>${userVO.id}님 로그인 환영합니다.</h3>
</body>
login() 메서드가 실행된 이후에 (UserVO 에 값이 set됨)
클라이언트에 전송되는 jsp에서는 Command 객체의 이름을 통해서 프로퍼티에 접근할 수 있음
(단, jsp에서 Command 객체를 사용하기 위해서는 Command 클래스 이름을 소문자로 해서 접근해야 함)
▶ 넘어온 파라미터의 값이 NULL 인경우 ? !
=> defaultValue 사용 !
@RequestParam(value="searchKeyword", defaultValue="")
redirect 를 하고싶으면 redirect:/ 을 ㅅ사용하면됨
보통은 forward
스프링 MVC를 이용하여 웹 어플리케이션을 개발 하는 과정 [1] 클라이언트의 요청을 받을 DispatcherServlet 을 web.xml에 설정함 [2] 클라이언트의 요청을 처리할 컨트롤러를 작성함 [3] ViewResolver를 설정함 ViewResolver는 컨트롤러가 전달한 값을 이용해서 응답 화면을 생성할 뷰를 결정함 [4] jsp 등을 이용하여 뷰 영역의 코드를 작성함
+ bean 등록, 와이어링
DispatcherServlet 설정과 ApplicationContext 의 관계
web.xml 파일에 한 개 이상의 DispatcherServlet 을 설 정할 수 있으며, 각 DispatcherServlet 은 한 개의 WebApplicationContext 를 갖게 됨
기존 context = servlet context
이 context = 자바객체 (설정화일에 bean 등록되어있는)를 관리해주는 context
=> dispatcherservlet 당 1개가 생성됨
그래서 여러개으 ㅣdispatcherservlet 을 등록할 수있음
설정화일에서 만들어지는 자바 객체들은 여기서 만들어지는 Context 에서 관리를 한다
servlet>
<servlet-name>front</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/front.xml</param-value>
</init-param>
</servlet>
여기서 만들어지는건 위의 dispatchersevlet 의 context 에서 관리
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/rest.xml</param-value>
</init-param>
</servlet>
여기서 만들어지는건 위의 dispatchersevlet 의 context 에서 관리
context 는 서로 다른 설정화일에 있는 자바 객체는 사용하지 못함
=> 공통으로 사용할 수 있는것이 필요함 로 다른 DispatcherServlet 이 공통 빈을 필요로 하는 경우
=> 방법 : ContextLoaderListener 를 사용하여 공통으로 사용될 빈을 설정할 수 있게 됨
ContextLoaderListener 는 부모컨텍스트이다. 자식들은 부모 컨텍스트의 자바객체를 사용할 수 있다
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
=> 공통빈은 부모 설정화일에 넣는다
'Spring' 카테고리의 다른 글
| [Spring] spring boot 스프링부트 (0) | 2022.05.31 |
|---|---|
| [Spring] mybatis (0) | 2022.05.30 |
| [Spring] 스프링 프레임워크 (0) | 2022.05.24 |
| [jsp]JSTL (0) | 2022.05.24 |
| [jsp] 표현언어 (0) | 2022.05.22 |