본문 바로가기
기술/Spring-Boot

@Controller는 뭘까?

by Zabee52 2021. 11. 26.

@Controller

스프링 입문자로써 아마 무작정 무언가 실습을 해보면서 기능들을 익혀나가는 경험을 다들 했을 것이다. 나도 이 단계에 속하는데, Controller 클래스에 @Controller 어노테이션을 붙이면 마법처럼 URL을 입력하면 이쪽으로 인도되고 작업이 처리되는 마법같은 경험을 하면서 편함을 느끼고 감사하다는 마음도 들지만 동시에 대체 뒤에서 무슨 일이 일어나고 있는 것인지 깊은 의문이 생기곤 한다. 코드 뒤에서 작은 난쟁이들이 뚝딱뚝딱 만들어주는 것은 아닐 것이지 않은가. 아 물론 엄밀히 따지자면 스프링이 해주고 있긴 한데.....

 

본론으로 들어가서, @Controller가 무슨 역할을 하는지 설명하려면, 먼저 @Controller가 없으면 우리가 이 기능을 구현하기 위해 무엇을 해야 하는가에 대해서 설명을 해야한다. 빠르게 간다. 잘 따라오세요.

솔직히 저는 잘해요. 근데 스프링이 제 템포를 견디지 못 해요.

스프링 부트의 @Controller가 없던 시절의 HTTP 통신은 어떻게 했냐면,

 

1. @WebServlet 어노테이션을 이용해 URL을 정의해준다.

2. 추상 클래스인 HttpServlet을 상속받는 Servlet Class를 작성한다.

@WebServlet(urlPatterns = "/api/search")
public class ItemSearchServlet extends HttpServlet {
	//...
}

3. HttpServlet 내부에 정의되어있는 알맞은 타입의 메소드를 override 한다. 

// GET, POST, PUT, DELETE 전부 들어있다.
public abstract class HttpServlet extends GenericServlet {

    // ...
    
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException{
         // ...
     }
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException {
		 // ...
    }
    
    // ...
 }

4. 요구사항에 따라 내용을 구현한다.

@WebServlet(urlPatterns = "/api/search")
public class ItemSearchServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String query = request.getParameter("query");
			
        // ...

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        String itemDtoListJson = objectMapper.writeValueAsString(itemDtoList);
        out.print(itemDtoListJson);
        out.flush();
    }
}

 

 

위와 같은 절차를 거치게 된다. 이렇게 작업을 하게 될 경우 몇 가지 불편한 점이 생기는데,

 

1. 하나의 페이지(@WebServlet)당 하나의 클래스를 반드시 생성해야 한다 : 관리해야 하는 파일이 많아진다.

2. 코드의 중복이 발생한다 : HttpServlet 상속받아야하고, doGet doPost doPut doDelete 메소드 오버라이드 해줘야하고, request 새로 정의하고 response 형식 정의해야하고.....

 

이런 생산성이 떨어지는 문제가 발생하기 때문에, 스프링부트는 반복되는 내용들을 한 방에 축약시켜서 선언시킬 수 있도록 해주었다.

 

@Controller
public class ItemSearchController {
    @GetMapping("/api/search")
    @ResponseBody
    public List<ItemDto> getItems(@RequestParam String query) throws IOException {
			
        // ...

        return itemDtoList;
    }
}

1. 하나의 클래스에 여러개의 페이지를 선언할 수 있게 되었고(@WebServlet -> @???Mapping)

2. 상속, override, 파라미터 재정의 등의 절차가 사라져 코드의 중복이 제거되었다.

 

 

이렇게, 편리하고 빠르면서 사용자가 어처구니없는 실수를 하게 되는 영역에 신경쓰지 않아도 되는 프로그래밍이 가능해진다.

그래서, @Controller가 무엇인가?에 대해서 간략하게 요약을 하자면,

 

1. 구성한 페이지를 보고 있는 사용자가 페이지 이동 또는 데이터를 받아오는 작업이 필요한 어떠한 것을 요청했을 때

2. 그 작업이 어떤 종류의 요청인지, 무엇을 해야하는 작업인지 판단하고 Service에 작업을 지시하는 컨트롤러가

3. 이전의 방식보다 더욱 편하고 직관적이게 프로그램을 작성할 수 있도록 도와주는 녀석이다.

 

라고 볼 수 있다.

 

 

 

이전 세대의 프로그래밍을 경험해본 적이 없기 때문에 추측만 해보자면, 아마 @WebServlet 역시 엄청나게 간소화된 기능일 것이다. 당시 개발자들도 엄청나게 편하다며 사용을 했겠지. 근데 이게 벌써 이전 세대의 기술이 되었다. 기술의 발전이 이렇게 무섭다. 나와 같은 신입 개발자에게 있어서 개발이 시간이 지남에 따라 이렇게 더더욱 간편해지는 것은 엄청나게 고마운 일일지도 모르겠지만, 결국 기존 개발자들 입장에서는 기능이 나온지 오랜 시간이 지나지도 않았는데 벌써 더욱 좋고 새로운 기능들이 자리를 꿰차며 자신의 영역을 넓혀나가고 있으니, 끊임없이 공부를 해야한다는 현실을 마주하게 만드는 요소가 될 것이다.

...라는 감정들을 어렴풋이나마 공감해볼 수 있는 부분이지 않을까 싶었다.

댓글