Spring MVC [Controller, servlet-context, eclipse]
반응형

본 게시글은 Seoul wiz의 신입SW인력을 위한 실전 자바(Java) 스프링(Spring)을 참고하여 작성한 글입니다.

 

웹 애플리케이션 제작에 사용되는 스프링 MVC는 다음과 같다.

Client에서 요청 -> DispatcherServlet에서 최초로 요청을 받는다.

이제 이 DispatcherServlet에서 요청을 Controller로 보내고,

(중간에 HandlerMapping, HandlerAdapter도 들린다.)

Controller에서는 처리하여 다시 DispatcherServlet으로 응답한다.

그럼 이제 다시 이 DispatcherServlet에서 ViewResolver에 보내여 사용자에게 View가 보이게 된다.

MVC에서 (Model, View, Controller) Model은 이 DispatcherServlet이라 보면 된다.

 

MVC 구조 시작하기

여기서부터는 가장 연동이 간편하고, 익숙한 Eclipse로 갈아타서 사용하기로 했다.

Eclipse에서 Help -> Eclipse MarketPlace를 들어간다.

들어가면 Search에서 STS를 검색하는데 이때 유의해야 할 점이 있다.

가장 최신버전인 STS4에서는 Legacy Project를 지원하지 않는다.

Spring MVC 프로젝트는 Spring Legacy Project를 통해 만드는것이 주로 인터넷에 나온 방법이다.

이를 위해서는 위의 Spring Tools3 Add-On for Spring Tools 4 플러그인을 추가로 설치해야 한다.

둘다 시키는데로 설치하고 나면 MVC 프로젝트를 생성해보자.

 

File -> New -> Other -> Spring -> Spring Legacy Project

Spring MVC Project -> 프로젝트 이름설정 -> 패키지설정까지 해주면 프로젝트가 생성된다.

 

log4j.xml 에러

혹시 log4j.xml 파일에서 Cannot find DTD 'file:///'과 같은 에러가 발생할 수 있다.

이는 DTD 파일이 없어서 생기는 문제로, 웹 경로로 지정하면 수정할 수 있다.

DOCTYPE 선언부분을 아래와 같이 수정해주자.

<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">

 

폴더 구조

 

  • web.xml : DispatcherServlet 매핑. 스프링 설정 파일 (servelt-context.xml) 위치 정의
<servlet>
    <servlet-name>appServlet</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>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

url-pattern이 "/" 인 것은 -> appServlet 즉 org.springframework.web.servlet.DispatcherServlet으로 가는데,

DispatcherServlet은 servlet-context의 Controller로 보낸다.

 

  • servlet-context.xmll : bean 관련 설정.
<context:component-scan base-package="com.birdmissile.example" />

이때 servlet-context에서는 com.birdmissile.example (패키지) 내를 스캔하여 해당하는 Controller를 찾는다.

 

  • HomeController.java
@Controller
public class HomeController {
    //....
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        //....
        return "home";
    }
}

그럼 @Controller 어노테이션이 붙어 있는 해당 패키지 내의 Java 클래스가 Controller가 된다.

이제 @RequestMapping에 따라 value가 "/"인 이 home 메소드가 실행되게 되고,

또한, return home을 통해 View중 home이 실행되게 된다.

 

다시 servlet-context.xml로 돌아와

<context:component-scan base-package="com.birdmissile.example" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <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>

여기서 prefix부분에 /WEB-INF/views로 되어있기 때문에 View 파일을 여기서 찾고,

suffix에 .jsp이기 때문에 이 안에 jsp파일을 View로 알아서 찾게 된다.

따라서 /WEB-INF/views의 + "home" +.jsp가 실행된 것이다.

한마디로 뷰의 이름만 정해주면 Dispatcher를 통해 Controller에서 View로 연결이 된다.

 

프로젝트를 실행해보면, localhost:8080/example/ 의 주소로 jsp파일이 실행됨을 확인할 수 있다. (그냥 실행하면 404)

이때의 주소는 Servers 폴더의 server.xml을 확인하면 자동으로 context 명이 설정됨을 확인할 수 있다.

com.birdmissile.example로 패키지를 만들었다면, 마지막 /example 부분이 context명이 되는 것이다.

<Context docBase="Sample" path="/example" reloadable="true" source="org.eclipse.jst.jee.server:Sample"/>

 

파일 추가하기

이미지, JS, CSS 등 여러 추가파일이 필요할 수 있다.

resources 폴더 내에 사진을 저장해보자. (birdmissile5.jpg)

이때 이미지의 주소는 context부터 시작한 "/example/resources/birdmissile5.jpg" 여야 한다.

왜 하필이면 resources 폴더만 가능할까?

servlet-context를 확인해보면 아래와 같은 부분이 존재한다.

<resources mapping="/resources/**" location="/resources/" />

위의 DispatcherServlet이 Controller로 호출하기 전에,

/resources/**로 시작하는 주소들은 가로채지 말고 /resources/ 폴더에서 찾아보라고 하는 의미이다.

따라서 다른 폴더를 사용하고 싶다면, 위와 같이 활용하면 된다.

 

반응형