티스토리 뷰

3) Spring MVC를 이용한 웹 페이지 작성 실습

사전 준비 사항

Maven Project를 생성합니다. 이때 archetypes webapp, Group Id kr.or.connect, Artifact Id mvcexam로 설정합니다.

Navigator 폴더에서 src main 폴더 안에 java 폴더도 하나 만들어 줍니다.

Project Explorer로 돌아가서 pom.xml에 필요한 부분들을 추가합니다. jdk 1.8 사용하기 위해서 plugins를 추가합니다.

<build>

           <finalName>mvcexam</finalName>

           <plugins>

                      <plugin>

                                  <groupId>org.apache.maven.plugins</groupId>

                                  <artifactId>maven-compiler-plugin</artifactId>

                                  <version>3.6.1</version>

                                  <configuration>

                                             <source>1.8</source>

                                             <target>1.8</target>

                                  </configuration>

                      </plugin>

           </plugins>

</build>

 

그리고 jstl, jsp, servlet 사용하기 위해서 라이브러리 추가합니다.

           <dependency>

                      <groupId>javax.servlet</groupId>

                      <artifactId>javax.servlet-api</artifactId>

                      <version>3.1.0</version>

                      <scope>provided</scope>

           </dependency>

          

           <dependency>

                      <groupId>javax.servlet.jsp</groupId>

                      <artifactId>javax.servlet.jsp-api</artifactId>

                      <version>2.3.1</version>

                      <scope>provided</scope>

           </dependency>

          

           <dependency>

                      <groupId>jstl</groupId>

                      <artifactId>jstl</artifactId>

                      <version>1.2</version>

           </dependency>

 

Spring을 사용하기 위해서 spring-context 추가하고 Spring MVC를 사용하기 위해서 webmvc 추가합니다. 그리고 Spring 버전을 통일하기 위해 properties에다가 Spring 버전을 넣습니다.

<properties>

           <project.build.sourceEncording>UTF-8</project.build.sourceEncording>

           <spring.version>4.3.5.RELEASE</spring.version>

</properties>

<dependency>

           <groupId>org.springframework</groupId>

           <artifactId>spring-context</artifactId>

           <version>${spring.version}</version>

</dependency>

 

<dependency>

           <groupId>org.springframework</groupId>

           <artifactId>spring-webmvc</artifactId>

           <version>${spring.version}</version>

</dependency>

 

pom.xml을 수정하면 반드시 Update Project 를 수행하여 업데이트 합니다.

그다음에 Navigator에서 settings facet 부분으로 가서 서블릿 버전을 3.1로 수정합니다. 수정 후에 Eclipse를 재시작합니다.

 

 

 

 

Properties Project Facet 부분에서 Dynamic Web Module이 제대로 바뀌어 있는지 확인합니다.

 

DispatcherServlet FrontController로 설정하기

  • Spring MVC에서 DispatcherServlet이 FrontController의 역할을 하기 위해 DispatcherServlet이 FrontController라는 설정을 합니다. 설정하는 방법이 여러 가지가 있는데 그 중 세 가지 방법에 대해서 알아보도록 하겠습니다.
  • web.xml 파일에 설정
    - 첫 번째는 DispatcherServlet도 일단 서블릿이기 때문에 web.xml 파일에 설정할 수 있습니다. xml에 servlet과 servlet mapping 태그에 각각의 값들을 넣어줘서 설정하는 방법을 활용하면 Spring이 제공하는 DispatcherServlet을 FrontController의 역할을 할 수 있도록 설정을 할 수가 있습니다.
  • javax.servlet.ServletContainerInitializer 사용
    -
    두 번째는 서블릿 3.0 이상의 스펙의 경우 web.xml을 대신하여 ServletContainerInitializer를 구현하는 클래스를 이용해서 설정하는 방법입니다.
  • org.springframework.web.WebApplicationInitializer 인터페이스를 구현해서 사용
    - 세 번째는 Spring이 제공하고 있는 WebApplicationInitializer 인터페이스를 구현하는 방법이 있습니다.
  • 이 중에서 가장 많이 사용되는 방법이 web.xml에다가 설정하는 방법과 WebApplicationInitializer 인터페이스를 구현하는 방법입니다. 여기서는 이 두 가지 방법에 대해서 살펴보겠습니다.

web.xml파일에서 DispatcherServlet 설정하기 - xml 파일로 설정 적용

xml spring 설정 읽어들이도록 DispathcerServlet설정(init-param으로 xml사용)

  • web.xml 파일에 서블릿을 등록합니다. servlet-name servlet mapping이 갖고 있는 servlet-name 하고 일치시킵니다.
  • servlet-class Spring이 제공하고 있는 DispatcherServlet을 이용할 것이므로 반드시 패키지 명을 포함해서 Spring이 제공하고 있는 클래스 명을 넣어줍니다.
  • init-param에서는 이 프로젝트에 대한 설정 정보를 어느 파일에 저장했는지 지정합니다. 나중에 이 xml 파일에 실제로 어떤 일들을 해야 될 건지를 설정합니다.

web.xml파일에서 DispatcherServlet 설정하기 - java config 파일로 설정 적용

Java config spring 설정 읽어들이도록 DispathcerServlet설정(init-param으로 클래스 사용)

  • DispatcherServlet xml 파일이 아니라 자바 config를 이용해서 사용을 할 수 있게 하는 방법입니다.
  • init-param 부분에 contextClass를 설정하여 xml 파일이 아니라 자바 클래스로 설정을 읽을 수 있도록 하였습니다. 해당 클래스는 contextConfigLocation을 통해 지정합니다. 여기서는 이 방법을 이용해서 설정들을 읽어올 것입니다.
  • servlet-mapping의 URL 패턴을 / 라고 설정해서 모든 요청을 받도록 설정합니다.

WebApplicationInitializer를 구현해서 설정하기

  • Spring MVC ServletContainerInitializer를 구현하고 있는 SpringServletContainerInitializer를 제공합니다.
  • SpringServletContainerInitializer WebApplicationInitializer 구현체를 찾아 인스턴스를 만들고 해당 인스턴스의 onStartup 메소드를 호출하여 초기화합니다.
  • 이 방법의 단점은 처음 웹 애플리케이션이 구동되는 시간이 오래 걸릴 수 있다는 겁니다.
  • Spring MVCWebApplicationInitializer 인터페이스를 구현한 구현체를 찾고 해당 객체의 onStartup 메서드를 이용해서 초기화를 하기 때문에 발생될 수 있습니다. 보통 설정하게 되면 화면처럼 WebApplicationInitializer 인터페이스를 구현하고 구현하고 있는 객체에서 이런 식으로 선언해서 사용할 수 있습니다. 여기서는 다루지 않고 그냥 소개만 하겠습니다.

Spring MVC 설정

  • kr.or.connect.mvcexam.config.WebMvcContextConfiguration
  • DispatcherServlet에 대한 설정은 web.xml에서 하고 DispatcherServlet이 읽어들여야 될 설정은 별도로 해야 합니다. 해당 설정은 자바 config(kr.or.connect.mvcexam.config.WebMvcContextConfiguration)로 설정합니다.
  • DispatcherServlet은 해당 설정 파일을 읽어서 내부적으로 Spring 컨테이너인 ApplicationContext를 생성하게 되는 겁니다.

DispatcherServlet Annotation

@Configuration

  • org.springframework.context.annotation Configuration 애노테이션과 Bean 애노테이션 코드를 이용하여 스프링 컨테이너에 새로운 빈 객체를 제공할 수 있다.
  • 이 어노테이션은 해당 클래스가 자바 config 파일이라는 것을 알려줍니다.

@EnableWebMvc

  • DispatcherServlet RequestMappingHandlerMapping, RequestMappingHandlerAdapter, ExceptionHandlerExceptionResolver, MessageConverter Web에 필요한 빈들을 대부분 자동으로 설정해준다.
  • xml로 설정했을 경우의 <mvc:annotation-driven/> 와 동일하다.
  • 기본 설정 이외의 설정이 필요하다면 WebMvcConfigurerAdapter 를 상속받도록 Java config class를 작성한 후, 필요한 메소드를 오버라이딩 하도록 한다.

EnableWebMvc의 코드

@ComponentScan

  • ComponentScan애노테이션을 이용하면 Controller, Service, Repository, Component애노테이션이 붙은 클래스를 찾아 스프링 컨테이너가 관리하게 된다.
  • DefaultAnnotationHandlerMapping RequestMappingHandlerMapping구현체는 다른 핸들러 매핑보다 훨씬 더 정교한 작업을 수행한다. 이 두 개의 구현체는 애노테이션을 사용해 매핑 관계를 찾는 매우 강력한 기능을 가지고 있다. 이들 구현체는 스프링 컨테이너, , 애플리케이션 컨텍스트에 있는 요청 처리 빈에서 RequestMapping애노테이션을 클래스나 메소드에서 찾아 HandlerMapping객체를 생성하게 된다.
  • HandlerMapping은 서버로 들어온 요청을 어느 핸들러로 전달할지 결정하는 역할을 수행한다.
  • DefaultAnnotationHandlerMapping DispatcherServlet이 기본으로 등록하는 기본 핸들러 맵핑 객체이고, RequestMappingHandlerMapping은 더 강력하고 유연하지만 사용하려면 명시적으로 설정해야 한다.
  • Spring MVC에서는 핸들러, , Controller를 찾아야 합니다. 컨트롤러를 찾기 위해서는 ComponentScan 어노테이션이 사용해야 합니다.

WebMvcConfigurerAdapter

  • org.springframework.web.servlet.config.annotation. WebMvcConfigurerAdapter
  • @EnableWebMvc 를 이용하면 기본적인 설정이 모두 자동으로 되지만, 기본 설정 이외의 설정이 필요할 경우 해당 클래스를 상속 받은 후, 메소드를 오버라이딩 하여 구현한다.

Controller(Handler) 클래스 작성하기

  • @Controller 애노테이션을 클래스 위에 붙인다.
  • 맵핑을 위해 @RequestMapping 애노테이션을 클래스나 메소드에서 사용한다.
  • 앞에까지 내용들이 모두 설정과 관련된 내용들이었다면 이제는 사용자가 핸들러 클래스인 컨트롤러를 작성해야 합니다. 실제로 요청을 처리하는 컨트롤러 클래스는 Controller라는 어노테이션을 클래스 위에다가 붙여주면 돼요.
  • 그러면 ComponentScan이 읽어들여서 Spring 컨테이너가 관리할 수 있도록 해줄 것입니다.
  • 그리고 Controller 클래스를 작성할 때 클래스 위나 메서드 위에다가 매핑을 위한 RequsetMapping이라는 어노테이션을 사용합니다. 요청에 대한 URL의 구분을 RequestMapping으로 합니다. 즉, 어떤 URL로 요청이 들어왔을 때RequestMapping에 설정한 값으로 컨트롤러를 구분하여 해당 컨트롤러가 작업을 처리할 수 있도록 합니다.

@RequestMapping

  • 서블릿을 등록할 때 URL 패턴을 지정하는 부분이랑 같다고 보면 됩니다.
  • 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")

실습

  • kr.or.connect.mvcexam.config 이름의 패키지를 생성합니다. 설정에 대한 부분을 모아놓은 패키지입니다. 그리고 DispatcherServletWebMvcContextConfiguration.java를 생성한 뒤 상속과 어노테이션을 지정합니다. ComponentScan 하실 때 basesPackages는 지정해야 합니다. 그렇지 않으면 어느 패키지부터 찾아내야 될지 몰라서 수행이 안 될 수도 있습니다. 여기서는 controller라는 패키지에서 찾을 거라고 지정한 것이라 보면 됩니다.
  • 지금 이 클래스가 DispatcherServlet이 실행될 때 읽어들이는 설정 파일이므로 추가로 사용할 메서드를 더 넣습니다.
  • addResourceHandlers라는 메서드를 오버라이드합니다. 이 부분이 필요한 이유는 URL요청이 컨트롤러에 매핑된 요청 이외에도 다른 파일이 들어오기 때문입니다. web.xml에서 DispatcherServlet 설정할 때 url-pattern/로 지정하였습니다. 그러나 컨트롤러의 URL이 매핑되어있는 요청만 들어오는 게 아니라 CSS라든가, 이미지라든가, 자바스크립트라든가 이런 등등의 것들도 요청에 해당되어 다 받아버립니다. 그래서 초창기에는 URL 패턴 부분에다가 /가 아니라 .do라는 걸 많이 사용을 했습니다. 그렇게 되면 .do라는 요청이 들어왔을 때만 컨트롤러에서 작업을 처리하고 HTML이라든가 .img이라든가 이런 것들은 다르게 요청을 처리했습니다.
  • 그런데 현재는 그렇게 url이 들어오는 방식이 약간 촌스럽기도 하고 노출이 되는 부분도 있고 이렇다 보니까 그렇게 하는 방식을 선호하지 않습니다. 그래서 addResourceHandlers를 이용하여 실제로 요청이 들어올 때 /js/**, /img/**, /css/** 이렇게 시작하는 URL 요청은 애플리케이션 루트 디렉터리 아래에 있는 각각의 이런 디렉터리를 만들어놓고 거기에다가 알맞게 사용하도록 합니다.

    (안하면 404)
  • 내용을 보면 addResourceHandler의 파라미터로 들어오는 요청들은 addResourceLocations의 파라미터에서 찾으라는 설정입니다. 이 부분이 없다면 모두 컨트롤러가 가진 RequestMapping에서 그것들을 찾으려고 하면서 오류를 발생시킬 겁니다. 그 부분 때문에 이 메서드가 반드시 필요하다고 이해하면 될 것 같습니다.

    @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);

    }

 

  • 다음으로는 configuerDefaultServletHandling 메서드를 오버라이드 하고 있는데 이 부분에서는 파라미터로 전달받은 DefaultServletHandlerConfigurer 객체의 enable이라는 메서드를 호출함으로써 DefaultServletHandler를 사용하도록 해주는 겁니다.
  • 매핑 정보가 없는 URL 요청은 Spring DefaultServletHttpRequestHandler가 처리하도록 해줍니다. Spring DefaultServletHttpRequestHandlerWAS DefaultServlet에게 해당 일을 넘깁니다. 그러면 WAS DefaultServlet static 한 자원을 읽어서 보여주게 해주는 겁니다.

    // default servlet handler를 사용하게 합니다.

    @Override

    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

        configurer.enable();

    }

 

  • 그 다음에 addViewControllers 메서드는 특정 URL에 대한 처리를 컨트롤러 클래스를 작성하지 않고 매핑할 수 있도록 해주는 메서드입니다. 요청 자체가 "/" 하고 들어오면 "main"이라고 하는 이름의 뷰로 보여주도록 하는 겁니다. 그러니까 main을 어떻게 찾아내게 되냐면 view name ViewResolver라는 객체를 이용해서 찾습니다. 실제 "main"이라는 이름만 가지고서는 뷰 정보를 찾아낼 수가 없고 뷰 정보는 getInternalResourceViewResolver 라는 메서드에서 설정된 형태로 뷰를 사용하게 됩니다.
  • getInternalResourceViewResolver를 보면 InternalResourceViewResolver를 생성을 하고 있고 이 resolver한테 Prefix, Suffix를 지정하고 있는 걸 볼 수 있습니다. 그러니까 이 이름 앞쪽에다가 prefix, Suffix는 뒤쪽에다가 붙여달라는 겁니다. 그러면 WEB-INF/views/main.jsp 라는 파일을 찾아주게 됩니다. 메서드가 지금 이제 뷰가 되는 거죠.

    @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;

    }

 

  • 위의 설정을, 오버라이딩된 메서드들을 읽어들여서 DispatcherServlet이 동작을 하게 될 거다라고 이해하시면 됩니다.
  • 다음으로는 이런 DispatcherServlet이 실제로 동작하도록 DispatcherServlet FrontServlet으로 등록하기 위해 web.xml을 엽니다.
  • servlet-mapping의 url-pattern을 "/" 으로 설정합니다. url "/" 하고 들어오면 모든 요청이 될 수 있겠죠. servlet-name mvc라고 되어있으니까 servlet-name이 똑같은 servlet element 안에 있는 servlet-name mvc인 이름을 찾아갈 겁니다.

<servlet-mapping>

    <servlet-name>mvc</servlet-name>

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

  </servlet-mapping>

 

  • mvc라는 이름의 servlet 안에는 servlet-class로 Spring이 제공하고 있는 DispatcherServlet이 설정되어 있습니다. 이 servlet을 FrontController로 한다는 의미를 갖고 있습니다.

<servlet-name>mvc</servlet-name>

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

 

  • 그리고 init-param에서 contextConfigLocation에다가 아까 만들었던 java config 파일을 등록합니다. 그러면 해당 설정들을 DispatcherServlet이 실행될 때 읽을 수 있습니다. 항상 클래스 등록하실 때는 패키지 명을 포함해서 등록하셔야 합니다.

<init-param>

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

      <param-value>kr.or.connect.mvcexam.config.WebMvcContextConfiguration</param-value>

    </init-param>

 

  • 그런 다음에 contextClass도 등록이 되었는지 확인합니다. ApplicationContext가 Bean 공장으로 어떤 클래스를 사용하는지 정하는 겁니다. 실행이 될 때는 AnnotationConfigWebApplicationContext 를 사용을 할 거라고 설정하고 있습니다.

<init-param>

      <param-name>contextClass</param-name>

      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>

</init-param>

 

  • 이렇게 해야 Spring에서 제공하고 있는 DispatcherServletFrontController의 역할을 할 수 있을 겁니다.
  • 간단한 테스트를 해보겠습니다. addViewControllers에 의해 / 로 접속하면 main.jsp로 이동할 것입니다. 이 부분은 RequestMapping이 없어도 실행되므로 제대로 동작을 하는지 보겠습니다.
  • main.jsp를 해당 경로, WEB-INF에다가 views라는 폴더를 하나 만드시고 views 안에다가 만듭니다.
  • 그런 다음에 실제로 이 페이지가 잘 뜨는지만 확인해볼 거니까 그냥 "main page" 만 써놓겠습니다.
  • 실행해보면 index.jsp로 접속이 되는데 이는 기본 설정 때문에 그런 것입니다. 해당 파일은 필요가 없으므로 삭제합니다.


  • 이렇게 실행하고 "/"로 요청이 들어왔을 때 main 페이지가 잘 호출되고 있는 것을 확인할 수가 있습니다. 여기까지 잘 나온다면 기본 설정을 잘 마친거라고 볼 수 있습니다.

실습 코드

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);

    }

 

    // default servlet handler를 사용하게 합니다.

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

 

Spring MVC를 이용한 웹 페이지 작성 실습

실제로 컨트롤러를 몇 개 작성을 해보겠습니다.

Controller 작성 실습 1/3

  • 요구사항
    • 웹 브라우저에서 http://localhost:8080/mvcexam/plusform 이라고 요청을 보내면 서버는 웹 브라우저에게 2개의 값을 입력받을 수 있는 입력 창과 버튼이 있는 화면을 출력한다.
    • 웹 브라우저에 2개의 값을 입력하고 버튼을 클릭하면 http://localhost:8080/mvcexam/plus URL 2개의 입력값이 POST방식으로 서버에게 전달한다. 서버는 2개의 값을 더한 후, 그 결과 값을 JSP에게 request scope으로 전달하여 출력한다.
  • 첫 번째 만들 JSP 파일은 입력 2개 받아내는 화면입니다. 이름은 plusform이라 하겠습니다. plusform에서는 입력을 2개 받아들이는 input 상자 2개랑 submit 버튼이 하나를 코딩합니다form 태그로 URL을 action에다가 지정하면 이 URL로 서버에다가 요청을 하게 됩니다. 그리고 요청을 할 때 메서드 방식은 POST로 보낼 거고 실제 이런 name 2개로 value1, value2라는 name으로 값을 전달해서 보낼 겁니다.
  • 두 번째로 만들 JSP 파일은 요청이 들어왔을 때, plus라는 요청을 받았을 때 처리하게 될 JSP입니다. 이름은 plusResult.jsp 라 하겠습니다. plusform.jsp에서 컨트롤러에게, 컨트롤러에서 plusResult.jsp에게 request scope을 통해 전달을 할겁니다. 각각의 값들을 request scope한테 꺼내가지고 출력할 수 있는 JSP 파일을 하나 만듭니다.
  • 그다음에 컨트롤러를 만들어야 합니다. 핵심이에요.
  • 컨트롤러만 모아놓는 패키지를 생성해줍니다. 이름을 kr.or.connect.mvcexam.controller 로 합니다. 해당 패키지에다가 사용할 컨트롤러, PlusController.java를 만듭니다.
  • 만들고 컨트롤러 클래스에는 반드시 클래스 위에다가 @Controller 어노테이션 붙여줘야 합니다. 그래야 찾아내서 사용할 수 있을 겁니다.
  • 해당 컨트롤러가 처리하는 요청이 2개입니다. 하나는 plusform이라는 요청이 들어왔을 때 대응해야 하고, 다른 하나는 plus라는 요청이 들어왔을 때도 대응해야 해서 메서드가 2개 만들어져야합니다. 이때 plusform 부분은 GET 방식으로 요청을 받아들이면 될 거고, plus POST 방식으로 받겠다고 했으니까 메서드 자체를 POST 방식으로 받아들이도록 합니다.
  • Mapping에 대한 부분은 @RequestMapping을 사용할 수 있었습니다. 그리고 Spring 버전 4.3부터는 @GetMapping, @PostMapping 같은 것들도 지원합니다. 우리는 Spring 4.3.5 버전을 사용하고 있으니까 @GetMapping으로 RequestMapping을 사용할 수 있습니다.
  • 일단은 먼저 plusform부터 보겠습니다. GET 방식으로 들어올 거라고 했으니까 GetMapping이라는 어노테이션을 사용하겠습니다GetMapping이 받아들일 path "/plusform" 이라고 지정합니다.
  • 메서드를 정의하는데 리턴으로 view name을 넘겨줘야 합니다. 이 때 리턴 타입을 ModelAndView라는 객체로 리턴할 수도 있고, String 타입으로 간단하게 뷰 이름만 넘겨줄 수도 있습니다. 현재 같은 경우에 굉장히 간단하게 처리하는 거니까 String으로 view name을 넘기겠습니다.
  • 메서드 이름은 가급적이면 연결이 있는 걸로 사용하시는 게 좋습니다. 실제 이 요청이 들어왔을 때는 컨트롤러에서 해야 될 일이 하나도 없죠? 해당 뷰만 찾아다가 뷰에 대한 정보만 넘겨주면 되니까 여기에다가 뷰의 이름을 넘겨주시면 됩니다.
  • 리턴으로 String 타입을 줬으니 뷰 네임을 뱉어야 하는데 jsp 이름으로 지정해야 합니다. 그러니까 아까 jsp 파일을 plusForm이라고 만들었으니 "plusForm" 이렇게 이름을 넘겨줍니다. 이때 대소문자 구분하니 주의하도록 합니다.
  • 이제 리턴받은 이 이름을 가지고 WebMvcContextConfiguration 클래스의 getInternalResourceViewResolver 메서드가 prefix와 suffix를 붙여서 완벽한 뷰의 정보, 해당 경로에 있는 파일을 찾아서 뷰로 보여줍니다.
  • 테스트하기 위해서 브라우저에서 url을 쳐서 페이지를 띄워봅니다localhost:8080/mvcexam/plusform으로 접속했을 때 jsp가 나온다면 성공한 겁니다.

 

  • 두 번째 요청을 처리하기 위해서 POST로 받기로 했으니까 메서드 위에 @PostMapping을 붙이고 path plus로 받기로 했으니까 "/plus" 하고 지정합니다.
  • 이 메서드에서는 form에서 넘겨 받은 2개의 값을 더한 다음에 각각 얘네들을 request scope에다가 넣어서 넘겨주면 해당 jsp가 값들을 출력하도록 해야 합니다.
  • 그러한 부분들을 메서드 인수 어노테이션을 이용하여 쉽게 사용할 수 있습니다.

Spring MVC가 지원하는 Controller메소드 인수 타입

  • javax.servlet.ServletRequest
  • javax.servlet.http.HttpServletRequest
  • org.springframework.web.multipart.MultipartRequest
  • org.springframework.web.multipart.MultipartHttpServletRequest
  • javax.servlet.ServletResponse
  • javax.servlet.http.HttpServletResponse
  • javax.servlet.http.HttpSession
  • org.springframework.web.context.request.WebRequest
  • org.springframework.web.context.request.NativeWebRequest
  • java.util.Locale
  • java.io.InputStream
  • java.io.Reader
  • java.io.OutputStream
  • java.io.Writer
  • javax.security.Principal
  • java.util.Map
  • org.springframework.ui.Model
  • org.springframework.ui.ModelMap
  • org.springframework.web.multipart.MultipartFile
  • javax.servlet.http.Part
  • org.springframework.web.servlet.mvc.support.RedirectAttributes
  • org.springframework.validation.Errors
  • org.springframework.validation.BindingResult
  • org.springframework.web.bind.support.SessionStatus
  • org.springframework.web.util.UriComponentsBuilder
  • org.springframework.http.HttpEntity<?>
  • Command 또는 Form 객체
  • Spring MVC가 지원하는 Controller 메서드의 인수 타입들은 필요할 때 컨트롤러의 메서드에다가 해당 부분들을 선언만 하면 됩니다. 그러면 Spring이 자동으로 이런 부분들을 만들어서 넣어줍니다.

Spring MVC가 지원하는 메소드 인수 어노테이션

  • @RequestParam
  • @RequestHeader
  • @RequestBody
  • @RequestPart
  • @ModelAttribute
  • @PathVariable
  • @CookieValue
  • Spring MVC가 지원하고 있는 인자의 어노테이션입니다. 어노테이션 붙여가지고 사용할 수 있습니다.

자주 사용할 메서드 인수 어노테이션

  • @RequestParam
    • Mapping된 메소드의 Argument에 붙일 수 있는 어노테이션
    • @RequestParam name에는 http parameter name과 맵핑. HTML form 태그에 input 상자의 name과 매핑돼서 여기에 지정된 name에 있는 값을 꺼낼 수 있습니다.
    • @RequestParam required는 필수인지 아닌지 판단. 그러니까 지정할 때 required라는 속성을 줄 수 있는데 그걸 가지고 필수인지 아닌지 판단이 가능합니다.
  • @PathVariable
    • 실제 URL path에다가 우리가 '?변수명 = 값' 이런 식으로 값을 넘겨올 때가 있었을 텐데 이럴 때 path에서 넘겨온 값을 받기 위해서 사용되는 어노테이션입니다.
    • @RequestMapping path에 변수명을 입력받기 위한 place holder가 필요함
    • place holder의 이름과 PathVariable name 값과 같으면 mapping
    • required 속성은 default true
    • 이런 부분들을 이용할 때 항상 주의하실 점은 이름이 정확히 일치하는지 주의해야 합니다. 왜냐하면 Spring이 대신 알아서 매핑하기 때문입니다.
  • @RequestHeader
    • 요청 정보의 헤더 정보를 읽어들 일 때 사용
    • @RequestHeader(name="헤더명") String 변수명
  • Spring MVC가 지원하는 메소드 리턴 값
    • org.springframework.web.servlet.ModelAndView
    • org.springframework.ui.Model
    • java.util.Map
    • org.springframework.ui.ModelMap
    • org.springframework.web.servlet.View
    • java.lang.String
    • java.lang.Void
    • org.springframework.http.HttpEntity<?>
    • org.springframework.http.ResponseEntity<?>
    • 기타 리턴 타입
    • 컨트롤러 메서드가 리턴할 때 리턴 값들을 지정할 수 있습니다. 아까와 같이 String 리턴하거나 ModelAndView 같은 객체 등도 가능합니다.

실습

  • 컨트롤러의 plus 메서드의 파라미터를 살펴보겠습니다. 메서드 인수 어노테이션을 적용하였는데 @RequestParam으로 name value1이라고 들어오는 것은 required 속성이 true라고 설정하였습니다. name이 value1로 들어오는 거를 plus 메서드 내에서는 int 타입으로, 메서드 내에서는 value1이라는 이름으로 사용할 거라는 뜻입니다.
  • 다시 이야기하자면 plusForm.jsp에서 보면 input name이 value1 이라고 넘어올 거잖아요. 그 부분이 @RequestParam입니다. input의 이름이 value1인 것의 값을 int형 변수 value1에다가 넣어준다는 의미입니다.
  • value2도 똑같이 @RequestParam 사용해서 넣어줍니다.

public String plus(@RequestParam(name = "value1", required = true) int value1,                               @RequestParam(name = "value2", required = true) int value2, ModelMap modelMap) {

 

  • 그다음에 request scope에다가 값을 넣어줍니다.
  • 여기서 HttpServletRequest 이런 것들을 선언해서 쓸 수도 있습니다. request.setAttribute 해서 가지고 값을 request에 직접 지정할 수도 있지만 그렇게 되면 HttpServletRequest에 종속되게 되니까 해당 방법을 사용하지 않습니다. 그래서 파라미터로 받은, Spring이 제공하고 있는 ModelMap이라는 객체에 넣어줄 겁니다. 여기다가 넣으면 Spring이 알아서 이 부분을 request scope에다가 알아서 매핑 시켜줍니다. 그러면 나중에 그걸 가져다가 그냥 사용하면 됩니다.
  • 다양한 타입으로 가져다가 사용할 수 있으니까 알맞은 것을 사용하면 됩니다. 그중에 ModelAndView 이런 객체를 받아와서 사용할 수도 있고 Model 객체를 받아와서 사용할 수도 있습니다.
  • 지금은 ModelMap이라는 것을 얻어온 다음에 해당 부분들을 modelMap에다가 값을 넣어주겠습니다.
  • 여기에 넣으실 때는 Map에 키, 밸류 넣는 것과 비슷하게 설정할 수 있습니다.

modelMap.addAttribute("value1", value1);

modelMap.addAttribute("value2", value2);

modelMap.addAttribute("result", result);

 

  • 그런 다음에 이제 String으로 리턴하기로 했죠. 리턴 부분이 view name이 될 거예요. 그러면 view name은 실제 여기에서 WebMvcContextConfigurationViewResolver를 통해서 pluseResult.jsp라는 뷰를 찾아낼 겁니다. 그럼 이 뷰는 html을 출력하면서 request scope에서 해당 값들을 꺼내다가 화면에다가 출력을 해주게 될 겁니다.

  • 테스트해보면 다음과 같습니다.
  • 만약 아래와 같이 나온다면 서블릿 버전이 2.5 이하여서 EL을 인식하지 못한 경우일 수도 있으니 우선 properties - project facets을 확인하고 3.1이상이면 web.xml에 들어가서 맨 윗줄을 확인합니다.
  • web.xml의 맨 윗줄이 아래와 같다면 2.3 서블릿 버전을 인식하고 있는 것이므로 다음과 같이 바꿉니다.
  • 이렇게 수정을 해도 이미 서버에 올라와있는 프로젝트이므로 인식이 되지 않을 수 있습니다. 그러면 서버탭에서 서버 하위에 있는 프로젝트를 삭제한 후에 다시 실행시킵니다. 그래도 안되면 Project 메뉴 중에서 Clean을 실행합니다CleanEclipse가 내부적으로 잘못 가지고 있는 설정들 지저분하게 엉켜있는 설정들 이런 부분들을 한번 정리해주는 것입니다.

실습 코드

plusForm.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>

<form method="post" action="plus"> 

value1 : <input type="text" name="value1"><br>

value2 : <input type="text" name="value2"><br>

<input type="submit" value="확인"> 

</form> 

</body>

</html>

 

plusResult.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>

${value1} 더하기 ${value2} (/) ${result} 입니다.

</body>

</html>

 

PlusController.java

package kr.or.connect.mvcexam.controller;

 

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

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

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

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

 

@Controller

public class PlusController {

           @GetMapping(path = "/plusform")

           public String plusform() {

                      return "plusForm";

           }

 

           @PostMapping(path = "/plus")

           public String plus(@RequestParam(name = "value1", required = true) int value1,

                                  @RequestParam(name = "value2", required = true) int value2, ModelMap modelMap) {

                      int result = value1 + value2;

 

                      modelMap.addAttribute("value1", value1);

                      modelMap.addAttribute("value2", value2);

                      modelMap.addAttribute("result", result);

                      return "plusResult";

           }

}

 

Controller 작성 실습 2/3

  • 요구사항
    • http://localhost:8080/mvcexam/userform 으로 요청을 보내면 이름, email, 나이를 물어보는 폼이 보여진다.
    • 폼에서 값을 입력하고 확인을 누르면 post방식으로 http://localhost:8080/mvcexam/regist 에 정보를 전달하게 된다.
    • regist에서는 입력받은 결과를 콘솔 화면에 출력한다.
  • 먼저 유저의 정보를 받아내는 userform.jsp를 만듭니다. userform에서는 입력 값을 받아내는 폼이 필요합니다. 그래서 form 태그 사용해서 submit 버튼을 누르면 regist라는 요청이 들어가게 됩니다. 이 때 메서드는 POST 방식으로 들어가게 합니다.

  • 요청을 처리할 컨트롤러인 UserController.java 클래스를 만듭니다.
  • @Controller라는 어노테이션을 붙이고 요청이 userform이라고 들어왔을 때 데이터를 처리할 메서드를 만듭니다.
  • 메서드는 @RequestMapping으로 받고 path "/userform"으로 설정합니다. 이때 메서드는 GET 방식으로 받도록 합니다. 이렇게 하면 지난번의 @GetMapping과 똑같이 받아내는 거예요. 리턴은 이렇게 받았을 때 뷰 이름이죠. userform이라고 보내면 views 안에 들어있는 userform.jsp를 보여줄 겁니다.

  • 테스트해서 userform으로 접속했을 때 userform.jsp가 나오면 성공한 것입니다.

  • 그다음으로 할 일은 userform에서 값들을 입력하고 submit 버튼을 눌렀을 때 regist라는 요청이 들어올텐데 이게 들어왔을 때 처리할 부분을 수행을 하면 됩니다.
  • @RequestMapping인데 path "/regist"이고 POST 방식으로 설정합니다. 그리고 값들을 읽어와서 콘솔에 출력합니다.
  • userform에서 값을 보냈을 때 보낸 값을 이렇게 @RequestParam을 통해서 하나, 하나 받는 방법도 있지만 DTO를 통해서 한꺼번에 받아낼 수도 있습니다.
  • @ModelAttribute라는 어노테이션을 이렇게 붙여주고 담아낼 객체를 하나 선언해주면 가져온 값을 여기다 담습니다.

  • DTO를 모아놓은 패키지도 만들어 보겠습니다.(kr.or.connect.mvcexam.dto)
  • 그리고 여기서 DTO로 사용할 User 클래스도 생성합니다. 필드는 name, email, 나이에 대하여 설정합니다.
  • 항상 주의하셔야 될 점은 Spring이 자동으로 여기에다가 값을 채워줄 것이므로 반드시 jsp input에 있는 name과 실제 DTO가 가진 name이 일치해야지만 Spring이 알아서 값을 채워줄 수 있다는 점입니다.
  • 그리고 하나 더 이 객체의 필드들은 다 private 합니다. 그런데 Spring이 접근해서 사용하려면 각각 이 필드의 setter 메서드들을 이용해야 할 것입니다.
  • DTO 사용할 때 반드시 필요한 것은 아니지만 toString 같은 메서드를 오버라이딩 하시면 해당 객체의 정보들을 손쉽게 볼 수 있으므로 구현합니다.
  • DTO 객체를 만들면 @ModelAttribute라는 어노테이션에 방금 만든 User라는 DTO를 선언합니다. 그러면 Spring MVC가 알아서 DTO 객체를 생성하고 jsp input에서 넘긴 값과 일치하는 name들을 꺼내서 생성한 DTO에 넣어줍니다.
  • 그다음엔 "regist"라는 값을 리턴하고 regist.jsp 파일을 생성하여 잘 등록되었다는 메시지를 출력하도록 합니다.
  • 테스트해보면 다음과 같습니다.

Controller 작성 실습 3/3

  • 요구사항
    • http://localhost:8080/mvcexam/goods/{id} 으로 요청을 보낸다.
    • 서버는 id를 콘솔에 출력하고, 사용자의 브라우저 정보를 콘솔에 출력한다.
    • 서버는 HttpServletRequest를 이용해서 사용자가 요청한 PATH정보를 콘솔에 출력한다.
  • 이번에는 goods라는 요청을 보낼 텐데 뒤에 중괄호해서 id가 같이 넘어옵니다. 이렇게 넘기는 값을 path variable이라고 합니다이런 식으로 요청을 보내면 서버는 해당 id를 콘솔에 출력하고 사용자의 브라우저 정보도 출력을 하는 것을 만들어보겠습니다.
  • 출력을 담당하는 JSP인 goodsById.jsp를 만듭니다. 출력할 때는 서버 쪽에서 등록한 값을 꺼내가지고 화면에 출력할 수 있도록 JSP 파일을 하나 만듭니다.
  • 컨트롤러 클래스 GoodsController.java를 생성합니다. 그리고 @Controller 어노테이션을 설정합니다.
  • 여기서는 path variable로 값이 들어왔을 때 이것을 처리하도록 코드를 작성하겠습니다. URL 요청이 들어왔을 때 이 뒤에 들어오는 값(여기서는 {id} 부분이 해당) 이것을 path variable로 받겠다는 뜻입니다.
  • 그래서 인자 안에 어노테이션이 @PathVariable 하고 붙어있는 걸 볼 수 있습니다. getMapping에서 id라는 이름으로 넘어온 것을 int형 변수 id에다가 받겠다는 의미입니다. 그러니까 이 메서드 안에서 사용할 때는 이 id를 사용하면 됩니다.
  • 그다음에 헤더에서 넘어오는 정보들을 꺼내기 위해 @RequestHeader를 사용하고 있습니다. 이때 받아온 것들을 String 변수로 받아내서 사용하고 있는 것을 볼 수 있습니다.
  • Request가 가진 값들은 스프링에서 지원하지 않으므로 HttpServletRequest를 이용하여 값을 꺼냅니다. 가급적이면 종속되는 부분들 때문에 사용하지 않는 게 좋지만 꼭 사용할 수밖에 없는 경우이므로 이렇게 사용하시면 됩니다.
  • 그리고 ModelMap을 이용해서 이렇게 값들을 등록시켜주면 JSP가 해당 값들을 꺼내다가 사용할 수가 있습니다.
  • "/goods" 뒤의 id 1을 넣어 테스트 해보겠습니다.
  • id, user_agent, path 정보들을 가져와서 출력을 하고 있습니다. 헤더로 전달된 정보라든가, request를 이용해서 꺼내온 정보들을 잘 가져와서 출력을 하고 있는 것을 볼 수 있습니다.

 

실습 코드

userform.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>

<form method="post" action="regist"> 

name : <input type="text" name="name"><br>

email : <input type="text" name="email"><br>

age : <input type="text" name="age"><br>

<input type="submit" value="확인">

</body>

</html>

 

UserController.java

package kr.or.connect.mvcexam.controller;

 

import org.springframework.stereotype.Controller;

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

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

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

 

import kr.or.connect.mvcexam.dto.User;

 

@Controller

public class UserController {

           @RequestMapping(path="/userform", method=RequestMethod.GET)

           public String userform() {

                      return "userform";

           }

          

           @RequestMapping(path="/regist", method=RequestMethod.POST)

           public String regist(@ModelAttribute User user) {

 

                      System.out.println("사용자가 입력한 user 정보입니다. 해당 정보를 이용하는 코드가 와야합니다.");

                      System.out.println(user);

                      return "regist";

           }

}

 

User.java

package kr.or.connect.mvcexam.dto;

 

public class User {

           private String name;

           private String email;

           private int age;

           public String getName() {

                      return name;

           }

           public void setName(String name) {

                      this.name = name;

           }

           public String getEmail() {

                      return email;

           }

           public void setEmail(String email) {

                      this.email = email;

           }

           public int getAge() {

                      return age;

           }

           public void setAge(int age) {

                      this.age = age;

           }

           @Override

           public String toString() {

                      return "User [name=" + name + ", email=" + email + ", age=" + age + "]";

           }         

}

 

regist.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>

<h2>등록되었습니다.</h2>

</body>

</html>

 

goodsById.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>

id : ${id } <br>

user_agent : ${userAgent }<br>

path : ${path }<br>

</body>

</html>

 

GoodsController.java

package kr.or.connect.mvcexam.controller;

 

import javax.servlet.http.HttpServletRequest;

 

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

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

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

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

 

@Controller

public class GoodsController {

           @GetMapping("/goods/{id}")

           public String getGoodsById(@PathVariable(name="id") int id,

                                                                                 @RequestHeader(value="User-Agent", defaultValue="myBrowser") String userAgent,

                                                                                HttpServletRequest request,

                                                                                ModelMap model

                                                                                ) {

                     

                      String path = request.getServletPath();

                     

                      System.out.println("id : " + id);

                      System.out.println("user_agent : " + userAgent);

                      System.out.println("path : " + path);

                     

                      model.addAttribute("id", id);

                      model.addAttribute("userAgent", userAgent);

                      model.addAttribute("path", path);

                      return "goodsById";

           }

}

 

생각해보기

  • SpringMVC를 이용해서 웹 어플리케이션을 개발하는 것과 서블릿을 이용해 개발하는 것과 비교해보면 어떤 장단점이 있다고 생각하세요?

참고 자료

[참고링크] WebMvcConfigurationSupport
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java

[참고링크] Web on Servlet Stack
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html

 

cf) 예제 2번에서 form에 한글을 입력 후 regist path로 넘기면 한글이 깨지는 현상이 있는데요, 아래 코드를 web.xml에 첨부하시면 해결됩니다!

<filter>

        <filter-name>encodingFilter</filter-name>

        <filter-class>

            org.springframework.web.filter.CharacterEncodingFilter

    </filter-class>

    <init-param>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

    </init-param>

</filter>

<filter-mapping>

        <filter-name>encodingFilter</filter-name>

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

</filter-mapping>

저와 같은 증상이 있으신분들께 공유드립니다.

동철(디오)  2018.05.05

 

Comments