스프링 프레임워크/스프링 기본 개념 정리 및 기본 예제

Spring MVC - Controller 작성 연습

edenDev 2023. 2. 13.

본 포스팅의 예제는 STS(Spring Tool Studio) 또는 Eclipse를 사용하지 않고 intellij를  통해 구현하고 있습니다.

그래서 기존의 생성된 STS(Spring Tool Studio) 생성된 Spring 프로젝트의 스프링 설정 파일명과 프로젝트 구조가

약간 다를 수 있습니다. Intellij 스프링 mvc 프로젝트 생성 포스팅을 참고해주시면 감사하겠습니다.


이번에는 Controller에서 가장 빈번하게 사용하는 5가지의 경우를 통해 Controller를 작성하는 방법을 연습해보고, 작성한 Controller를 WAS 없이 테스트 해보도록 하겠습니다.


1. void 리턴 타입인 경우

VoidController 을 아래와 같이 작성해주세요

@Controller
public class VoidController {

    private static final Logger logger = LoggerFactory.getLogger(VoidController.class);

    @RequestMapping("/doA")
    public void doA() {
        logger.info("/doA called...");
    }

    @RequestMapping("/doB")
    public void doB() {
        logger.info("/doB called...");
    }
}

/doA, /doB 요청 시 브라우저와 콘솔 화면


2. String 리턴 타입인 경우

StringController 을 아래와 같이 작성해주세요.

@Controller
public class StringController {
    private static final Logger logger = LoggerFactory.getLogger(StringController.class);
    @RequestMapping("/doC")
    public String doC(@ModelAttribute("msg") String msg) {
        logger.info("/doC called");
        return "tutorial/result";
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Sting Controller Test</title>
</head>
<body>
<span>Hello ${msg}</span>
</body>
</html>

/doC 요청시 브라우저와 콘솔 화면 확인


3. 만들어진 결과 데이터를 View에 전달할 경우

ValueController 을 아래와 같이 작성해주세요.

@Controller
public class ValueController {

    private static final Logger logger = LoggerFactory.getLogger(ValueController.class);

    @RequestMapping("/doD")
    public String doD(Model model) {

        TestVO testVO = new TestVO("desktop", 10000);
        model.addAttribute(testVO);

        logger.info("/doD called");
        return "tutorial/test_detail";
    }
}

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Value Controller Test</title>
</head>
<body>
    <span>${testVO.name}</span>
    <span>${testVO.price}</span>
</body>
</html>

/doD 요청시 브라우저와 콘솔화면 확인


4. redirect를 해야할 경우

RedirectController를 아래와 같이 작성해주세요.

@Controller
public class RedirectController {

    private static final Logger logger = LoggerFactory.getLogger(ValueController.class);

    @RequestMapping("/doE")
    public String doE(RedirectAttributes redirectAttributes) {
        logger.info("/doE called and redirect to /doF");
        redirectAttributes.addAttribute("msg", "this is the message with redirected");

        return "redirect:./doF";
    }

    @RequestMapping("/doF")
    public void doF(@ModelAttribute("msg") String msg) {

        logger.info("/doF called" + msg);
    }
}

/doE  요청 시 브라우저와 콘솔화면 확인


5. JSON 데이터를 생성하는 경우

JsonController 을 아래와 같이 작성해주세요

@Controller
public class JsonController {

    private static final Logger logger = LoggerFactory.getLogger(ValueController.class);

    @RequestMapping("/doJson")
    @ResponseBody
    public TestVO doJson() {
        TestVO testVO = new TestVO("가격", 1000);

        return testVO;
    }
}

/doJson 요청시 브라우저와 콘솔 화면 확인


6. WAS없이 Controller 테스트

이번에는 spring-test 모듈을 통해 별도의 WAS 구동없이 컨트롤러를 테스트를 해보자. Spring 3.2 버전부터는 jUnit만을 사용하여 Spring MVC에서 작성된 컨트롤러를 테스트 할 수 있었는데, WAS에서 테스트를 하는 것이 어려울 경우 아주 유용하게 사용 할 수 있습니다.

 

pom.xml : 테스트 진행을 위해 javax.servlet 라이브러리 버전 변경

 

● 기존의 라이브러리

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

 

● 버전을 변경한 라이브러리

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

테스트를 위한 코드는 아래와 같이 작성해줍니다.

 

 

testDoA()

INFO : com.eden.sample.ControllerTest - setup...
INFO : com.eden.sample.controller.VoidController - /doA called...

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /doA
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.eden.sample.controller.VoidController
           Method = com.eden.sample.controller.VoidController#doA()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = doA
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en"]
     Content type = null
             Body = 
    Forwarded URL = /WEB-INF/views/doA.jsp
   Redirected URL = null
          Cookies = []

testDoB()

INFO : com.eden.sample.TestController - setup...
INFO : com.eden.sample.controller.VoidController - /doB called...

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /doB
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.eden.sample.controller.VoidController
           Method = com.eden.sample.controller.VoidController#doB()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = doB
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en"]
     Content type = null
             Body = 
    Forwarded URL = /WEB-INF/views/doB.jsp
   Redirected URL = null
          Cookies = []

testDoC()

INFO : com.eden.sample.TestController - setup...
INFO : com.eden.sample.controller.StringController - /doC called

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /doC
       Parameters = {msg=[world]}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.eden.sample.controller.StringController
           Method = com.eden.sample.controller.StringController#doC(String)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = tutorial/result
             View = null
        Attribute = msg
            value = world
           errors = []

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en"]
     Content type = null
             Body = 
    Forwarded URL = /WEB-INF/views/tutorial/result.jsp
   Redirected URL = null
          Cookies = []

testDoD()

INFO : com.eden.sample.TestController - setup...
INFO : com.eden.sample.controller.ValueController - /doD called

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /doD
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.eden.sample.controller.ValueController
           Method = com.eden.sample.controller.ValueController#doD(Model)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = tutorial/test_detail
             View = null
        Attribute = testVO
            value = TestVO{name='desktop', price=10000.0}
           errors = []

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en"]
     Content type = null
             Body = 
    Forwarded URL = /WEB-INF/views/tutorial/test_detail.jsp
   Redirected URL = null
          Cookies = []

 

testDoE()

INFO : com.eden.sample.TestController - setup...
INFO : com.eden.sample.controller.ValueController - /doE called and redirect to /doF

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /doE
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.eden.sample.controller.RedirectController
           Method = com.eden.sample.controller.RedirectController#doE(RedirectAttributes)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = redirect:/doF
             View = null
        Attribute = msg
            value = this is the message with redirected

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 302
    Error message = null
          Headers = [Content-Language:"en", Location:"/doF?msg=this+is+the+message+with+redirected"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = /doF?msg=this+is+the+message+with+redirected
          Cookies = []

 

testDoJson()

INFO : com.eden.sample.TestController - setup...

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /doJson
       Parameters = {}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.eden.sample.controller.JsonController
           Method = com.eden.sample.controller.JsonController#doJson()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"name":"laptop","price":3000000.0}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

x테스트 코드를 작성하고 테스트를 하는 것의 장점

  • 웹페이지를 테스트 하려면 매번 입력 항목을 입력해서 제대로 동작하는지 확인하는데, 여러번 웹 페이지를 입력하는 것 보다 테스트 코드를 통해 처리하는 것이 개발 시간을 단축 할 수 있습니다.
  • JSP등에서 발생하는 에러를 해결하는 과정에서 매번 WAS에 만들어진 Controller 코드를 수정해서 배포하는 작업은 많은 시간을 소요 하므로 테스트 코드를 이용해서 수정 하는 것이 시간을 단축 할 수 있습니다.
  • Controller 에서 결과 데이터만을 확인할 수 있기 때문에 문제 발생시 원인을 파악하는 시간이 절약 됩니다.

댓글