최범균의 스프링책과 인터넷 검색 결과를 바탕으로 만든 자료입니다.

스프링 MVC는 html form 안의 데이터를 자바빈 객체로 전달받을 수 있다.
기본빈이다. 말그대로 get/set을  정의한 표준빈 형태...

방법은 간단하다.

1. 폼 데이터 받기
HTML폼의 데이터를 자바빈으로 가져오려면, 
@RequestMapping 어노테이션을 적용한 메소드의 파라미터에 자비빈 타입을 추가하기만 하면된다. (이를 커맨드객체라고 하는건가??? )

그게... 만약 html의 form 에 input 의 name에 맞는 set/get 을 가진 빈을 만들어 넣으면 거기에 값이 들어가있는것...

@RequestMapping(method = RequestMethod.POST)
public String submit(폼에맞춘빈클래스 command) {
command.getXxx();
        .... 
}

2. 뷰에서 데이터 접근
위의 내용을 view 에서 접근할 수 있는데 JSTL EL로 접근한다.

예로, NewArticleCommand 타입의 커맨드객체를 전달받았다면...
@RequestMapping(method = RequestMethod.POST)
public String submit(NewArticleCommand command) {
    ....
}

이런경우, view 에서는 클래스이름을 이용해서 객체에 접근할 수 있다.

<body>
....
제목 : ${newArticleCommand.title}
....

근데 이건 좀 아니지; 클래스명을 쓰긴 뭐하잖아? 바꿀 수 있다.


@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") NewArticleCommand command) {
articleService.writeArticle(command);
return "article/newArticleSubmitted";
}


<body>
....
제목 : ${command.title}
....
 

3. 뷰에서 콜렉션 타입 받기 
특별한것도 없고 List 타입의 값을 받으면된다.
다음엔 xxx[i].변수
로.. [인덱스] .. 배열처럼 접근하면된다.


4. 컨트롤러가 있는 RequestMapping된 메서드의 파라미터 종류
@RequestMapping 이 적용된 메소드에는 커맨드클래스 말고도 HttpServletRequest, HttpSession, Locale 등 웹 어플리케이션 관련 다양한 타입의 파라미터를 가질 수 있다.

종류...
 파라미터 타입설명 
 HttpServletRequest, HttpServletResponse HttpSession 서블릿
 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폼 처리를 완료 했음을 처리하기 위해 사용. @SessionAttribute 어노테이션을 명시한 session 속성을 제거하도록 이벤트를 발생시킨다. 


Errors와 BindingResult는 연관된 커맨드 객체 바로 다움에 와야한다. (메소드의 파라미터 위치에 말야) 이 두 타입을 제외한 나머지 타입은 순서에 상관없다.



4.1 @RequestParam

컨트롤러 구현시 가장 많이 쓴단다.
HTTP 요청 파라미터를 메소드의 파라미터로 전달받을때 사용.

즉 html로 요청을 받을때 존재하는 파라미터를 바로 어떤 변수와 매핑시키는 역할이다.
사실 이건 그냥 꺼내와서 변수에 넣으면 ... 이게 바로 @RequestParam 어노테이션이 하는 내용과 같아진다.


ex)
.../search/internal.do?query=spring&p=3

@RequestMapping("/search/internal.do")
public ModelAndView searchInternal(@RequestParam("query") String query,
                               @RequestParam(value = "p", defaultValue = "1") int pageNumber) {
        ...
}

딱보니 뭔지 알겠지?

만약 위에서 p 값에 숫자가 아닌 값이 오게 되면 400 에러를 웹 브라우저에 보낸다. (Bad Request)
@RequestParam이 오면 필수 파라미터가 된다. 이를 필수가 아니게 하고 싶다면...?

required=false 이다.

@RequestMapping("/search/external.do")
public ModelAndView searchExternal(@RequestParam(value="query", required=false) String query,
                                                @RequestParam(value = "p", defaultValue = "1") int pageNumber) {
 
만약 필수 파라미터인데 html에서 오지 않았다면? null을 할당한다.
허나.. 그 타입이 null을 할당할 수 없다면? 에러를 발생한다;; 이를 피하기 위해서 defaultValue를 이용한다.



4.2 @CookieValue 어노테이션

쿠키값을 전달받을 수 있다.

@RequestMapping("/cookie/view.do")
public String view( @CookieValue( "auth" ) String auth) {

위의 경우 auth 라는 쿠키를 찾는데 없으면 500 에러가 나온다.
이때 required=false 하면, null을 전달 받는다.

@RequestMapping("/cookie/view.do")
public String view( @CookieValue(value="auth" , required=false ) String auth) {


defaultValue를 통한 값 설정도 가능하다.
@RequestMapping("/cookie/view.do")
public String view( @CookieValue(value = "auth", defaultValue = "0") String auth) {
 

4.3 @RequestHeader 어노테이션을 이용한 헤더 매핑
HTTP 요청 헤더의 값을 메소드 파라미터로 전달한다.
(즉... UA 값등...)


@RequestMapping("/header/check.do")
public String check(@RequestHeader("Accept-Language") String languageHeader) {
...
}

역시 헤더에 값이 존재 하지 않으면 500리턴한다. 역시 required 및 defaultValue 값을 설정할 수 있다.

4.4 서블릿 API 사용 (HttpServletRequest, HttpServletResponse , HttpSession)

보통은 안쓰지만, 사용하게 되는 경우는...
ㄱ. HttpSession의 생성을 직접 제어해야하는 경우
ㄴ. 컨트롤러에서 쿠키를 생성해야 하는 경우
ㄷ. 서블릿 API 사용을 선호하는 경우

HttpSession 타입의 파라미터를 가질경우,  
기존의 세션이 존재하면 그게오고, 없다면 새로 세션이 생성되어서 온다.
하여 null일 수 없다.


 

5. 뷰 이름 지정
5.1 뷰 이름 명시적 지정


뷰이름을 명시적으로 지정하려면 ModelAndView 나 String을 리턴하면된다.

@RequestMapping("/index.do")
public ModelAndView index() {
ModelAndView mav = new ModelAndView("index");
            ....
            return mav;
}

위처럼 생성자를 통해서나 serViewName() 을 통해서 지정할 수 있다.

아니면 리턴타입을 String으로 해서

public String index() {
    return "index";
}

로 할수도 있다.

5.2 뷰 이름 자동 지정

ㄱ. 리턴타입이 Model 이나 Map 인경우
ㄴ. 리턴 타입이 void 이면서 ServletResponse 나 HttpServletResponse 타입의 파라미터가 없는 경우.

위의 경우는 RequestToViewNameTranslator를 이용해서 URL로 부터 뷰 이름을 구한다.

.xml 설정파일에 RequestToViewNameTranslator 빈이 존재하지 않을 경우는 DefaultRequestToViewNameTranslator가 사용된다.

DeafultRequestToViewNameTranslator 는 요청 URI로부터 맨 앞의 슬래시와 확장자를 제외한 나머지 부분을 뷰 이름으로 사용한다.
(즉, 전체경로를 사용하지 않도록 설정한 경우 서블리 경로를 제외한 나머지 경로가 사용된다)

@RequestMapping("/search/game2.do")
public Map<String,Object> search() {
    HashMap<String,Object> model = new HashMap<String,Object>();
    ....
    return model;
}

위예제에서는 뷰에서 쓸 데이터모델을 Map을 이용한 모델로 리턴하고 있다. 이 경우 RequestToViewNameTranslator 를 이용해서 
결과를 보여줄 뷰 이름을 결정하게 된다. DefaultRequestToViewNameTranslator가 사용될 경우

ex) /search/game2.do --> search/game2


5.3 리다이렉트 뷰 

뷰 이름에 redirect: 접두어를 붙이면 해당 페이지로 리다이렉트된다.

- redirect: /bbs/list  --> 현재 서블릿 컨텍스트에 대한 상대적인 경로로 리다이렉트
- redirect: http://host/bbs/list --> 지정한 절대  URL로 리다이렉트













3.0 에서는 Controller 어노테이션을 이용해서 컨트롤러 클래스를 구현한단다. (과거에는 AbstractController 등을 썼음)

1. 기본구현
@Controller , @RequestMapping 어노테이션을 이용하면된다.

@Controller
public class HelloController {
@RequestMapping("/hello.do")
public String hello() {
            return "hello";
        }

@RequestMapping 어노테이션의 값에는 해당 메소드에서 처리할 URI가 무엇인지를 정의한다.
위의 경우 리턴값이 ModelAndView 가 아니라 String인데 이는 바로 이값이 ViewName이 된다.
이 뷰이름으로 ViewResolver 를 통해서 실제 view 파일을 가져와서 보여주겠지..


2. 전송방식... GET/POST
어차피... 이건 웹 어플리케이션이다. 전송하는 방식은 GET/POST 겠지.
같은 URL 이고 get/ post 의 다른 방식의 전송을 할때 다르게 처리가능하다.

@Controller
public class NewArticleController {
 
@RequestMapping(value="/article/newArticle.do", method = RequestMethod.GET)
public String form() {
return "article/newArticleForm";
}

@RequestMapping(value="/article/newArticle.do", method = RequestMethod.POST)
public String submit(@ModelAttribute("command") NewArticleCommand command) {
return "article/newArticleSubmitted";
}

public void setArticleService(ArticleService articleService) {
this.articleService = articleService;
}

}

만약 위처럼 처리하는 메소드가 동일한 URI에 대해서 처리하는것이라면 기본 URI를 지정할 수 도 있다.

@Controller
@RequestMapping("/article/newArticle.do")
public class NewArticleController {
 
@RequestMapping(method = RequestMethod.GET)
public String form() {
...
}

@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") NewArticleCommand command) {
...
}
...
}

만약 RequestMapping 어노테이션에 method 설정은 안하면 ,GET/POST 등 모든 HTTP 전송방식을 처리한다.



RequestMapping 에 대한 어노테이션 기능은 별도의 문서에 정리했다. 참고바란다.

3. 컨트롤러 메소드의 리턴타입?

매핑된 컨트롤러의 메소드가 해야할 일을 처리한다음... 뭔가를 리턴할것이다.
그 타입에 대한 설명이다.
@RequestMapping 메소드의 리턴타입
리턴타입 설명
ModelAndView 뷰 정보 및 모델정보를 담고 있는 ModelAndView 객체
Model 뷰에 전달할 객체 정보를 담고 있는 Model을 리턴한다. 이때 뷰 이름은 요청 URL로부터 결정된다.(RequestToViewNameTranslator 를 통해 뷰 결정)
 Map 뷰에 전달할 객체 정보를 담고 있는 Model을 리턴한다. 이때 뷰 이름은 요청 URL로부터 결정된다.(RequestToViewNameTranslator 를 통해 뷰 결정)
 String 뷰 이름을 리턴한다.
 View 객체View 객체를 직접 리턴, 해당 View 객체를 이용해서 뷰를 생성한다. 
 void메소드가 ServletResponse나, HttpServletResponse 타입의 파라미터를 갖는 경우 메소드가 직접 응답을 처리한다고 가정한다. 그렇지 않을 경우 요청 URL로 부터 결정된 뷰를 보여준다.(RequestToViewNameTranslator를 통해 뷰 결정) 
 @ResponseBody 어노테이션적용
메소드에서 @ResponseBody 어노테이션이 적용된 경우, 리턴객체를 HTTP응답으로 전송한다. HttpMessageConverter를 이용해서 객체를 HTTP 응답 스트림으로 변환한다. 


4. 컨트롤러 클래스 자동스캔
@Controller 어노테이션은 @Component 어노테이션과 마찬가지로 컴포넌트 스캔대상이다. 
<context:component-scan> 태그를 이용해서 아래처럼 선언해서 (xml) 어노테이션이 적용된 컨트롤러를 자동으로 로딩할 수 있다.

<context:component-scan base-package="madvirus.spring.chap06.controller" />


 



'IT > 스프링' 카테고리의 다른 글

@ModelAttribute  (2) 2012.01.13
모델 생성.... (Model )  (0) 2012.01.13
filter....  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10


스프링은 요청 파라미터의 캐릭터 인코딩을 설정할 수 있는 필터클래스인 CharacterEncodingFilter 클래스를 제공한단다...

         <filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>  // encoding을 통해서 지정
<param-value>EUC-KR</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>











'IT > 스프링' 카테고리의 다른 글

모델 생성.... (Model )  (0) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09



최범균님의 스프링과 인터넷검색을 기반으로 제가 볼 용도의 글을 쓰는것입니다.

우선 web.xml에 dispatcherServlet 이름을 지정하여 생성하는데, 그러면 [dispatcherServlet이름]-servlet.xml 이 설정파일이 된다.

이때 servlet.xml 에 무식하게 다 적는 방법이 아닌 다른 설정을 불러와서 추가 하고 싶은경우가 있다면?

DispatcherServlet을 설정할때, contextConfingLocation 초기화 파라미터에 설정파일 목록을 지정하면된다. 
구분자는  콤마(,) 공백 , 탭, 줄바꿈(\n) , 세미콜론(;) 가 가능하다.

        <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/main.xml /WEB-INF/bbs.xml</param-value>
</init-param> 
 
</servlet>

요런식으로 가능하게 된다.

혹은 dispatcherServlet 자체를 여러개 만들어도 된다.
 
        <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>
        <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>

그럼 front-serlvet.xml 과 rest-servlet.xml 2개의 설정파일이 생기게 되는데, 이때 같은빈을 각각의 설정파일에서 등록하고 있다면?
이를 공통화할 수 있다.
공통으로 사용될 빈 객체 정보를 담고 있는 설정파일목록을 아래처럼 service에 넣어서 처리가능하다.

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
        /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>

ContextLoaderListener 가 생성하는 WebApplicationContext 는 웹어플리케이션에서 루트컨텍스트, DispatcherServlet이 생성하는 WebApplicationContext는 루트 컨텍스트를 부모로 사용하는 자식 컨텍스트가 된다. 자식은 root가 제공하는 빈을 쓸 수 있으므로 ContextLoaderListener 를 이용하여 설정하는것임

ContextLoaderListener 는 contextConfigLocation 컨텍스트 파라미터를 명시하지 않으면 /WEB-INF/applicationContext.xml 을 설정 파일로 사용한다.

<param-value> classpath:xxx.xml</param-value>
하면 클래스패스에 위치한 파일로부터 설정 정보를 읽어온다.

 
 

 



'IT > 스프링' 카테고리의 다른 글

@Controller 어노테이션... - 1 -  (0) 2012.01.10
filter....  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09
weaving??  (0) 2012.01.09

from http://ihoney.pe.kr/entry/%EC%9A%B0%EB%B6%84%ED%88%AC-%ED%95%9C%EA%B8%80%ED%8F%B0%ED%8A%B8-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%95%88%ED%8B%B0%EC%96%BC%EB%A6%AC%EC%96%B4%EC%8B%B1-%EC%A0%81%EC%9A%A9%EB%B2%95



우분투 9.10 버전을 어렵게 어렵게 설치를 한 후, 어색한 폰트들 대신 익숙한 나눔폰트 계열로 수정하려고 하다가 이렇게 기록으로 남긴다. 다른 사람 블로그 찾아다니는 것이 귀찮은 게 가장 크다고 할까? ^^;;

# sudo nautilus

명령실행하여 root 권한을 가진 노틸러스를 실행시킨다.

# /usr/share/fonts/trutype 로 이동 하여 폴더를 생성한다. 생성된 폴더에 원하는 폰트들을 넣는다.


그런 후 터미널에서 

# sudo -s
passwd 입력
# fc-cache -f -v


폰트 리스트 점검을 하는 과정이 완료되고 난 후에 우분투 폰트 리스트에 해당하는 폰트들이 추가가 되었음을 확인해볼 수 있다.

우분투에서는 안티앨리어싱을 끄도록 설정이 되어 있기 때문에, 새로 추가된 폰트들을 넣을 경우 계단지어지고 깨지는 어색한 모습을 볼 수 있다. 폰트와 관련된 안티앨리어싱을 끄도록 하자. 

터미널에서 아래의 명령어를 실행한다.
# sudo gedit /etc/fonts/conf.d/29-language-selector-ko-kr.conf


열린 gedit 의 내용 중에서 아래 항목을 찾아 <match target~ 부분을 주석처리(<!-- -->로 막는다. 
<!-- Turn off antialias and autohint for Korean fonts depending on pixelsize -->
<!-- <match target="font">
        <test name="lang" compare="contains">
                <string>ko</string>
        </test>
        <test name="pixelsize" compare="more">
        <int>10</int>
    </test>
        <test name="pixelsize" compare="less">
        <int>22</int>
    </test>
        <edit name="antialias" mode="assign">
        <bool>false</bool>
    </edit>
        <edit name="autohint" mode="assign">
        <bool>false</bool>
    </edit>
        <edit name="hintstyle" mode="assign">
        <const>hintmedium</const>
    </edit>
</match> -->


다음 항목 을 찾아 마찬가지로 주석처리한다.
<!-- Turn off antialias and autohint for ttf-alee depending on pixelsize -->
<!-- <match target="font">
        <test name="family">
                <string>Guseul</string>
        </test>
        <edit name="autohint" mode="assign">
        <bool>true</bool>
    </edit>
</match>
<match target="font">
        <test name="family">
                <string>Guseul</string>
                <string>Guseul Mono</string>
        </test>
    <test name="pixelsize" compare="more">
        <int>11</int>
    </test>
    <test name="pixelsize" compare="less">
        <int>16</int>
    </test>
    <edit name="antialias" mode="assign">
        <bool>false</bool>
    </edit>
        <edit name="autohint" mode="assign">
        <bool>false</bool>
    </edit>
</match> -->


※ 이 옵션은 저 파일을 삭제하는 것과 동일하므로, 차라리 저 파일을 삭제하는 것도 괜찮다.
Alt + F2 하신 다음,
gksu rm /etc/fonts/conf.d/29-language-selector-ko-kr.conf


최범균님의 스프링과 인터넷검색을 기반으로 제가 볼 용도의 글을 쓰는것입니다.



흐음.. 이게 벌써 몇번째 정리인지 모르겠다.

아무튼 스프링책을 다시 보면서 정리하는 중이니 역시 정리하겠다. 스프링 또한 여차 프레임웍처럼 스프링 MVC를 제공한다.

간단하게 정리하자면.. 이 모든것을 총괄하는 커맨드센터격는 DispatcherServlet 이다.

1. 기본흐름

클라이언트 ---- 요청 ----> DispatcherServlet 

DispatcherServlet ---- 처리할 컨트롤러 파악 ----> HandlerMapping
DispatcherServlet <---- 처리할 컨트롤러 파악 ---- HandlerMapping

DispatcherServlet ---- 처리요청 ----> Controller 
DispatcherServlet <---- ModelAndView 리턴 ---- Controller
DispatcherServlet ---- ModelAndView 결과를 보여줄 View 파악 ----> ViewResolver
DispatcherServlet <---- View 리턴 ---- ViewResolver
DispatcherServlet ---- 결과물 출력요청 ----> View


개발자는 컨트롤러와 클라이언트의 응답결과화면 보여줄 뷰화면을 만드는게 주이다.
보통은 DispatcherServlet , HandlerMapping, ViewResolver 는 기본 클래스를 쓴다.


하여
ㄱ. DispatcherServlet을 web.xml파일에 설정한다.
ㄴ. 컨트롤러를 작성한다.
ㄷ. ViewResolver를 설정한다. 이는 컨트롤러가 전달한 ModelAndView 값을 이용해서 만듬
ㄹ. 뷰 관련 템플릿(jsp etc...) 로 화면을 만든다.


아니면 개발 과정으로 설명하자면

ㄱ. 클라이언트의 요청을 받을 DispaatcherServlet 을 web.xml에 선언한다.
ㄴ. 클라이언트의 요청을 처리할 컨트롤러 클래스를 만든다.
ㄷ. 컨트롤러가 만든 ModelAndView 데이터를 이용해서 View를 처리할 ViewResolver를 설정한다. ( xml)
ㄹ. Velocity 나 JSP로 뷰를 작성한다.



2. DispatcherServlet 설정
web.xml을 설정하는 과정이다.
/WEB-INF/web.xml
 서블릿과 서블릿 맵핑 정보를 추가하면됨

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
// *.do로 들어오는 클라이언트요청을  dispatcher에서 처리함
<url-pattern>*.do</url-pattern>
<url-pattern>/game/*</url-pattern>
</servlet-mapping>
 
DispatcherServlet은 WEB-INF/ 디렉토리에 위치한 [서블릿이름]-servlet.xml 파일을 스프링 설정파일로 사용한다.

위의 경우 dispatcher 이므로 dispatcher-servlet.xml 파일을 설정파일로 사용한다.
해당 설정파일에는 Controller,ViewResolver,View 등의 빈을 설정한다.


3. Controller 구현
컨트롤러를 구현하려면 @Controller 어노테이션 을 해당 클래스에 적용한다.
@RequestMapping 어노테이션을 이용하면, 클라이언틔 요청을 처리할 메소드를 지정할 수 있다.

@Controller
public class HelloController {

@RequestMapping("/hello.do")
public ModelAndView hello() {
              ModelAndView mav = new ModelAndView();
mav.setViewName("hello");    // 뷰 이름이 hello (.jsp)
mav.addObject("greeting", getGreeting());
return mav;
        }
        ....
}



스프링 MVC는 ModelAndView 말고도 String,Map 등과 같은 타입을 이용해서 뷰이름과,정보를 보낼 수 있다.

당연히 해당 컨트롤러를 DispatcherServlet에서 찾을 수 있도록 스프링 컨테이너의 빈 으로 등록해주어야한다. 

스프링 2.5에서는 컨트롤러 어노테이션에 대해서 추가 작업이 필요하나 3.0에서는 변경되었다.

위의 맵핑에서 정의한 컨트롤러의 메소드에서 ModelAndView 로 결과를 리턴하는데 이 결과와 매칭되는 뷰 구현체를 찾기위해
ViewResolver를 사용한다.  스프링은 여러 벨로시티등의 여러가지 뷰 구현체를 지원하는데 jsp 를 사용할경우 
org.springframework.web.servlet.view.InternalResourceViewResolver 구현체를 빈으로 등록해주면된다.

in [서블릿이름]-servlet.xml 파일안에 
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
// ViewResolver 가 /WEB-INF/view/뷰이름.jsp 를 뷰 JSP로 사용.  위의 컨트롤러에서 view 이름을 hello로 잡았으므로 실제 리턴하는 파일은 
// /WEB-INF/view/hello.jsp 파일이다.  즉 [prefix]뷰이름[suffix] 가 된다.
</bean> 
  

이제 호출하면된다. 
http://localhost:8080/hello.html



자.. 그럼 다시 살펴보면 우선 web.xml에 DispatcherServlet 과 Mapping 설정을 해두었다.
사용자가 특정 url 요청을 하게 되면 Mapping 해두었던 설정에 따라 어떤 dispatcherServlet을 쓸지 확인하고 해당 dispatcherSerlvet 의 설정파일 [dispatcherServlet]-servlet.xml 파일을 읽어서 요청에 맞는 url 패턴을 가진 컨트롤러를 등록된 빈 에서 찾는다.

찾았으면 해당 컨트롤러에 가서 정의된 @RequestMapping 어노테이션중 맞는것을 찾아서 ModelAndView 를 만들고, 리턴한다.

그러면 이를 처리할 ViewResolver 를 찾아야 하는데 그건 [dispatcherServlet이름]-serlvet.xml 파일에 정의된 viewResolver 를 사용해서 

prefix/suffix를 이용한 url을 만든다. 사용자의 눈에는 그 url 이 보이진 않는다. viewResolver가 view를 찾아서 그걸 보여주기만 할뿐 주소의 변경은 없다.

해서 요청 url 패턴이 html 이었다면 .html로 요청한 주소는 그대로이고, viewResolver 에서 만든 주소(by prefix,suffix) 의 대상이 실제 보이게 된다.


'IT > 스프링' 카테고리의 다른 글

filter....  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09
weaving??  (0) 2012.01.09
Pointcut 표현식... execution , within  (0) 2012.01.06
최범균님의 스프링과 인터넷검색을 기반으로 제가 볼 용도의 글을 쓰는것입니다.

흐음.. 기본적으로 스프링AOP는 스프링의 빈 객체에 대해서만 적용된다.
즉 스프링을 이용하지 않는 객체에 AOP를 적용하고 싶다면...?

스프링의 xml 설정을 바꾸어서 AspectJ를 적용할 수 있다.

AspectJ 를 이용해서 그냥 new 등을 통해 생성된 객체에도 AOP 기능을 쓸 수 있다는 의미이다!!

예제 결과를 보기 전 까지는 이게 뭐지였음; 근데 실행문을 보고 나서야 의미를 알았음;
아마 AspectJ를 몰라서 그런거였겠지;?


객체와 Advice 를 weaving 할 설정은
<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE aspectj PUBLIC 
"-//AspectJ//DTD//EN"
"http://www.eclipse.org/aspectj/dtd/aspectj.dtd">

<aspectj>
// Aspect 의 설정 및 적용할 범위를 정의함 
<weaver>
<include within="madvirus.spring.chap05.board.service.*" />
<include within="madvirus.spring.chap05.board.Article" />
</weaver>
// 어떤 Aspect를 적용할지 정의함
<aspects>
<aspect name="madvirus.spring.chap05.aop.annot.ProfilingAspect"/>
</aspects>
</aspectj>

이렇게 어떤 패키지에 어떤 Aspect를 적용할지 설정 한다.  

 그 다음 스프링 설정 xml 에 <context:load-time-weaver /> 를 추가함

==============================================

AspectJ를 이용한 객체의 DI 처리..
 
스프링 컨테이너를 통해서 생성되는 빈객체는 의존관계처리가 가능하고, 결과 의존성도 줄이고 결합도도 낮출 수 있다.
허나 역시,  스프링 컨테이너를 통하지 않은 생성에서는 제어할 수 없다.

 이를 스프링의 AspectJ 지원기능을 이용하면 스프링 컨테이너밖에서 생성되는 객체에 대해서도 DI를 적용할 수 있게 된다.

해당 클래스에 
 @Configurable 어노테이션을 적용한다.
역시 설정에 weaving을 해야하고,  


'IT > 스프링' 카테고리의 다른 글

DispatcherServlet... more  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10
weaving??  (0) 2012.01.09
Pointcut 표현식... execution , within  (0) 2012.01.06
JointPoint ..?  (0) 2012.01.06

http://dev.anyframejava.org/anyframe/doc/core/3.2.0/corefw/guide/aop-components.html



Weaving 또는 CrossCutting

AOP가 Core Concerns 모듈의 코드를 직접 건드리지 않고 필요한 기능이 작동하도록 하는 데는 Weaving 또는 CrossCutting이라고 불리는 특수한 작업이 필요하다. Core Concerns 모듈이 자신이 필요한 Crosscutting Concerns 모듈을 찾아 사용하는 대신에 AOP에서는 Weaving 작업을 통해 Core Concerns 모듈의 사이 사이에 필요한 Crosscutting Concerns 코드가 동작하도록 엮어지게 만든다. 이를 통해 AOP는 기존의 OOP로 작성된 코드들을 수정하지 않고도 필요한 Crosscutting Concerns 기능을 효과적으로 적용해 낼 수 있다.

Weaving은 기존의 자바 언어와 컴파일러에서는 쉽게 구현할 수 있는 방법이 아니었으며 본격적인 AOP 기술이 등장한 것은 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에 의해 AspectJ가 개발되면서라고 볼 수 있다. 
Weaving을 처리하는 방법은 다음과 같이 3가지가 존재한다.
Weaving 방식
설명
Compiletime Weaving별도 컴파일러를 통해 Core Concerns 모듈의 사이 사이에 Aspect 형태로 만들어진 Crosscutting Concerns 코드들이 삽입되어 Aspect가 적용된 최종 바이너리가 만들어지는 방식이다. (ex. AspectJ, ...)
Loadingtime Weaving별도의 Agent를 이용하여 JVM이 클래스를 로딩할 때 해당 클래스의 바이너리 정보를 변경한다. 즉, Agent가 Crosscutting Concerns 코드가 삽입된 바이너리 코드를 제공함으로써 AOP를 지원하게 된다. (ex. AspectWerkz, ...)
Runtime Weaving소스 코드나 바이너리 파일의 변경없이 Proxy를 이용하여 AOP를 지원하는 방식이다. Proxy를 통해 Core Concerns를 구현한 객체에 접근하게 되는데, Proxy는 Core Concerns 실행 전후에 Cross Concerns를 실행한다. 따라서 Proxy 기반의 Runtime Weaving의 경우 메소드 호출시에만 AOP를 적용할 수 있다는 제한점이 있다. (ex. Spring AOP, ...)


'IT > 스프링' 카테고리의 다른 글

Spring 3.0 MVC 정리  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09
Pointcut 표현식... execution , within  (0) 2012.01.06
JointPoint ..?  (0) 2012.01.06
Advice..?  (0) 2012.01.06

+ Recent posts