[Spring MVC동작방식] (중요)

:: MVC패턴 모델2와 Spring MVC의 개념을 설명할 수 있어야 함


☞Spring Framework

:: 


☞Spring MVC

:: 컴포넌트들에 다양한 인터페이스 및 구현클래스 제공

:: 컨트롤러나 폼클래스 작성시에 상속받거나 참조 필요없이 비즈니스 로직에 집중한 코드 작성

:: 웹 요청 파라미터와 커맨드 클래스간에 데이터매핑 기능을 제공

:: Validator와 Error처리 기능 제공

::JSP Form을 쉽게 구성하기위한 Tag제공


☞동작 방식

:: 서버 시작 -> 컨테이너 자동으로 만들어짐 -> 지정된 xml문서를 쭉 읽어들이고 컨트롤러 클래스를 bean으로 등록 -> 컨트롤러 안의 

설정대로 핸들러 매핑 객체 만들고 view resolover객체 만들음 -> 요청 url과 매핑되는 컨트롤러 클래스를 사용하라고 정보 저장되어 있음

-> 클라이언트 요청 -> 서블릿 실행 -> 핸들러 매핑-> 요청한 uri구함(저장된 uri값이랑 비교) -> 요청한 컨트롤러 알려줌 

-> 컨트롤러에 요청정보 가져가서 컨트롤러 실행 -> 비지니스로직 처리 -> 결과를 보냄(모델<뷰에서 사용할 데이터>과 뷰) -> 받아온 뷰정보만 꺼내서 view Resolver에 보내고 -> 어떤 뷰를 쓰라는 정보를 넘겨 받음 -> 뷰에서 사용할 데이터를 들고 화면들 만들음 -> 정보를 서블릿으로 보내면 

-> 서블릿은 클라이언트에게 정보를 보냄   


Dispatcher Servlet은 제공하는 API쓸 것

HandlerMapping은 annotation으로 쓸것

ViewResolver는 기본 제공되는 거 쓸 것

직접 만드는 것은 Controller와 View만 만들면 됨


ºDispatcher Servlet

:: 클라이언트의 요청을 전달 받음

:: 결과값(모델,뷰)을 View에 전달하여 응답을 생성


º예제 MVC동작 순서

요청 -> web.xml -> index.jsp -> hello.do요청이 들어감 -> web.xml에서 dispatcher를 객체로 만들음(컨테이너) 

-> 서블릿과 같은 이름의 xml파일을 찾음 -> dispatcher-servlet.xml문서 실행 -> bean객체 생성

-> 컨트롤러를 읽어들여 hello.do 매핑을 컨트롤러에 요청하고 modelandview에 view이름과 model값을 저장

-> servlet에 전달 -> viewresolver에 뷰이름 전달-> 뷰에 model전달


[Controller]


파라미터 저장

1. 컨트롤러 메서드의 매개변수 - 커맨드 객체 타입(파라미터이름 == 변수명)

// 여기서 말하는 커맨드 객체는 자바 빈

// 자바빈 객체를 메서드에 매개변수로 넣어서 파라미터를 저장

2. 파라미터 이름 == 매개변수명

3.@RequestParam("파라미터이름") 매개변수

4.HttpServletRequest타입 매개변수


view name 설정

1. returnType = String, 리턴값 -> viewname

2. returnType = ModelAndView

new ModelAndView().setViewName("viewname");

new ModelAndViewe("viewname");

// ModelAndView 생성자의 첫번째 매개변수는 viewname으로 사용함

3. RequestMapping 요청 url의 앞 뒤를 잘라 보내고 ViewResolver에서 앞 뒤를 붙여서 ViewName을 만든다.

4. httpServletresponse


Model데이터 설정

1. 컨트롤러 메서드의 매개변수 

:: 커맨드 객체 타입


2. 컨트롤러 메서드의 매개변수

 :: Map, Model,ModelMap

 :: Map.put("name", value) // Map 타입

 :: Model.addAttribute("name", value) // Model 타입


3. 리턴타입 

:: return Type을 ModelAndView로 사용

::  new ModelAndView().addObject("name", value);

:: new ModelAndView("viewname");

:: new ModelAndView("viewname", Map타입 구현 객체);

:: new ModelAndView("viewname", "modelname", modelvalue); // 저장할 model데이터가 하나이면

   

4. @ModelAttribute메서드

:: 리턴값은 Model Data가 됨




[View]

:: web-inf에 jsp파일을 만들면 실행을 못했는데 그건 접근 권한이 없기 때문

  하지만 뷰 페이지는 어디에 있던 상관 없지만 url로 바로 실행하지 못하도록 web-inf파일 아래에 view폴더를 만들어서 넣어놓고 사용

:: return 값이 void면 자동으로 모델 name이 지정됨

:: Controller가 지정한 뷰 이름으로부터 응답 결과 화면을 생성하는 View객체를 ViewResolver가 구함

:: Dispatcher-Servlet이 ViewResolver를 알아서 찾아서 사용.

: Mapping되는 View객체가 존재하지 않으면 null을 리턴.


☞구현 클래스

- InternalResourceViewResolver (주로 사용)

:: 이름으로부터 JSPTiles 연동을 위한 View 객체를 리턴한다.

- BeanNameViewResolver (주로 사용)

:: 이름과 동일한 이름을 갖는 빈 객체를 View 객체로 사용한다.

- ResourceBundleViewResolver

::  이름과 View 객체간의 Mapping정보를 저장하기 위해 Resource 파일을 사용한다.

- XmlViewResolver

::  이름과 View 객체간의 Mapping정보를 저장하기 위해 XML 파일을 사용한다.


☞ View 객체

:: render메서드에 model과 요청 url을 매개변수로 받기에 응답을 할 수 있다.


☞ InternalResourceViewResolver설정

:: WEB Application에 접근할 수 있는 View url을 리턴

:: prefix와 suffix를 이용해 url 경로를 추가한 값이 사용될 Resource의 경로가 됨(url은 공백이 들어가도 완성이 됨)


☞ BeanNameViewResolver설정

:: 커스텀 View Class를 View로 사용할 때 bean으로 만들어 씀


☞ XmlViewResulver설정

:: 지정된 xml파일에 있는 View만 쓰고 싶을 때 사용

:: 기본값은 /WEB-INF/views.xml이며 지정할 때 p:location으로 지정하여 사용


☞ 다수의 ViewResolver설정

:: 선언된 순서대로 하나하나 찾아감

:: 우선순위가 높은 ViewResolver가 null값을 리턴하면 다음 우선순위인 ViewResolver를 요청

:: 우선순위를 지정할 때 주의할 점은 InternalResourceViewResolver를 마지막 순위로 지정해야 함

  왜냐, null값을 리턴하지 않기 때문에 우선순위가 낮은 ViewResolver를 실행 할 일이 없어지기 때문.


1
2
3
4
5
6
7
<bean id = "ViewResolver1"
class = "org.springframework.web.servlet.view.BeanNameViewResolver"/>
 
<bean id = "viewResolver2" class = "org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>

// bean id는 다르게 지정하고 우선순위는 위에 먼저 선언한 ViewResolver를 먼저 인식해 실행





☞ LocaleResolver

:: SessionLocaleResolver를 bean으로 등록(class에 i18n이라고 적혀있으면 Locale과 언어에 관련된 class를 다루고 있는 패키지)

:: class에서 주입을 받아 사용

:: 다른 사용방법 중 setter도 없고 Resolver를 등록하지 않고 사용하는 방법도 있다.( RequestContextUtils.getLocaleResolver(request)를 이용 )

:: 더 편한 방법은 LocaleChangeIntercepter Class를 이용해서 변경( HandlerMapping의 interceptors프로퍼티에 등록만 하면 설정 완료)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
index_view.xml
 
<a href="jsp/login/login?language=en">영문</a><br>
<a href="jsp/login/login?language=ko">한글</a><br>
 
dispatcherInternal-servlet.xml
<!-- LocaleChangeInterceptor로 language에 따른 언어변경  -->
 
<bean id="localeResolver" 
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
 
<bean id="localeChangeInterceptor" 
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="language"/>
            
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list></property></bean>





※인터셉터 안먹힐 때 사용하는 다른 방법


1
2
3
4
5
<mvc:interceptors>
    <bean id="localeChangeInterceptor" 
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
p:paramName="language"/>
</mvc:interceptors>




☞ Tiles

:: pom.xml에 tiles추가.

:: definition name은 viewname으로 사용하며 나머지는 기존 설정과 같다.

1
2
3
4
5
6
7
8
9
10
WEB.xml설정

<servlet>
        <servlet-name>dispatcherTiles</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
 
<servlet-mapping>
        <servlet-name>dispatcherTiles</servlet-name>
        <url-pattern>/tiles/*</url-pattern>
</servlet-mapping>
 



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
dispatcher*.xml파일 설정

<!-- LocaleChangeInterceptor로 language에 따른 언어변경  -->
 
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
 
<!-- <bean id="localeChangeInterceptor" 
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="language"/>
            
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean> -->
 
<!-- interceptors가 안먹힐 때 사용하는 방법 -->
<mvc:interceptors>
    <bean id="localeChangeInterceptor" 
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
p:paramName="language"/>
</mvc:interceptors>
 
<bean id="tilesviewResolver"
        class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" />
    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"<!-- difinition 설정파일을 찾는 class  -->
        <property name="definitions">
            <list>
                <value>/WEB-INF/tilesdef/tilesdef.xml</value>
            </list>
        </property>
        <property name="preparerFactoryClass" value="org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory"/>
    </bean>
cs


☞ HTML이외의 뷰 구현

:: 파일 다운로드

:: 엑셀파일 다운로드

:: pdf파일 다운로드


[XML과 JSON응답 처리]



[파일 업로드/다운로드 처리]


<pom.xml>

1
2
3
4
5
6
7
8
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
    </dependency>
    <!-- 등록후 maven dependencies에 commons-fileupload.jar, commons-io.jar파일 두개가 
          리스트에 있어야 함  -->



<dispatcher.servlet.xml>

1
2
<bean id = "multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>




create table report(

sno varchar2(10), --학번

orig_name varchar2(100),--원본 파일 이름(OriginalFilename)

sys_name varchar2(100), -- 업로드된 파일 이름(SystemFilename)

f_size number, -- 파일 사이즈

regdate date -- 업로드 날짜(sysdate)

);



[사용 방법]

1. @RequestParam 사용

2. MultipartHttpServletRequest 사용

3. 커맨드 객체 사용



--.SimpleDateFormat--


☞ Date -> String


new SimpleDateFormat("보여질 패턴").format(new Date())


☞ String -> Date


new SimpleDateFormat("문자열 날짜 패턴").parse("패턴에 맞는 문자열")


new SimpleDateFormat("yyyy/MM/dd").parse("1234/12/12")

:: 패턴과 문자열이 같기에 인식 


new SimpleDateFormat("yyyy/MM/dd").parse("1234-12-12") 

:: 패턴이 다르기 때문에 인식이 안됨



@RequestBody

:: HTTP요청의 본문 body부분

@ResponseBody

:: 메시지 컨버터를 통해 바로 HTTP응답의 메시지 본문으로 변환







'프로그래밍 > Java' 카테고리의 다른 글

java란?  (0) 2019.01.31
spring MVC 게시판  (0) 2018.09.21
Spring 데이터 베이스 연동 지원  (0) 2018.09.11
Spring AOP  (0) 2018.09.10
Spring정리  (0) 2018.09.05

+ Recent posts