스프링 MVC


웹어플리케이션 —배포—> Tomcat(WAS)

  1. web.xml(로 설정하는것 찾아보자!) DispatcherServlet (path : /) - 읽어들일 파일도 설정 (xml, java config)
    • 내부적으로 ApplicationContext를 가지고 있다.
    • 위의 ApplicationConxtext는 ContextLoaderLsitener의 ApplicationContext를 부모로 가진다.
    • 부모의 bean부터 찾는다.
    • 웹과 관련됨 ContextLoaderListener : 읽어들일 파일을 설정 ( xml, java config)
    • 내부적으로 ApplicationContext 를 가지고 있다 (스프링 컨테이너)
    • 부모에서 자식 bean을 찾을 순 없다.
    • Service, Repository 등의 비지니스와 관련

web.xml 파일이 없다면!

  1. ServletContainerInitalizer 를 구현하는 클래스를 작성하여 설정.(서블릿 스펙 3.0 이상)

  2. WebApplicationInitializer(스프링이 제공) 를 구현


스프링 MVC

mvc


기존 Spring JDBC 예제에 Spring MVC를 적용.

  1. pom.xml 파일에 다음의 내용 추가
    <packaging>war</packaging>
    .....
        <!-- web 개발 -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

  1. DispatcherServlet, ContextLoaderListener 를 설정한다.
public class MainWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    // 비지니스 로직 관련 스프링 설정
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { ApplicationConfig.class };
    }
    // 웹과 관련된 설정
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    // 사용자가 필터를 설정.
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");

        return new Filter[]{encodingFilter};
    }

}
  1. 비지니스 로직을 설정을 읽어들인다. ApplicationConfig.class Dao, Service 에 대한 설정.

  2. 웹과 관련된 설정을 읽어들인다. WebConfig.class



@EnableWebMvc // Spring WebMVC설정을 위한 애노테이션
@Configuration
@ComponentScan(basePackages = { "my.examples.springjdbc.controller" })
public class WebConfig extends WebMvcConfigurerAdapter { // Web설정은 WebMvcConfigurerAdapter를 상속받아서 구현한다. (Spring 5에서는 사용하면 안된다.)

    // JSP를 위한 ViewResolver빈을 생성한다.
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        // JstlView는 JSP를 실행하는 View(forward)
        bean.setViewClass(JstlView.class);
        
        // 컨트롤러가 view name으로 "list"를 리턴한다면 
        // "/WEB-INF/views/" + "list" + ".jsp"로 포워딩한다.
        bean.setPrefix("/WEB-INF/views/");
        bean.setSuffix(".jsp");

        return bean;
    }

    //   원래 /로 등록되는 서블릿은 DefaultServlet이라고 했었다.
    //   그런데 Spring MVC는 DispatcherServlet이 그것을 사용한다.
    //   브라우저에서 GET /git.png 이런 요청이 왔는데, 이 정보가 
    //   HandlerMapping에 없다. 이 경우 404가 발생하는데,
    //   아래와 같은 설정을 하게 되면 DispatcherServlet이 처리못하는 path를
    //   기존 DefaultServlet에게 넘긴다.
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        super.configureDefaultServletHandling(configurer);
        configurer.enable();
    }


    // Controller를 만들지 않고 헨들러를 설정.
    // http://localhost:8080 로 요청이 오면 /list로 리다이렉트 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/list");
    }
}
  1. 컨트롤러를 작성한다.

@Controller
public class UserController {
    UserService userService;

    public UserController(UserService userService){
        this.userService = userService;
    }

    //  @RequestMapping(method=GET, path="/list") 와 같은 것
    @GetMapping("/list")
    public String main(Model model){
        List<User> users = userService.getUsers();
        model.addAttribute("users", users);
        return "index"; // view name
    }
}
  1. index.jsp 를 작성한다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>test</title>
</head>
<body>
<h1>test</h1>
<img src="/github.gif">
<br><br data-tomark-pass>s

<c:forEach items="${users}" var="user">
    name : ${user.name}, email : ${user.email}<br data-tomark-pass>
</c:forEach>
</body>
</html>
  1. servlet / jsp에서 웹 어플리케이션 실행했던 것처럼 intelliJ에서 설정하고 실행.

  • 스프링 MVC 기본 흐름

웹브라우저→ 디스패쳐서블릿→ 컨트롤러→ 모델앤뷰→ 컨트롤러→ 디스패쳐서블릿→ 웹브라우저

  • 스프링 MVC 어노테이션

    • @controller는 클라이언트로부터 전달되어진 데이터를 가공하기 위한 Controller임을 명시하며 @RequestMapping 을 통해 경로 설정을 하게 된다.
    • @Repository 는 해당 클래스가 데이터베이스에 접근하는 DAOs 클래스임을 명시
    • @Service는 Repository를 통해 데이터베이스에서 데이터를 가져온 후 컨트롤러에게 전달해 주는 비지니스로직이 들어간 서비스 클래스임을 명시한다
    • @Entity Spring data JPA를 사용할 시 데이터베이스에 테이블을 생성하거나 데이터를 가공하기 위한 클래스임을 명시한다
      으로 클래스를 만들면 데이터베이스에 해당 클래스 이름으로 테이블을 만들고, 변수로 필드를 만든다.
      JPA를 통해 @Domain 클래스에서 사용되어지는 다양한 어노테이션이 존재하게 된다. ~~~
@MappedSuperClass

부모클래스임을 지정하며 자식클래스가 테이블로 생성할 때 부모클래스의 변수는 자동적으로 자식클래스의 필드에 생성된다.

@Id

기본키임을 명시.

@CreateDate

@LastModifyDate

@GenerateValue

데이터 자동으로 증가

@Column

@NotNull

타입이 숫자계열일때 not null임을 명시

@NotEmpty

:타입이 숫자계열이 아닌 타입에 대해서 not null임을 명시

@ManyToOne

테이블 매핑시 N:1임을 명시

@ManyToMany

테이블 매핑시 N:N임을 명시

@OneToMany

테이블 매핑시 1:N임을 명시

@JoinTable

다른 테이블과 Join된 변수임을 명시

@JsonIgnore

@Repository를 통해 데이터를 얻을 때 해당 어노테이션이 지정된 변수의 데이터를 가져올 수 없다.

~~~