ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Back End] Spring MVC
    Web Development/부스트코스 - Back-End(Java) 2020. 4. 3. 22:15

    ✔️ MVC

    ◾ MVC는 Model-View-Controller의 약자이다. 

    ◾ Model : 모델은 뷰가 렌더링하는데 필요한 데이터이다. 예를들어 사용자가 요청한 상품 목록이나 주문내역이 이에 해당한다.

    ◾ View : 웹 애플리케이션에서 뷰는 실제로 보이는 부분이며, 모델을 사용해 렌더링을 한다. 뷰는 JSP, JSF, PDF, XML 등으로 표현한다.

    ◾ Controller : 컨트롤러는 사용자의 액션에 응답하는 컴포넌트이다. 컨트롤러는 모델을 업데이트하고, 다른 액션을 수행한다. 

     


    ✔️ Spring MVC

     

    Spring MVC 기본 동작 흐름

    1️⃣ DispatcherServlet

    ◾ 프론트 컨트롤러(Front Controller)

    ◾ 클라이언트의 모든 요청을 받은 후 이를 처리할 핸들러에게 넘기고 핸들러가 처리한 결과를 받아 사용자에게 응답 결과를 보여준다.

    ◾ DispatcherServlet은 여러 컴포넌트를 이용해 작업을 처리한다. 

     


    ✔️ Spring MVC 실습 1

    ◾ 아래 기능을 하는 실습을 해보자 

    웹 브라우저에서 http://localhost:8080/mvcexam/plusform 이라고 요청을 보내면 서버는 웹 브라우저에게 2개의 값을 입력받을 수 있는 입력창과 버튼이 있는 화면을 출력한다.

    웹 브라우저에 2개의 값을 입력하고 버튼을 클릭하면 http://localhost:8080/mvcexam/plus URL로 2개의 입력값이 POST 방식으로 서버에 전달한다. 서버는 2개의 값을 더한 후, 그 결과 값을 JSP에게 request scope로 전달하여 출력한다. 

    💾 WebMvcContextConfiguration.java : Spring DispatcherServlet설정 클래스

    더보기
    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 {  
       
        //css파일, img 파일, js 파일 등 스태틱 소스에 대한 요청 처리. 이 부분이 없으면 컨트롤러를 통해 해야함.. 
        @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); 
        } 
      
        // 매핑정보가 없는 url요청은  스프링의 default sevlet http request handler가 처리하도록 해준다.  
        // 스프링의 default servlet http request handler는 was의 defalut servlet에게 해당일을 넘긴다.  
        // was는 defalut servelt이 스태틱한 자원을 읽어서 보여주게 한다. 
    
        @Override 
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
            configurer.enable(); 
        } 
        
        // 특정 URL에 대한 처리를 Controller 클래스를 작성하지 않고 매핑할 수 있도록 해준다. 
        @Override 
        public void addViewControllers(final ViewControllerRegistry registry) { 
                System.out.println("addViewControllers가 호출됩니다. "); 
            // "/" 라는 URL을 main.jsp로 매핑해준다. 
            // main이라는 viewName은  아래의 viewResolver 라는 객체를 통해서 찾는다. 
            // Prefix + "main" + Suffix -> /WEB-INF/views/main.jsp (아래 InternalResourceViewResolve 메서드를 보자) 
            registry.addViewController("/").setViewName("main");  
        } 
         
        @Bean 
        public InternalResourceViewResolver getInternalResourceViewResolver() { 
            InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 
            resolver.setPrefix("/WEB-INF/views/");  
            resolver.setSuffix(".jsp");  
            return resolver; 
        } 
    }

    💾 web.xml : Spring DispatcherServlet을 FrontController로 설정하는 파일

    더보기
    <?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> <!-- 스프링이 제공하는 DispatcherServlet을 FrontController로 설정 --> 
        <init-param>
          <param-name>contextClass</param-name> <!-- IoC를 위한 bean 공장 설정 -->
          <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param> <!-- WebMvcContextConfiguration 클래스를 보고 DispatcherServlet을 설정한다. -->
          <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> <!-- "/" 즉, 모든 요청에 대해  서블릿 네임 mvc가 실행 되도록하는 설정-->
      </servlet-mapping>
    </web-app>

    💾 plusForm.jsp : 두 개의 숫자를 입력받고, /plus URL로 POST 요청을 보냄

    더보기
    <%@ 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 : request socope에서 결과값을 가져와서 보여줌

    더보기
    <%@ 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 : plus 관련 컨트롤러

    더보기
    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 {
      
      // GET 요청 처리 메서드
       @GetMapping(path="/plusform")
       public String plusform() {
         return "plusForm"; //plusFrom.jsp 뷰를 보여준다. WebMvcContextConfiguration 클래스에서 설정한대로 된다(WEB-INF/views/plusForm.jsp)
       }
       
       // POST 요청 처리 메서드. 값 두개를 받아서 결과값을 request scope에 넣어주고 plusResult 뷰를 보여준다. 
       // @RequestParam의 name은 http parameter의 name과 매핑된다. (html input 상자의 name과 매핑) required는 값이 필수인지 아닌지 설정하는 것
       @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 객체를 사용해 request scope에 변수를 넣어준다. 
           modelMap.addAttribute("value1", value1); 
           modelMap.addAttribute("value2", value2);
           modelMap.addAttribute("result", result);
           return "plusResult"; // views/plusResult.jsp 로 연결 ( WebMvcContextConfiguration 클래스의 viewResolver을 통해 WEB-INF/views/plusResult.jsp로 연결된다. )
       }
    }
    

     

     


    ✔️ Spring MVC 실습 2

    ◾ http://localhost:8080/mvcexam/userform 으로 요청을 보내면 이름, email, 나이를 물어보는 폼이 보여진다.

    ◾ 폼에서 값을 입력하고 확인을 누르면 post 방싟으로 http://localhost:8080/mvcexam/regist에 정보를 전달하게 된다.

    ◾ regist에서는 입력받은 결과를 콘솔 화면에 출력한다. 

     

    💾 userform.jsp : user 정보를 입력받아 /regist에 post로 요청하는 뷰

    더보기
    <%@ 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>

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

    💾 UserController.java : user 관련 컨트롤러

    더보기
    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 {
      
        // "/userform" URL에 대해 userform.jsp 뷰를 보여준다. 
        @RequestMapping(path="/userform", method=RequestMethod.GET) //@GetMapping 어노테이션으로도 할 수 있음.
        public String userform() {
            return "userform"; 
        }
        
        // "/regist" URL에 대한 요청처리. post로 받은 user 데이터를 user dto에 매핑한다음 콘솔에 출력
        @RequestMapping(path="/regist", method=RequestMethod.POST)
        public String regist(@ModelAttribute User user) { // @ModelAttribute 을 dto앞에 붙여주면 스프링이 pos 데이터를 보고 알아서 값을 넣고 객체를 만들어 넘겨줌
    
            System.out.println("사용자가 입력한 user 정보입니다. 해당 정보를 이용하는 코드가 와야합니다.");
            System.out.println(user);
            return "regist";
        }
    }

    💾 User.java : user DTO

    더보기
    package kr.or.connect.mvcexam.dto;
    
    public class User { // getter, setter 메서드가 있어야 스프링 컨테이너가 객체의 필드를 사용할 수 있음.
        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 + "]";
        }   
    }

     


    ✔️ Spring MVC 실습 3

    ◾ http://localhost:8080/mvcexam/goods/{id} 으로 요청을 보낸다.

    ◾ 서버는 id를 콘솔에 출력하고, 사용자의 브라우저 정보를 콘솔에 출력한다.

    ◾ 서버는 HttpServletRequest를 이용해서 사용자가 요청한 PATH 정보를 콘솔에 출력한다. 

     

    💾 goodsById.jsp : path 값(id)하고 사용자 브라우저 정보를 보여주는 뷰

    더보기
    <%@ 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}") // {id} 형태로 path variable를 받겠다는 뜻
        public String getGoodsById(@PathVariable(name="id") int id, // 애노테이션을 이용해 pathVariable을 가져온다.!
                                   @RequestHeader(value="User-Agent", defaultValue="myBrowser") String userAgent, //애노테이션을 이용해 헤더 정보를 가져온다.
                                  HttpServletRequest request, // 이렇게 HttpServletReques 서블릿을 사용할 수도 있다.
                                  ModelMap model //ModelMap 객체를 사용해서 request scope에  값을 등록한다. 그 다음 goodsById.jsp 뷰에서 이 값을 화면에 보여준다. 
                                  ) {
            
            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";
        }
    }

    댓글

Designed by Tistory.