해당 글은 intelliJ 에서 스프링 MVC 를 해보고자 하는 저같은 초보!! 들에게 필요한 내용을 위주로 담고 있습니다.
고로 좀더 나이스한 설정법과 기타 미려한 내용들은 다 빠지고 ...

그야 말로 우선 가장 작은 단위를 만들어서 돌려보는것이 의의를 가지고 있습니다.

이렇게 한번 돌린것을 기반으로 변경해나가시면 훌륭한 프레임웍을 구성하실 수 있을거라 믿습니다.

참고


-------------------------------------------------------------------------------

1. File --> new Project --> create project from scratch


2. 프로젝트 이름정하고 아래 모듈이름도 정한다음...

모듈은 Maven Module 로 선택하고 

다음을 누른뒤 화면에서 Create from archetype 를 체크하면 프로토타입이 나온다.

(안나오면 언체크 한뒤 다시 체크하면됨)


org.apache.maven.archetypes:maven-archetype-webapp

위의것을 선택하면 기본 구조가 나온다.




3. pom.xml에 

 <properties>

        <java-version>1.6</java-version>

        <org.springframework-version>3.0.6.RELEASE</org.springframework-version>

        <org.aspectj-version>1.6.9</org.aspectj-version>

        <org.slf4j-version>1.5.10</org.slf4j-version>

    </properties>

추가하고  (일종의 변수이다...변수선언.. 이걸 한다고 해서 해당 버전으로 고정되는게 아니라 저걸 정의하는곳에 이용할뿐이다)

dependencies 아래에

 <dependency>

      <groupId>org.springframework</groupId>

      <artifactId>spring-webmvc</artifactId>

      <version>${org.springframework-version}</version>

    </dependency>


스프링 소스 홈페이지에 보면 maven 설정을 위한 내용이 있다. http://www.springsource.org/spring-framework#maven   

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>3.1.1.RELEASE</version> 

</dependency> 

추가하고, 오른쪽 메이븐프로젝트 사이드바에서 reimport를 하든지 이벤트로그에서 

Maven projects need to be imported: Import Changes Enable Auto-Import 에서 Import Changes를 선택하면된다.




4. web.xml

우선 web-app 태그에 값으로

version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

를 넣는다.

<web-app

  version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">


 web-app 안에 서블릿 설정 추가


    <servlet>

        <servlet-name>example</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <load-on-startup>1</load-on-startup>

    </servlet>


    <servlet-mapping>

        <servlet-name>example</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>


 


5. src->main 아래에 디렉토리 java 생성하고 F4를 눌러서 프로젝트 구조를 띄운다음

오른쪽에서 좀전에 만든 java를 선택하고 마우스오른쪽 -->make directory as --> Source를 선택하여 소스디렉토리로 사용


6. 해당 소스디렉토리 이후레 패키지 생성 ex. com.sib.test


그리고 클래스를 하나 만들자

package com.sib.test;


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;


/**

 * Created by IntelliJ IDEA.

 * User: nexGen

 * Date: 12. 3. 27

 * Time: 오후 2:29

 * To change this template use File | Settings | File Templates.

 */


@Controller

public class HelloWorldController {


    @RequestMapping("/helloWorld")

    public ModelAndView helloWorld() {

        ModelAndView mav = new ModelAndView();

        mav.setViewName("helloWorld");

        mav.addObject("message","Hello World");

        return mav;

    }

}



그리고 view 를 만들어두자.위에서 ViewName을 helloWorld로 했으니..

WEB-INF 밑에 views 디렉토리를 만들고 helloWorld.jsp를 추가

hello<br/>


${message}~~~



간단하게 만들었다.



7. 이제 web.xml에 스프링관련 설정.xml 을 추가하자.

서블릿이름-servlet.xml 을 하든지 아래처럼 명시적으로

<servlet> 안에 

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>

</init-param>


관리하기 쉽도록 명시적으로 처리하자.

해당 디렉토리를 만들고 파일도 만들면 web.xml에 있는 에러내용이 없어질것이다.

해서 만들어진 결과 

최종 web.xml

<!DOCTYPE web-app PUBLIC

 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

 "http://java.sun.com/dtd/web-app_2_3.dtd" >


<web-app

  version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>Archetype Created Web Application</display-name>


    <servlet>

        <servlet-name>example</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>


    <servlet-mapping>

        <servlet-name>example</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>


</web-app>






빈의 오토스캔을 위해 servlet-context.xml에

<context:component-scan base-package="com.sib.test"/>

를 넣어야 하는데... context 태그를 쓰기위해서는 beans 선언에 추가할것이 있다.


xmlns:context="http://www.springframework.org/schema/context"

를 하면 context 태그를 쓸 수 있다. 우선 아래를 참고해라


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" 

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:p="http://www.springframework.org/schema/p" 

    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">


    <context:component-scan base-package="org.springframework.samples.petclinic.web"/>


    // ...


</beans>


결과 최종 servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/mvc"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:beans="http://www.springframework.org/schema/beans"

       xmlns:context="http://www.springframework.org/schema/context"


       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-3.0.xsd

       http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd">


       <context:component-scan base-package="com.sib.test"/>


    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <beans:property name="prefix" value="/WEB-INF/views/" />

        <beans:property name="suffix" value=".jsp" />

    </beans:bean>


</beans:beans>


 



tomcat에 소스를 deploy  해야한다.


그전에 maven 에서 소스를 package 해야한다. (war 생성)

compile 하고 package 해야하는지는.. 잘 모르겠고;


8. 우선 톰켓이 없으면 설정한다. 프로젝트 최상위에 마우스 선택후 Add Framework Support

--> application server --> tomcat


다음 상단에 play 바 왼쪽에 셀렉트 박스에서 톰켓을 선택하고 다시 선택하여 Edit Configurations 선택

--> deployement 탭을 선택하여 + 표시.. 선택 --> Artifact --> 나오는 war 선택


이제 서버기동!



3월 27, 2012 3:24:55 오후 org.springframework.web.servlet.FrameworkServlet initServletBean

정보: FrameworkServlet 'example': initialization started

3월 27, 2012 3:24:55 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh

정보: Refreshing WebApplicationContext for namespace 'example-servlet': startup date [Tue Mar 27 15:24:55 KST 2012]; root of context hierarchy

3월 27, 2012 3:24:55 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

정보: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]

3월 27, 2012 3:24:56 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons

정보: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@60bd76d7: defining beans [helloWorldController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.web.servlet.view.InternalResourceViewResolver#0]; root of factory hierarchy

3월 27, 2012 3:24:56 오후 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler

정보: Mapped URL path [/helloWorld] onto handler 'helloWorldController'

3월 27, 2012 3:24:56 오후 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler

정보: Mapped URL path [/helloWorld.*] onto handler 'helloWorldController'

3월 27, 2012 3:24:56 오후 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler

정보: Mapped URL path [/helloWorld/] onto handler 'helloWorldController'


servlet 'example'을 기동했고 mapping 정보를 읽어왔다.




http://localhost:8080/helloWorld


해보자. 나온다~





@Autowired wires per type and
@Resource wires per bean name

from http://forum.springsource.org/showthread.php?48563-Autowired-and-Resource-difference 





흐음.. 뭐 중요하다면 중요한데.. .우선 .. 적당히 하고 넘어가고 필요할때 보자

알다시피 DispatcherServlet 이 HandlerMapping을 통해서 어떤 컨트롤러를 쓸지 알아내고
그 컨트롤러가 ModelAndView(물론 다른게 될 수 도 있고) 를 돌려주면 어떤 뷰를 써야하는지 알려주는 대상이 있다.

바로 ViewResolver 인데, 스프링이 제공하는 ViewResolver에 대해서 살펴보고 뷰구현기술에 대해서도.... 책봐라 -ㅅ-

ViewResolver는 응답 결과를 생성할 뷰 객체를 리턴한다.
모든 View 클래스는 View 인터페이스를 구현한다.




1. InternalResourceViewResolver
jsp, html 파일과 같이 웹 어플리케이션의 내부자원을 이용하여 부를 생성하는 경우?
AbstractUrlBasedView타입의 객체이고, 기본적으로 View 클래스는 InternalResourceView 클래스임

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/viewjsp/" />
<property name="suffix" value=".jsp" />
</bean>


2. BeanNameViewResolver 설정
뷰 이름과 동일한 이름을 갖는 빈을 뷰 객체로 사용하는경우.

public ModelAndView download() throws Exception {
File downloadFile = getFile();
return new ModelAndView("download", "downloadFile", downloadFile);  // download 빈 으로 처리하도록 설정
}
        
        // 빈 등록하고
<bean id="viewResolver"
class="org.springframework.web.servlet.view.BeanNameViewResolver" />

        // download 빈 등록
<bean id="download" class="madvirus.spring.chap07.view.DownloadView" />

3. XmlViewResolver
뷰 이름과 동일한 이름을 갖는 빈을 뷰 객체로 사용.
2번과 큰 차이는 없는데, 차이가 있다면 별도의 xml 설정 파일로 부터 빈 객체를 검색한다는것임

  <bean id="viewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver"
                p:location="/WEB-INF/nonHtml-view.xml"/>


 4. ResourceBundleViewResolver 
리소스 번들(프로퍼티파일)로 부터 View 이름과 매핑 View 클래스를 구한다. 
책봐라..

그리고 DI,AOP 기능이 필요하다면 BeanNameViewResolver 나 XmlViewResolver 클래스를 사용한다.

 

다수의ViewResolver 설정하기
하나의 DispatcherServlet은 한 개 이상의 ViewResolver를 설정할 수 있도록 하고 있다.
order 를 두고 우선순위를 정할 수 있지. 순서대로 찾아가는 꼴이라고 보면 된다.

주의할 점은 InternalResourceViewResolver는 마지막 순위가 되도록 해야하는데, 왜냐면 해당 Resolver는 무조건 뷰 이름에 매핑되는 뷰 객체를 리턴하기 때문이다. (null을 리턴하지 않음)
Velocity도 마창가지로 주의해야하는데, VelocityViewResolver / VelocityLayoutViewResolver 는 뷰 이름에 매핑되는 Velocity 템플릿 파일이 존재하지 않을경우 예외를 발생시켜버린다.



스프링 커스텀 태그...
1. 메시지 

<spring:message> 커스텀태그를 이용해서 MessageSource 로 부터 메시지를 가져와 출력할 수 있다. (즉... 프로퍼티 같이 설정되어있는 값을 가져와 대치하는거지)

2. 폼관련
뭐.. 이제는 당연한거지만, 입력 폼(form)안의 데이터를 커맨드객체에 저장해서 넘겨받아 처리하는 형태이다. 
또한 반대로 커맨드 객체으 기밧을 입력폼에 출력해주는 기능도 있다. 
스프링은 많은 커스텀태그를 제공하고 있다.

<form:form commandName="login">
<form:errors />
<p>
<label for="loginType"><spring:message code="login.form.type" /></label>
<form:select path="loginType" items="${loginTypes}" />
</p>
<p>
<label for="id"><spring:message code="login.form.id" /></label>
<form:input id="id" path="id"/>
<form:errors path="id" />
</p>
<p>
<label for="password"><spring:message code="login.form.password" /></label>
<form:password id="password" path="password"/>
<form:errors path="password" />
</p>
<p>
<input type="submit" value="<spring:message code="login.form.submit" />">
</p>
</form:form>

흐음...  

<form:input>
<form:password>
<form:hidden>
위의 셋은  path 속성에 바인딩 될 커맨드객체의 프로퍼티를 지정함. 즉 이 값이 input 의 name 과 id 값이 된다.

<form:select>
: option 태그를 생성하는데 필요한 콜렉션을 전달받을 수 있음
<form:options>
:지정한 콜렉션 객체를 이용해서 option 태그를 생성할 수 있음
<form:option>
: 한개의 option...

컨틀롤러에서 생성해 뷰에 넘겨줄때 @ModelAttribute 어노테이션을 이용해서 넘겨준다.

@ModelAttribute("loginTypes")
protected List<String> referenceData() throws Exception {
List<String> loginTypes = new ArrayList<String>();
loginTypes.add("일반회원");
loginTypes.add("기업회원");
loginTypes.add("헤드헌터회원");
return loginTypes;
}
위처럼하고..
위의 html 을 보면

<p>
...
<form:select path="loginType" items="${loginTypes}" />
</p>

부분처럼 쓰인다.

그러면 생성되는 내용은
<select id='loginType' name='loginType'>
    <option value='일반기업'>일반회원</option>
    <option value='기업회원'>기업회원</option>
    <option value='헤드헌터회원'>헤드헌터회원</option>
</select>

 위의 방법 말고 <form:options> 도 있다.

<form:select path='loginType'>
    <option value="">---------- select --------------</option>
    <form:options items="${loginType}"/>
    <form:option value="TEST"/>
    <form:option value="TEST2">TEST2</form:option>
</form:select>
 

<form:checkboxes>
<form:checkbox> 

위의 둘도 select와 별 반 다를게 없다.

Map<String, String> favoritesOsNames = new LinkedHashMap<String, String>();
favoritesOsNames.put("윈도우XP", "윈도우XP");
favoritesOsNames.put("비스타", "비스타");
favoritesOsNames.put("윈도우7", "윈도우7");
favoritesOsNames.put("우분투", "우분투");
favoritesOsNames.put("맥", "맥");

                model.addAttribute("favoritesOsNames", favoritesOsNames); // 넣고...

jsp 에서 
 
<form:checkboxes items="${favoritesOsNames}" path="favorites" />
위와같이 하면

<input id='favorites1' name='favorites' value='윈도우XP'/><label for='favorites1'>윈도우XP</label>
<input id='favorites2' name='favorites' value='비스타'/><label for='favorites2'>비스타</label>

그 외 내용은 책에서;;


<form:radiobuttons>
<form:radiobutton>
: 흐음.. 역시나 select 나 checkbox와 비슷한다. 


Map<String, String> tools = new LinkedHashMap<String, String>();
tools.put("Eclipse", "Eclipse");
tools.put("IntelliJ", "IntelliJ");
tools.put("NetBeans", "NetBeans");

                model.addAttribute("tools", tools); 
이렇게 해두고...

 
<form:radiobuttons items="${tools}" path="tool" />
-->

<input id='tool1' name='tool' type='radio' value='Eclipse'/><label for='tool1'>Eclipse</label>
<input id='tool2' name='tool' type='radio' value='intelliJ'/><label for='tool2'>intelliJ</label>


<form:textarea>
뭐.. 별다를게 있겠느냐 아래를 봐라
<form:textarea path="etc" cols="20" rows="3"/>
-->
html로.. 변환하면
<textarea id="etc" name="etc" cols="20" rows="3"></textarea>


스프링이 제공하는 에러관련 커스텀 태그


뭐... Validator 를 이용해서 각종 에러 설정한것을 jsp에서 쓸 수 있는데..
Errors 나 BindingResult를 이용해서 에러 정보를 추가한 경우 <form:errors> 를 통해서 에러 메시지를 출력할 수 있다.

<p>
<form:label path="userId">회원 ID</form:label>
<form:input path="userId" />
<form:errors path="userId" />
</p>

이런경우... 실제 화면에서 아이디를 안넣고 submit을 한다든지 하면 form:errors 에서 에러메시지르 화면에 보여주게 된다.
(예로 필수항목입니다.. 등의 메시지가 옆에 표시됨)

그런용도로 쓸 수 있지...



 












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

Bean .. 빈 객체 스캔하여 빈 등록  (0) 2012.02.29
스프링이 객체를 생성하는 형태?  (0) 2012.02.22
@RequestBody , @ResponseBody  (0) 2012.01.20
WebApplicationContext 직접접근?  (0) 2012.01.19
캐시옵션 설정  (0) 2012.01.19

흐음... 요즘은.. 서비스가 하나의 형태로 나타나지 않는다. 똑같은 데이터를 가지고 이런서비스 저런 서비스에서 똑같이 사용할 수 있단 말이지.
방법이야 게이트단에서 각 단에 맞게 보내주면되긴하다. 

스프링에서도 제공하는기술이 데이터 를 XML이나 JSON 형태로 주고 받을 수 있다. 그거지. 많은 추가 작업없이 가능하다.
예로 .htm 으로 호출하면 html이 오고 .json 으로 호출하면 그 결과가 json으로 오면된다. 주로 키맵의 리턴이 되는 형태 (여러 서비스들간의 통신에서?)
로 주고 받을 수 있다는거다.

@RequestBody 와 @ResponseBody 어노테이션은 각각 HTTP 요청 몸체를 자바 객체로 변환하고 자바 객체를 HTTP 응답 몸체로 변환해주는데 사용된다. 

@RequestBody 어노테이션을 이용하면 HTTP 요청 몸체를 자바 객체로 전달받을 수 있다.
@ResponseBody 어노테이션을 이용하면 자바 객체를 HTTP 응답 몸체로 전송할 수 있다. 

@RequestMapping( method = RequestMethod.POST)
@ResponseBody
public String simpleTest(@RequestBody String body) {
return body;
}

@RequestBody 어노테이션은 @RequestMapping에 의해 POST 방식으로 전송된 HTTP 요청 데이터를 String 타입의 body 파라미터로 전달한다.
@ResponseBody 어노테이션은 @RequestMapping 메서드에 적용되면 해당 메소드의 리턴값을 HTTP 응답데이터로 사용한다.

위의 경우 리턴값이 String 이므로 String 데이터를 HTTP 응답 데이터로 전송한다.

응답데이터.. 결과는 아래처럼 간다...
만약 폼에 값들이 들어있었다면

name=John&age=22

위의 경우 요청 몸체 데이터를 body 파라미터에 전달받고 있으며, body 파라미터를 그대로 결과값으로 리턴한다.
그런데 @ResponseBody 어노테이션이 적용되어 있어서 .. HTTP 요청데이터가 그대로 응답데이터로 간다.

해서 html... 웹브라우저 뷰에 

name=John&age=22

나올것이다.

이런것을.. 스프링MVC는 HttpMessageConverter를 이용해서 자바객체와 HTTP 요청/응답 몸체 사이의 변환을 처리한다.



HttpMessageConverter를 이용한 처리

AnnotationMethodHandlerAdapter 클래스는 @RequestBody 어노테이션이 적용된 파라미터나 @ResponseBody 어노테이션이 적용된 메소드에 대해 HttpMessageConverter 를 사용해서 변환처리한다. (정확히는 HttpMessageConveter의 구현클래스를 사용)

이 HttpMessageConverter를 구현한 몇가지 클래스들이 있다.
ByteArrayHttpMessageConveter 등.. 찾아봐라

만약 다른 messageConverter를 사용하겠다면 명시적 정의 가가능하다. (아래처럼...)
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="cacheSeconds" value="0" />
<property name="alwaysUseFullPath" value="true" />
<property name="webBindingInitializer">
<bean class="madvirus.spring.chap06.binder.CustomWebBindingInitializer" />
</property>
<property name="messageConverters">
<list>
<ref bean="byteArrayHttpMessageConverter" />
<ref bean="stringHttpMessageConverter" />
<ref bean="formHttpMessageConverter" />
<ref bean="sourceHttpMessageConverter" />
<ref bean="marshallingHttpMessageConverter" />
<ref bean="jsonHttpMessageConverter" />
</list>
</property>
</bean>
























 



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

스프링이 객체를 생성하는 형태?  (0) 2012.02.22
뷰 영역???  (0) 2012.01.26
WebApplicationContext 직접접근?  (0) 2012.01.19
캐시옵션 설정  (0) 2012.01.19
HandlerInterceptor  (0) 2012.01.19


DispatcherServlet은 DefaultAnnotationHandlerMapping 클래스를 기본 HandlerMapping 구현체로 사용한다.

 @RequestMapping 의 주의사항..

@RequestMapping("/search/game.do")
public String search(...) {
...


@RequestMapping("/game/info")
public String info(...) {
...


코드를 보면 /search/game.do 는 search에서 처리하고, /game/info 는 info에서 처리할듯 하지만...
첫번째것은 맞고 두번째는 틀렸다.

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/game/*</url-pattern>
</servlet-mapping>

url-pattern 에서 /game/* 로 설정했기 때문이라네?
url-pattern값으로 디렉토리를 포함한 패턴을 지정하게 되면 서블릿 경로는 /game 이 되며, 
서블릿 경로를 제외한 나머지 경로를 이용해서 @RequestMapping 어노테이션의 값과 매칭여부를 판단한단다.

해서 game/info 의 요청이 오면 실제 요청 URI 는 /info가 된다. 
허나 RequestMapping 에는 /game/info라고 했으므로 /info와 맞지 않게 된다.


이런 이유는 DispatcherServlet 이 기본적으로 사용하는 HandlerMapping 구현체와 HandlerAdapter 구현체가 전체 경로를 사용하지 않도록 설정되어있기 때문이란다.

해서 사용하게 설정하면... 위의 경우 잘 되겠지?
즉, 서블릿 경로를 포함한 전체 경로를 이용해서 매칭 여부를 판단하도록 설정하려면, 
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:alaywaUseFullPath="true"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerAdapter" p:alwaysUseFullPath ="true"/>
 


 










 



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

Ant 경로 패턴 in @RequestMapping  (0) 2012.01.16
PathVariable 어노테이션을 이용한 URI 템플릿...  (0) 2012.01.16
@ModelAttribute  (2) 2012.01.13
모델 생성.... (Model )  (0) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10


@ModelAttribute 를 이용하면 2가지 작업이 가능

ㄱ. @RequestMapping 어노테이션이 적용되지 않은 별도 메소드로 모델에 추가될 객체를 생성가능
ㄴ. 커맨드 객체의 초기화 작업을 수행

두개의 RequestMapping 된 메소드가 같은 내용의 모델을 필요로 한다고 할때, 보통 그냥 별도의 메소드로 빼서 그것을 참조하게
한다. 

단 이렇게 하면 공통 메소드에 추가 조건절이 들어갈 수 도 있고 리턴에 대해서도 사용하는 측에서 맞춰야한다.

이때 @ModelAttribute를 사용할 수 있다.

 @ModelAttribute 를 메소드에 적용하면 해당 메소드가 생성한 객체가 뷰에 전달된다!!!!


아하.. 그래서 return 에 없는 객체들을 jsp 에서 참조가능했구나!!!!!!

즉 이 어노테이션은 ModelAttribute , 모델속성!! 이라는 의미의 단어를 그대로 뜻하는 것이다!!! 


@Controller
public class GameSearchController {
@Autowired
private SearchService searchService;

@ModelAttribute("searchTypeList")
public List<SearchType> referenceSearchTypeList() {
List<SearchType> options = new ArrayList<SearchType>();
options.add(new SearchType(1, "전체"));
options.add(new SearchType(2, "아이템"));
options.add(new SearchType(3, "캐릭터"));
return options;
}

@ModelAttribute("popularQueryList")
public String[] getPopularQueryList() {
return new String[] { "게임", "창천2", "위메이드" };
}

@RequestMapping("/search/main.do")
public String main() {
return "search/main";
}

@RequestMapping("/search/game.do")
public ModelAndView search(@ModelAttribute("command") SearchCommand command) {
ModelAndView mav = new ModelAndView("search/game");
System.out.println("검색어 = " + command.getQuery().toUpperCase());
SearchResult result = searchService.search(command);
mav.addObject("searchResult", result);
return mav;
}


해서 위의 콘트롤러를 보면 리턴해줄 모델의 값은 단지 mav일뿐이다. 허나 @ModelAttribute 어노테이션을 다른 메소드에 붙이므로써
모델에 속성을 추가하게 되는것이다!



다른 용도는 커맨드 객체 초기화 부분이다.
@ModelAttribute 어노테이션을 사용하면, 커맨드 객체의 초기화 작업을 수행할 수도 있다.
그럴수 밖에... 
@Controller
@RequestMapping("/account/create.do")
public class CreateAccountController {

@ModelAttribute("command")
public MemberInfo formBacking(HttpServletRequest request) {
if (request.getMethod().equalsIgnoreCase("GET")) {
MemberInfo mi = new MemberInfo();
Address address = new Address();
address.setZipcode(autoDetectZipcode(request.getRemoteAddr()));
mi.setAddress(address);
return mi;
} else {
return new MemberInfo();
}
}

private String autoDetectZipcode(String remoteAddr) {
return "000000";
}

@RequestMapping(method = RequestMethod.GET)
public String form() {
return "account/creationForm";
}

@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") MemberInfo memberInfo,
BindingResult result) {
new MemberInfoValidator().validate(memberInfo, result);
if (result.hasErrors()) {
return "account/creationForm";
}
return "account/created";
}
}

GET/POST 각각의 요청에 따라 객체 초기화가 가능하다.
위에서보면 submit 시의 command 가 바로 @ModelAttribute("command") 의 객체를 가르키게 된다.
왜냐면 @ModelAttribute 어노테이션이 적용된 메소드가 @RequestMapping 어노테이션이 적용된 메소드보다 먼저 호출되므로,
초기화 작업처럼 되는것이다.

그리고 ModelAttribute 어노테이션이 적용된 메소드는 RequestMapping 어노테이션이 적용된 메소드와 동일한 타입의 파라미터를 가질 수 있다.
 @ModelAttribute("command")
public MemberInfo formBacking(HttpServletRequest request) {

HttpServletRequest 말고도 Locale, @RequestParam 어노테이션 적용, @PathVariable 어노테이션등을 적용가능하다. 
 



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

PathVariable 어노테이션을 이용한 URI 템플릿...  (0) 2012.01.16
URI 매칭.. (서블릿 맵핑)  (0) 2012.01.13
모델 생성.... (Model )  (0) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10
filter....  (0) 2012.01.10


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

+ Recent posts