출처: http://gangzzang.tistory.com/entry/스프링Spring-MVC-프레임워크Model-View-Controller-Framework-1 [갱짱.study]
스프링의 흐름을 가장 잘 설명한 글인것같아서 퍼왔다 참고할것
1. 스프링(Spring) MVC 프레임워크(Model View Controller Framework)
- 스프링이 제공하는 트랜잭션 처리, DI, AOP를 손쉽게 사용
- 스트럿츠2와 같은 프레임워크와 연동이 쉬움
2. 스프링 MVC 주요 구성 요소 및 처리 흐름
- 다른 MVC 프레임워크와 마찬가지로 컨트롤러를 사용하여 요청을 처리
- 스프링에서는 DispatcherServlet이 MVC에서의 컨트롤러(Controller) 부분을 처리
구성 요소 | 설명 |
DispatcherServlet | 클라이언트의 요청을 전달받아 요청에 맞는 컨트롤러가 리턴한 결과값을 View에 전달하여 알맞은 응답을 생성 |
HandlerMapping | 클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지 결정 |
Controller | 클라이언트의 요청을 처리한 뒤, 결과를 DispatcherServlet에게 리턴 |
ModelAndView | 컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담음 |
ViewResolver | 컨트롤러의 처리 결과를 생성할 뷰를 결정 |
View | 컨트롤러의 처리 결과 화면을 생성, JSP 또는 Velocity 템플릿 파일 등을 뷰로 사용 |
3. 스프링 MVC 개발
- 클라이언트에 요청을 받을 DispatcherServlet을 web.xml 파일에 설정
- 클라이언트의 요청을 처리할 컨트롤러 작성
- ViewResolver 설정 (컨트롤러가 전달한 값을 이용해서 응답 화면을 생성할 뷰를 결정)
- JSP나 Velocity 등을 이용하여 뷰영역의 코드를 작성
3.1. DispatcherServlet 설정 및 스프링 컨텍스트 설정
- web.xml(자바 웹 어플리케이션 설정 파일)에 DipathcerServlet 설정 및 공통으로 사용할 어플리케이션 컨텍스트 설정
- <servlet> 태그를 이용하여 DispatcherServlet 설정
- <servlet-mapping> 태그를 이용하여 요청 URL 패턴 설정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!--?xml version="1.0" encoding="UTF-8"?--> <!-- web.xml --> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringBlog2</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> | cs |
3.2. 컨트롤러 구현 및 설정 추가
- @Controller 애노테이션을 클래스에 적용
- @RequestMapping 애노테이션을 이용해서 클라이언트의 요청을 처리할 메서드를 지정
- ModelAndView는 컨트롤러의 처리 결과를 보여줄 뷰와 뷰에서 출력할 모델을 지정
- DispatcherServlet은 스프링 컨테이너에서 컨트롤러 객체를 검색하기 때문에 스프링 설정 파일에 컨트롤러를 빈으로 등록해야 함
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // HelloController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class HelloController { @RequestMapping("/hello.do") public ModelAndView hello() { ModelAndView mv = new ModelAndView(); mv.setViewName("hello"); mv.addObject("message", "Hello Spring MVC"); return mv; } } // HelloController | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!--?xml version="1.0" encoding="UTF-8"?--> <!-- dispatcher-servlet.xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="helloController" class="com.tistory.gangzzang.controller.HelloController"></bean> </beans> | cs |
3.3. 설정 파일 View Resolver 설정 추가
- 컨트롤러에서 ModelAndView.setViewName() 메서드로 뷰이름을 지정
- 이 뷰이름과 매칭되는 뷰 구현체를 찾기 위해 ViewResolver를 사용
- prefix 프로퍼티와 suffix 프로퍼티를 지정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!--?xml version="1.0" encoding="UTF-8"?--> <!-- dispatcher-servlet.xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="helloController" class="com.tistory.gangzzang.controller.HelloController"></bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans> | cs |
3.4. 뷰 코드 구현
- ModelAndView.addObject() 메서드로 모델을 추가할 때 사용한 이름을 이용해서 모델의 값을 사용
1234567891011 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>${ message }</title></head><body>${ message }</body></html>cs
3.5. 실행
- 컨트롤러의 지정된 URL 요청을 주소창에 입력
4. DispatcherServlet 설정과 ApplicationContext의 관계
- web.xml 파일에 한 개 이상의 DispatcherServlet 설정할 수 있으며, 각각 한 개의 WebApplicationContext를 갖음
4.1. DispatcherServlet 설정
- DipatcherServlet는 기본적으로 /WEB-INF/ 디렉터리에 위치한 [서블릿이름]-servlet.xml 파일로부터 스프링 설정 정보를 읽어 옴
- 한개 이상의 설정 파일, 또는 설정 다른 이름의 설정 파일을 사용할 경우 contextConfigLocation 초기화 파라미터에 설정 파일 목록을 지정
- 설정 파일 구분은 콤마(","), 공백 문자(" "), 탭(\t), 줄 바꿈(\n), 세미콜론(";")을 이용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <!--?xml version="1.0" encoding="UTF-8"?--> <!-- web.xml --> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringBlog2</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/beans.xml /WEB-INF/main.xml </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> | cs |
4.2. ApplicationContext 설정
- 한 개 이상의 DispatcheerServlet을 사용할 때 별도의 WebApplicationContext를 생성
- 이 경우 공통 빈을 필요로 할 때 ContextLoaderListener를 사용하여 사용될 빈을 설정
- ServletListener로 등록, contextConfigLocation 컨텍스트 파라미터를 이용, 공통으로 사용될 빈 정보를 담고 있는 설정 파일 목록을 지정
- ContextLoaderListener가 생성하는 WebApplicationContext는 웹 어플리케이션의 루트 컨텍스트
- DispatcherServlet이 생성하는 WebApplicationContext는 루트 컨텍스트를 부모로 사용하는 자식 컨텍스트
- ContextLoaderListener는 contextConfigLocation 컨텍스트 파라미터를 명시하지 않으면 /WEB-INF/applicationContext.xml을 설정 파일로 사용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <!--?xml version="1.0" encoding="UTF-8"?--> <!-- web.xml --> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringBlog2</display-name> <!-- <servlet> <servlet-name>front_dispatcher</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> <servlet> <servlet-name>rest_dispatcher</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> --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/front.xml /WEB-INF/service.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>front</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet> <servlet-name>rest</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> | cs |
5. 캐릭터 인코딩 처리 필터 설정
- 모든 컨트롤러에서 response.setCharacterEncoding() 코드를 실행하는 번거로움을 해소하기 위해 서블릿 필터를 이용 처리
- 서블릿 필터에서 캐틱터 인코딩을 설정할 수 있는 CharacterEncodingFilter 클래스를 제공
- web.xml 파일에 설정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!--?xml version="1.0" encoding="UTF-8"?--> <!-- web.xml --> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringBlog2</display-name> <servlet> <servlet-name>dispathcer</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> | cs |
6. 컨트롤러 구현
- 스프링 3.0 버전 부터는 @Controller 애노테이션을 이용해서 컨트롤러 클래스를 구현하도록 권장
6.1. @Controller 애노테이션, @RequestMapping 애노테이션
- 컨트롤러 클래스에 @Controller 애노테이션 적용
- 클라이언트의 요청을 처리할 메서드에 @RequestMapping 애노테이션 적용
- 설정 파일에 컨트롤러 클래스를 빈으로 등록
- @RequestMapping 애노테이션은 해당 메서드에서 처리할 URI를 값으로 갖음
- @RequestMapping 애노테이션의 메서드의 리턴 타입은 상황에 따라 알맞은 타입을 선택
6.2. 컨트롤러 메서드 HTTP 전송 방식(method) 한정
- 하나의 요청 URL에 대해 HTTP GET 요청과 POST 요청을 한 개의 컨트롤러에서 처리할 경우
- @RequestMapping 애노테이션의 method 속성을 이용해서 메서드가 처리할 HTTP 메서드를 제한
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // HelloController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class HelloController { @RequestMapping(value="/write.do", method=RequestMethod.GET) public String writeForm() { return "writeForm"; } @RequestMapping(value="/write.do", method=RequestMethod.POST) public String writeSub() { return "writeSub"; } } // HelloController | cs |
- 두 메서드가 동일한 URI를 처리하는 경우 @RequestMapping 애노테이션을 클래스에 적용해서 해당 클래스가 처리할 기본 URI를 지정가능
- @RequestMapping 애노테이션에 method 속성을 설정하지 않을 경우 모든 HTTP 전송방식(GET, POST, DELETE 등)을 처리
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // HelloController2.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/write.do") public class HelloController2 { @RequestMapping(method=RequestMethod.GET) public String writeForm() { return "writeForm"; } @RequestMapping(method=RequestMethod.POST) public String writeSub() { return "writeSub"; } } // HelloController2 | cs |
6.3. HTML 폼, 커맨드 객체
- HTML 폼에 입력한 데이터를 자바빈 객체를 이용해서 전달 받음
- HTML 폼의 항목 이름과 자바빈 클래스의 프로퍼티 이름이 일치할 경우 폼에 입력한 값을 프로퍼티 값으로 설정
- @RequestMapping 애노테이션이 적용된 메서드의 파라미터로 자바빈 타입을 추가
- 폼에 입력한 값은 모두 문자열이지만 스프링은 자바빈의 타입 변환 처리 기능으로 프로퍼티의 타입으로 알맞게 변환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!-- writeForm.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>WriteForm</title> </head> <body> <form action="write.do" method="post"> <input type="text" name="name" placeholder="폰 이름" required="required" size="50"><br> <input type="text" name="manufacturer" placeholder="폰 제조사" required="required" size="50"><br> <input type="text" name="price" placeholder="폰 가격" required="required" size="50"><br> <input type="submit" value="작성"><input type="reset" value="취소"> </form> </body> </html> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // PhoneDTO.java package com.tistory.gangzzang.model; public class PhoneDTO { private String name; private String manufacturer; private int price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getManufacturer() { return manufacturer; } public void setManufacturer(String manufacturer) { this.manufacturer = manufacturer; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } } // PhoneDTO | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // PhoneController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.tistory.gangzzang.model.PhoneDTO; @Controller public class PhoneController { @RequestMapping(value = "/write.do", method = RequestMethod.GET) public String writeForm() { return "writeForm"; } @RequestMapping(value = "/write.do", method = RequestMethod.POST) public String wirteSubmit(PhoneDTO phoneDTO) { return "writeSubmit"; } } // PhoneController | cs |
6.3.1. 뷰에서 커맨드 객체 접근
- 뷰에서 @RequestMapping 애노테이션 메서드에서 전달받은 커맨드 객체(자바빈 객체)의 클래스명을 이용해서 접근 가능(단 첫글자는 소문자)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!-- writeSubmit.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>WriteSubmit</title> </head> <body> <input type="text" name="name" placeholder="폰 이름" required="required" readonly="readonly" size="50" value="${ phoneDTO.name }"><br> <input type="text" name="manufacturer" placeholder="폰 제조사" required="required" readonly="readonly" size="50" value="${ phoneDTO.manufacturer }"><br> <input type="text" name="price" placeholder="폰 가격" required="required" readonly="readonly" size="50" value="${ phoneDTO.price }"><br> </body> </html> | cs |
- 뷰에서 사용할 모델의 이름을 변경할 때는 @ModelAttribute 애노테이션을 이용, 커맨드 객체의 모델 이름을 지정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // PhoneController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.tistory.gangzzang.model.PhoneDTO; @Controller public class PhoneController { @RequestMapping(value = "write.do", method = RequestMethod.GET) public String writeForm() { return "writeForm"; } @RequestMapping(value = "write.do", method = RequestMethod.POST) public String wirteSubmit(@ModelAttribute("p") PhoneDTO phoneDTO) { return "writeSubmit"; } } // PhoneController | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!-- writeSubmit.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>WriteSubmit</title> </head> <body> <input type="text" placeholder="폰 이름" required="required" readonly="readonly" size="50" value="${ p.name }"><br> <input type="text" placeholder="폰 제조사" required="required" readonly="readonly" size="50" value="${ p.manufacturer }"><br> <input type="text" placeholder="폰 가격" required="required" readonly="readonly" size="50" value="${ p.price }"><br> </body> </html> | cs |
6.3.2. 커맨드 객체로 List 받기
- 폼에서 "프로퍼티명[인덱스].프로퍼티" 같이 입력 폼의 이름을 구성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // PhoneVO.java package com.tistory.gangzzang.model; import java.util.List; public class PhoneVO { private List<PhoneDTO> phoneItems; public List<PhoneDTO> getPhoneItems() { return phoneItems; } public void setPhoneItems(List<PhoneDTO> phoneItems) { this.phoneItems = phoneItems; } } // PhoneVO | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!-- writeListForm.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>WriteListForm</title> </head> <body> <form action="writeList.do" method="post"> <input type="text" name="phoneItems[0].name" placeholder="폰 이름1" required="required" size="50"><br> <input type="text" name="phoneItems[0].manufacturer" placeholder="폰 제조사1" required="required" size="50"><br> <input type="text" name="phoneItems[0].price" placeholder="폰 가격1" required="required" size="50"><br> <hr> <input type="text" name="phoneItems[1].name" placeholder="폰 이름2" required="required" size="50"><br> <input type="text" name="phoneItems[1].manufacturer" placeholder="폰 제조사2" required="required" size="50"><br> <input type="text" name="phoneItems[1].price" placeholder="폰 가격2" required="required" size="50"><br> <hr> <input type="submit" value="작성"><input type="reset" value="취소"> </form> </body> </html> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // PhoneController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.tistory.gangzzang.model.PhoneDTO; import com.tistory.gangzzang.model.PhoneVO; @Controller public class PhoneController { @RequestMapping(value = "write.do", method = RequestMethod.GET) public String writeForm() { return "writeForm"; } @RequestMapping(value = "write.do", method = RequestMethod.POST) public String wirteSubmit(@ModelAttribute("p") PhoneDTO phoneDTO) { return "writeSubmit"; } @RequestMapping(value = "writeList.do", method = RequestMethod.GET) public String writeListForm() { return "writeListForm"; } @RequestMapping(value = "writeList.do", method = RequestMethod.POST) public String wirteListSubmit(@ModelAttribute("phone") PhoneVO phoneVO) { return "writeListSubmit"; } } // PhoneController | cs |
6.4. 컨트롤러 메서드 파라미터 타입
- 컨트롤러의 @RequestMapping 애노테이션이 적용된 메서드는 커맨드 클래스외에도 다양한 타입의 파라미터를 가질 수 있음
파라미터 타입 | 설명 |
HttpServletRequest, HttpServletResponse, HttpSession | 서블릿 API |
java.util.Locale | 현재 요청에 대한 Locale |
InputStream, Reader | 요청 컨텐츠에 직접 접근할 때 사용 |
OutputStream, Writer | 응답 컨텐츠를 생성할 때 사용 |
@PathVariable 애노테이션 적용 파라미터 | URI 템플릿 변수에 접근할 때 사용 |
@RequestParam 애노테이션 적용 파라미터 | HTTP 요청 파라미터를 매핑 |
@RequestHeader 애노테이션 적용 파라미터 | HTTP 요청 헤더를 매핑 |
@CookieValue 애노테이션 적용 파라미터 | HTTP 쿠키 매핑 |
@RequestBody 애노테이션 적용 파라미터 | HTTP 요청의 몸체 내용에 접근할 때 사용(HttpMessageConverter를 이용, HTTP 요청 데이터를 해당 타입으로 변환) |
Map, Model, modelMap | 뷰에 전달할 모델 데이터를 설정할 때 사용 |
커맨드 객체 | HTTP 요청 파라미터를 저장한 객체, 클래스이름을 모델명으로 사용(@ModelAttribute 애노테이션으로 모델명 설정) |
Errors, BindingResult | HTTP 요청 파라미터를 커맨드 객체에 저장한 결과(커맨드 객체를 위한 파라미터 바로 다음에 위치) |
SessionStatus | 폼 처리 완료 처리하기 위해 사용(@SessionAttributes 애노테이션을 명시한 session 속성을 제거 이벤트 발생) |
6.4.1. @RequestParam 애노테이션 이용 파라미터 매핑
- HTTP 요청 파라미터를 메서드의 파라미터로 전달받을 때 사용
- 애노테이션이 적용된 파라미터가 String이 아닐 경우 실제 타입에 따라 알맞게 타입 변환 수행
- 필수가 아닌 파라미터인 경우 required 속성 값을 false로 지정 (기본 값은 true), 값은 null로 저장
- 필수가 아닌 파라미터인 경우 defaultValue 속성 값으로 기본값을 지정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // ParamController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @Controller public class ParamController { @RequestMapping(value = "param.do", method = RequestMethod.GET) public String param( @RequestParam(value="name", required=false) String name, @RequestParam(value="age", defaultValue="1") int age) { return "param"; } } // ParamController | cs |
6.4.2. @CookieValue 애노테이션 이용 쿠키 매핑
- 쿠키 값을 파라미터로 전달 받을 때 사용
- 해당 쿠키가 존재하지 않으면 500 응답 에러 코드 전송
- 쿠키가 필수가 아닌 경우 파라미터와 같이 required 속성의 값을 false로 지정 (기본값은 true), 값은 null로 저장
- 필수가 아닌 쿠키인 경우 defaultValue 속성 값으로 기본값을 지정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // CookieController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class CookieController { @RequestMapping(value = "cookie.do", method = RequestMethod.GET) public String cookie( @CookieValue(value="name", required=false) String name, @CookieValue(value="age", defaultValue="1") int age) { return "cookie"; } } // CookieController | cs |
6.4.3. @RequestHeader 애노테이션 이용 헤더 매핑
- HTTP 요청 헤더의 값을 메서드의 파라미터로 전달 받을 때 사용
- 해당 헤더가 존재하지 않으면 500 응답 에러 코드 전송
- required 속성과 defaultValue 속성을 위와 같이 사용 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // HeaderController.java package com.tistory.gangzzang.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class HeaderController { @RequestMapping(value = "header.do", method = RequestMethod.GET) public String header( @RequestHeader(value="Accept-Language", required=false) String languageHeader, @RequestHeader(value="user-agent", defaultValue="모름") String agentHeader) { return "header"; } } // HeaderController | cs |
6.4.4. 서블릿 API 직접 사용
- javax.servlet.http.HttpServletRequest / javax.servlet.ServletRequest
- javax.servelt.http.HttpServletResponse / javax.servlet.ServletResponse
- javax.servlet.http.HttpSession
- 스프링 MVC 제공 애노테이션을 이용 정보(파라미터, 헤더, 쿠키, 세션 등)에 접근 할 수 있기 때문에 직접적으로 서블릿 API를 사용해야 하는 경우는 드뭄
- 세가지 경우에 사용(HttpSession의 생성을 직접 제어, 컨트롤러에서 쿠키를 생성, 서블릿 API 사용을 선호)
6.5. 컨트롤러 메서드 리턴 타입
- ModelAndView : 뷰 정보 및 모델 정보를 담고 있는 ModelAndView 객체
- Model : 뷰에 전달할 객체 정보를 담고 있는 Model을 리턴, 뷰 이름은 요청 URL로 부터 결정(RequestTOViewNameTranslator를 통해 뷰 결정)
- Map : 뷰에 전달할 객체 정보를 담고 있는 Map을 리턴, 뷰 이름은 요청 URL로 부터 결정(RequestTOViewNameTranslator를 통해 뷰 결정)
- String : 뷰 이름을 리턴
- View 객체 : View 객체를 직접 리턴, 해당 View 객체를 이용해서 뷰를 생성
- void : 메서드가 ServletResponse나 HttpServletResponse 타입의 파라미터를 갖는 경우 메서드가 직접 응답을 처리한다고 가정, 그렇지 않을 경우 요청 뷰 이름은 요청 URL로부터 결정
- @ResponseBody : 메서드에서 @ResponseBody 애노테이션이 적용된 경우 리턴 객체를 HTTP 응답으로 전송, HttpMessageConverter를 이용해서 객체를 HTTP 응답 스트림으로 변환
6.6. 컨트롤러 클래스 자동 스캔
- @Controller 애노테이션은 @Component 애노테이션과 마찬가지로 컴포넌트 스캔 대상
- <context:component-scan> 태그를 이용 컨트롤러 클래스를 자동으로 로딩
- base-package 속성에 자동 스캔할 패키지 경로를 입력
- 복수의 패키지를 사용하고 싶은 경우 <context:component-scan> 태그를 복수개 작성
1 2 3 4 5 6 7 8 9 10 11 12 | <!--?xml version="1.0" encoding="UTF-8"?--> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.tistory.gangzzang.controller"></context:component-scan> </beans> | cs |
'IT > Spring' 카테고리의 다른 글
[SPRING,JAVA] 프레임워크에 Ajax사용을 위한 JsonView 설정하기, Spring Framework JsonView Ajax Sample (0) | 2018.01.30 |
---|---|
Restful 이란 무엇인가 (0) | 2018.01.19 |
Spring 개인프로젝트 이슈들 정리 (1) | 2018.01.05 |
[스크랩]알아두면 유용한 자주쓰는 어노테이션 (0) | 2018.01.03 |
스프링 타일즈 (Spring Tile) 설정해보기 (4) | 2017.12.29 |