들어가기 전에
이번 시간엔 Spring MVC를 이용하여 웹 어플리케이션을 작성하는 방법에 대하여 실습을 통해 알아보도록 하겠습니다.
학습 목표
- Spring MVC를 이용해 프로젝트를 구성할 수 있고, 개발자가 작성해야 할 파일이 무엇인지 이해한다.
- Spring MVC를 이용해 웹 어플리케이션을 작성할 수 있다.
핵심 개념
- DispacherServlet
- WebApplicationInitializer
- @RequestMapping = @GetMapping = @PostMapping
학습하기
DispatcherServlet을 FrontController로 설정하기
- web.xml 파일에 설정
- javax.servlet.ServletContainerInitializer 사용
- 서블릿 3.0 스펙 이상에서 web.xml파일을 대신해서 사용할 수 있다. - org.springframework.web.WebApplicationInitializer 인터페이스를 구현해서 사용
web.xml파일에서 DispatcherServlet 설정하기 1/2
WebApplicationInitializer를 구현해서 설정하기 1/2
- Spring MVC는 ServletContainerInitializer를 구현하고 있는 SpringServletContainerInitializer를 제공한다.
- SpringServletContainerInitializer는 WebApplicationInitializer 구현체를 찾아 인스턴스를 만들고 해당 인스턴스의 onStartup 메소드를 호출하여 초기화한다.
WebMvcConfigurationSupport
@ComponentScan
- ComponentScan애노테이션을 이용하면 Controller, Service, Repository, Component애노테이션이 붙은 클래스를 찾아 스프링 컨테이너가 관리하게 된다.
- DefaultAnnotationHandlerMapping과 RequestMappingHandlerMapping구현체는 다른 핸드러 매핑보다 훨씬 더 정교한 작업을 수행한다. 이 두 개의 구현체는 애노테이션을 사용해 매핑 관계를 찾는 매우 강력한 기능을 가지고 있다. 이들 구현체는 스프링 컨테이너 즉 애플리케이션 컨텍스트에 있는 요청 처리 빈에서 RequestMapping애노테이션을 클래스나 메소드에서 찾아 HandlerMapping객체를 생성하게 된다.
- HandlerMapping은 서버로 들어온 요청을 어느 핸들러로 전달할지 결정하는 역할을 수행한다.
- DefaultAnnotationHandlerMapping은 DispatcherServlet이 기본으로 등록하는 기본 핸들러 맵핑 객체이고, RequestMappingHandlerMapping은 더 강력하고 유연하지만 사용하려면 명시적으로 설정해야 한다.
WebMvcConfigurerAdapter
- org.springframework.web.servlet.config.annotation. WebMvcConfigurerAdapter
- @EnableWebMvc 를 이용하면 기본적인 설정이 모두 자동으로 되지만, 기본 설정 이외의 설정이 필요할 경우 해당 클래스를 상속 받은 후, 메소드를 오버라이딩 하여 구현한다.
Controller(Handler) 클래스 작성하기
- @Controller 애노테이션을 클래스 위에 붙인다.
- 맵핑을 위해 @RequestMapping 애노테이션을 클래스나 메소드에서 사용한다.
@RequestMapping
- Http 요청과 이를 다루기 위한 Controller 의 메소드를 연결하는 어노테이션
- Http Method 와 연결하는 방법
- @RequestMapping(value="/users", method=RequestMethod.POST)
- From Spring 4.3 version (@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping) - Http 특정 해더와 연결하는 방법
- @RequestMapping(method = RequestMethod.GET, headers = "content-type=application/json") - Http Parameter 와 연결하는 방법
- @RequestMapping(method = RequestMethod.GET, params = "type=raw") - Content-Type Header 와 연결하는 방법
- @RequestMapping(method = RequestMethod.GET, consumes = "application/json") - Accept Header 와 연결하는 방법
- @RequestMapping(method = RequestMethod.GET, produces = "application/json")
실습 코드
WebMvcContextConfiguration.java
package kr.or.connect.mvcexam.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "kr.or.connect.mvcexam.controller" })
public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/META-INF/resources/webjars/").setCachePeriod(31556926);
registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(31556926);
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
System.out.println("addViewControllers가 호출됩니다. ");
registry.addViewController("/").setViewName("main");
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>Spring JavaConfig Sample</display-name>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>kr.or.connect.mvcexam.config.WebMvcContextConfiguration</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>main page~~~!!</h1>
</body>
</html>
comment
WEB-INF 파일에 jsp파일 넣는 이유가 뭐죠...
이러면 컨트롤러 통해서만 봐야해서 불편한디
스프링 5버전 이상 쓰시는 분들
extends WebMvcConfigurerAdapter
deprecated 경고가 뜨면
implements WebMvcConfigurer
이걸로 바꿔주시면 됩니다
참고
https://www.baeldung.com/web-mvc-configurer-adapter-deprecated
+
서버 실행 시
[오류]java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
나시는 경우
https://jp1020.tistory.com/entry/%EC%98%A4%EB%A5%98javalangClassNotFoundException-orgspringframeworkwebservletDispatcherServlet
여기 내용처럼 하시면 됩니다.