현실적인 개발자 로드맵(6) - Spring의 탄생

# 포스팅에서 사용된 코드의 전체 코드는 https://github.com/ITVillage-Kevin/roadmap-spring-mvc 에서 다운로드 받으실 수 있습니다.

# 해당 포스팅은 IT Village 유튜브 채널(https://www.youtube.com/channel/UCSIvsntWA8aJ3Apoc7kTxig)에서도 시청하실 수 있습니다.


안녕하세요, Kevin입니다. 

지난 시간까지 Ajax와 jQuery가 등장함으로 인해서 웹 애플리케이션 개발이 Front-end와 Back-end로 나누어 지기 시작했다고 말씀을 드렸는데요. 지난 시간에 Front-end쪽을 잠깐 살펴보았으니 이번 시간에는 Servlet에서 멈춰 있는 Back-end 쪽의 기술의 변화를 다시 살펴 보도록 하겠습니다.

Servlet을 사용하여 Back-end쪽을 불편하고 복잡하게 개발을 하던 시절의 무렵, 혜성 같이 등장한 구원투수가 있었으니 그것은 바로 Spring이라는 놈이었습니다. 마치 야근을 밥 먹듯이 하는 개발자들에게 봄날이 오길 바라는 마음에서 였을까 아무튼 자바 개발자들에게 Spring은 봄(spring)이 오듯이 찾아왔습니다. ^^;

Java 웹 개발의 이전과 이후는 Spring을 기준으로 나뉘어 진다고해도 과언이 아니라고 볼 수 있습니다. 마치 예능 프로그램이 무한도전 이전과 이후로 나뉜다고 볼 수 있는것 처럼 말이죠. ^^

아무튼 Spring이라는 프레임워크가 등장한 이후로 웹 애플리케이션을 개발에 있어서 커다란 변화가 생겼음은 Java 개발자라면 누구나 부정할 수 없을것이라고 봅니다. 

Spring 1.0 버전이 2004년에 나온것으로 알고 있는데 저는 개인적으로 2009년에 Spring 2.5를 처음 접하게 되었습니다.

2018년 10월 현재 Spring 5 버전이 나오면서 Spring 프레임워크의 기술에도 많은 변화가 있었으나 IOC, DI, AOP 같은 Spring의 근본 기술들은 Spring의 핵심 기술로 변함없이 자리를 지키고 있습니다.

이 포스팅은 Spring에 대한 구체적인 사용방법 등에 대해서 이야기를 하는것이 아니기때문에 Spring에 대한 이야기들은 추후에 다시 포스팅할 수 있는 기회가 있었으면 좋겠습니다.

Java 개발자 로드맵에 이미 Spring이 추가가 될 것이라는 결론은 난 셈이 되지만 그래도 이대로 글을 마치게되면 너무 싱거우니 여태까지 해온대로 이전 포스팅에서 Servlet 기반으로 구현했던 TODO 애플리케이션을 Spring 프레임워크를 사용하여 개선을 해보도록 하겠습니다. Servlet 기반의 TODO 애플리케이션 구현에 대한 상세한 내용은 아래 포스팅을 참고해주세요.

2018/09/07 - [현실적인 개발자 로드맵] - 현실적인 개발자 로드맵(3) - JSP 모델2


자, 그럼 결론적으로 Servlet으로 구현한 TODO 애플리케이션의 Servlet 코드와 Spring으로 구현한 Spring Controller의 코드를 비교해서 잠깐 살펴보겠습니다. 아래는 TodoAjaxServlet의 코드입니다.

==== ToDoAjaxServlet.java ====

package com.itvillage.servlet;

import com.google.gson.Gson;
import com.itvillage.vo.ToDo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet(name = "ToDoAjaxServlet", value = "/todoAjax")
public class ToDoAjaxServlet extends HttpServlet {
// Database를 대신한다.
private List<ToDo> todoList;

@Override
public void init() throws ServletException {
super.init();
this.todoList = new ArrayList<>();
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

String todoName = request.getParameter("todoName");
String todoDate = request.getParameter("todoDate");

todoList.add(new ToDo(todoName, todoDate));

Gson gson = new Gson();
String json = gson.toJson(todoList);

response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");
response.getWriter().write(json);

}
}


다음은 Spring으로 구현한 ToDoController입니다.

==== ToDoController.java ====

package com.itvillage;

import com.itvillage.vo.ToDo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;

@Controller
public class ToDoController {
@RequestMapping(value = "/todoAjax", method = RequestMethod.POST)
@ResponseBody
public List<ToDo> todoAjax(@RequestParam("todoName")String todoName,
@RequestParam("todoDate")String todoDate) {
ToDo.todoList.add(new ToDo(todoName, todoDate));
return ToDo.todoList;
}
}


ToDoAjaxServlet 클래스의 doPost() 메서드와 ToDoController 클래스의 todoAjax() 메서드는 클라이언트측으로부터 Ajax 요청을 처리하는 메서드인데요. 일단 눈으로 보이는 소스 코드의 길이만 봐도 ToDoController의 todoAjax() 메서드가 확연히 짧고 간결한것이 보이시죠?

ToDoAjaxSevlet의 doPost()에서는 캐릭터 셋 설정이나 JSON으로의 포맷팅 설정, response의 설정까지 직접 해주어야 했으나 ToDoController의 todoAjax() 메서드에는 그런 설정들이 전혀 없습니다. 

Spring 설정파일에 별도의 설정을 하긴 하지만 구현 코드상에서는 모두 제거되어 Servlet 보다 실제로 깔끔한 소스 코드를 유지하는것이 가능해졌습니다.

사실 왜 Spring을 사용하여야 되는지에 대해서 구체적으로 설명하려면 저는 내일 출근을 못합니다.^^; 

Spring에 대해서는 다음에 더 많은 얘기를 나눌 수 있는 기회가 있을것이라고 생각을 하고, 우선 지금은 이것 하나만 기억하시면 되겠습니다.

Spring은 Java 개발자가 되기 위해서 반드시 알아야되는 핵심 기술중에 하나이다 라는것을 말이죠.


자, 이미 앞에서 이미 다 결론이 난 상태이지만 그래도 로드맵을 정리하는 차원에서 다시 한번 로드맵을 그려보면 다음과 같습니다.

[Spring 프레임워크가 추가된 개발자 로드맵]


짠~ 예상했던대로 Spring 프레임워크가 개발자 로드맵에 추가가 되었습니다.^^;


Spring에 대해서는 몇십번을 강조해도 지나치지 않을만큼 Java 개발자가 되기위해서 필수적으로 알아야 되는 기술입니다. 

더 정확하게 말하자면 Spring을 몰라도 당연히 Java 개발자가 될 수 있지만 조금 더 스마트하고 미래지향적인 Java 개발자가 되기위해서는 배워야 될 기술입니다.


이렇게 Spring에 대한 칭찬만 하다가 끝나도 사실 상관은 없지만 그래도 Spring에 대한 단점에 대해서 언급은 하고 가는것이 맞는거 같아 제가 Spring을 처음 접하면서 겪었던 불편함을 잠시 말씀드리겠습니다.

처음 Spring을 접하면서 가장 불편했던점은 바로 Spring의 개발 환경을 구축하는것이었습니다. 

Spring의 기술을 사용하기 위해서 해야되는 설정이 생각보다 복잡했고, Spring에 대한 근본 지식이 없는 상태에서 설정을 하다가 에러를 만나게 되면 해결하는것이 그리 만만치 않았다는 것입니다.

이번 포스팅을 위해서 오랜만에 Spring 개발 환경 설정을 해보았는데 역시나 설정하는데 오래 걸리더군요. 보통 밤 12시 전에 잠을 자는데 설정하고 정상적으로 동작하는지 확인하느라 12시를 넘겨버리고 말았습니다. ^^;


그럼 Spring 프레임워크를 사용하여 개발하는데 있어서 어떤 설정을 해주어야 하는지에 대해서 간단하게만 말씀 드리고 이번 포스팅을 마치도록 하겠습니다.

==== dispatcher-servlet.xml ===



    
        
            
        
    
    


    
        
        
    

dispatcher-servlet.xml에는 웹 프리젠테이션 계층의 빈(Bean)을 등록하는 설정 파일입니다. ToDo 애플리케이션의 경우 샘플 애플리케이션이다 보니 많은 빈(Bean)이 등록되지 않았으나 애플리케이션의 기능이 늘어날수록 빈 설정의 수는 늘어날 것입니다. 현재는 응답 데이터를 JSON으로 변환해주는 Converter와 JSP 뷰를 리졸빙해주는 Resolver만 설정되어 있습니다.

==== web.xml ====



    
        contextConfigLocation
        /WEB-INF/spring-config/applicationContext.xml
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
        dispatcher
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            /WEB-INF/spring-config/dispatcher-servlet.xml
        
        1
    
    
        dispatcher
        /
    
    
        CORSFilter
        com.itvillage.filter.CORSFilter
    
    
        CORSFilter
        /*
    


Servlet 사용 시 필요한 web.xml 파일에 Spring 연동을 위한 설정들이 추가로 포함되었습니다. ContextLoaderListener를 통해 Root Web Application Context를 등록하고, 앞서 보았던 dispatcher-servlet.xml 파일의 경로를 추가함으로써 Servlet Web Application Context를 등록하였습니다. 그리고 추가적으로 CORS(Cross Origin Resource Sharing) 문제를 해결하기 위해서 Filter 설정이 포함되었습니다. 

이 포스팅에서는 이런 설정들이 정확하게 무엇을 하는지 몰라도 상관없습니다. 이런 설정들을 해야지만 Spring을 사용할 수 있다라는 정도만 알고 계시면 될것 같습니다.


설정이 간단해 보이지만 직접 한번 해보시면 다양한 에러를 만나실 수 도 있을것입니다. ^^; 제 경우는 Spring 설정 + IDE 설정 + CORS 문제 등등으로 시간이 좀 걸렸습니다.


아무튼 Spring의 이런 설정상의 불편함때문에 개발자들이 정작 핵심 개발에 집중을 하지 못하고 Spring 설정에서부터 벽에 부딪치는 경우도 종종 있다고 알고 있는데요. 아시는 분들은 아시겠지만 이런 불편함이 추후에 개선이 되었더랬죠.

이 부분에 대해서는 다음 시간에 말씀을 드리도록하고, 오늘은 이만 여기서 포스팅을 마무리해야겠습니다. 그럼 다음 시간에 다시 찾아뵐게요~


[Kevin의 알기 쉬운 Java 개발자 로드맵 이야기] 인프런 강의 바로가기


현실적인 개발자 로드맵 - jQuery의 등장

# 포스팅에서 사용된 코드의 전체 코드는 https://github.com/ITVillage-Kevin/roadmap-front-javascript 에서 다운로드 받으실 수 있습니다.

# 해당 포스팅은 IT Village 유튜브 채널(https://www.youtube.com/channel/UCSIvsntWA8aJ3Apoc7kTxig)에서도 시청하실 수 있습니다.



안녕하세요, Kevin입니다. 추석을 앞두고 비가 오더니 집에 올때 쯤 그쳤네요. 오늘은 조금 일찍 퇴근해서 이렇게 글을 적고 있습니다. 오늘도 아직 끝나지 않은 개발자 로드맵에 관한 이야기를 해볼까 합니다.
지난 시간에는 Ajax 기술이 등장함으로 인해서 Front-end와 Back-end가 나누어지는 기술의 추세를 잠깐 언급을 했었는데요.

제가 Ajax 기술을 처음으로 접했던게 2007년이었던가 2008년 이었던가 아무튼 오래되서 기억이 가물 가물한데 아무튼 제 기억으로는 Ajax 기술을 처음 접한 이후, 오래지 않아서 순수 자바스크립트 Ajax 기술의 복잡함을 단순화 시킬 수 있는 기술이 등장을 하게됩니다. 

그것은 바로.. jQuery입니다. 두둥~ 

처음 jQuery를 접했을땐 조금 충격적이었습니다. 그 당시만해도 자바스크립트는 이해하기 쉽지 않은 언어였었고, 자바스크립트 Ajax 통신을 통해서 가져온 데이터를 이용하여 DOM을 조작해서 UI를 업데이트 하는것이 결코 쉬운 작업이 아니었습니다. 자바스크립트로 그런 복잡한 작업을 하다가 jQuery를 사용하여 똑같은 작업을 하면서 어떻게 이렇게 간결하게 작성할 수 있을까라며 놀라움을 금하지 못하던 때가 분명히 있었네요. ^^;

그럼 지난 시간에 순수 자바 스크립트 Ajax 기술을 사용해서 서버와 통신을 하던 부분을 jQuery로 똑같은 기능을 하도록 작성을 해보겠습니다.

먼저 순수 자바 스크립트로 작성한 것을 다시 한번 보도록 하겠습니다.

        function registerTodo(){
            var todoName = document.getElementById("todoName").value;
            var todoDate = document.getElementById("todoDate").value;

            if(!todoName){
                alert("할일을 입력해주세요.");
                return false;
            }

            if(!todoDate){
                alert("날짜를 입력해주세요.");
                return false;
            }

            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://localhost:8080/todoAjax', true);
            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

            xhr.onload = function(){
                if(xhr.status == 200 || xhr.status == 201){

                    // 화면에 반영
                    var todoList = JSON.parse(xhr.responseText);
                    var html = "";
                    for (var i in todoList) {
                        var todo = todoList[i];
                        html += '' + todo.todoName + '' + todo.todoDate + '';
                    }
                    var todoContents = document.getElementById("todoContents");
                    todoContents.innerHTML = '';
                    todoContents.innerHTML = html;
                }else{
                    // 에러 처리
                }
            };
            xhr.send('todoName=' + todoName + '&todoDate=' + todoDate);
        }


15번 라인에서 36번 라인까지가 자바스크립트 Ajax 기술을 사용하여 서버와 데이터를 주고 받는 부분인데요. 소스 코드 자체가 복잡해보이는건 어쩔 수 없습니다. 
그럼 이제 위 소스코드를 jQuery로 다시 한번 구현을 해보도록 하겠습니다. jQuery로 구현한 코드는 아래와 같습니다.
$(document).ready(function(){
   $("#btnReg").click(function(){
       var todoName = $("#todoName").val();
       var todoDate = $("#todoDate").val();

       if(!todoName){
           alert("할일을 입력해주세요.");
           return false;
       }

       if(!todoDate){
           alert("날짜를 입력해주세요.");
           return false;
       }

       $.post("http://localhost:8080/todoAjax", {
           todoName: todoName,
           todoDate: todoDate
       }, function(todoList) {
           var contents = "";
           for (var i in todoList) {
               var todo = todoList[i];
               contents += '' + todo.todoName + '' + todo.todoDate + '';
           }

           $("#todoContents").html(contents);
       }, 'json');
   });
});

저희의 TODO 프로젝트 UI가 단순하다보니 UI쪽 코드는 코드 길이도 그렇게 차이나지 않고 복잡함에 있어서도 별 차이가 나지 않네요. 하지만 Ajax 통신하는 부분을 한번 보십시요. 소스 코드 길이도 물론 반으로 줄었고, 한눈에 봐도 되게 단순해 보이지 않나요?

하지만 이렇게 승승장구 할것만 같았던 jQuery도 세월이 흐르면서 서서히 한계를 드러내기 시작을 했더랬습니다. 그 이야기는 나중에 다시 하도록하고, 어쨌든 오늘은 보시면 아시겠지만 저희가 개선한 코드를 통해 추출할 수 있는 기술은 딱 한가지입니다. 

바로 jQuery이지요. jQuery의 사용 빈도가 점점 줄어들고 있는건 사실이긴하지만 그래도 한국에서는 여전히 많이 사용되고 있는 기술중에 하나이기때문에 익혀두는것이 결코 나쁘지는 않습니다. jQuery 자체가 간결함을 지향하는 기술이기 때문에 학습 곡선 역시도 크게 가파르지 않으므로 조금만 시간 투자를 하시면 금방 익숙하게 사용하실 수 있을거라고 생각합니다.


자, 그럼 오늘 추출한 기술을 포함한 지금까지의 로드맵을 마인드 맵으로 한번 그려 볼까요?

[jQuery 기술이 추가된 개발자 로드맵]


기술이 점점 늘어가고 있군요. ^^

이번 시간까지는 Front-end쪽의 기술의 변화를 살펴봤으니 다음 시간에는 다시  Back-end쪽의 기술의 변화를 살펴보도록 하겠습니다. 

선선한 가을 바람이 부는 금요일 밤인데 저는 잠깐 조깅을 하러 나가봐야겠습니다. 추석 연휴 잘들 보내시길 Kevin이 진심으로 기원하겠습니다. 다음 시간에 뵐게요~



현실적인 개발자 로드맵 - Ajax의 등장

# 포스팅에서 사용된 코드의 전체 코드는 https://github.com/ITVillage-Kevin/roadmap-front-javascript 에서 다운로드 받으실 수 있습니다.

# 해당 포스팅은 IT Village 유튜브 채널(https://www.youtube.com/channel/UCSIvsntWA8aJ3Apoc7kTxig)에서도 시청하실 수 있습니다.


안녕하세요, 오늘도 여전히 금요일 저녁에 찾아뵙네요. 평일엔 일 하느라 바빠서 포스팅을 할 수 없어서 금요일만 되면 포스팅 할 수 있다는 설레는 마음으로 이렇게 컴퓨터 앞에 앉아있습니다. ^^;

자, 그럼 지난 시간에 이어서 개발자 로드맵에 대해서 계속 이야기 해볼까요?

지난 시간에는 JSP 모델1을 개선한 모델2까지에서 추출한 로드맵을 그려보았습니다. 바로 아래와 같죠?


[JSP 모델2 방식에서 추가된 개발자 로드맵]


자, 그런데 JSP를 사용해보신 분들이라면 다들 알고 계시겠지만 JSP에는 한가지 문제점이 있습니다. 사실 문제점이라기 보다는 JSP 등의 서버 사이드 언어를 사용하면 당연시 여기던 것이었는데요. 저희는 아래와 같은 TODO 애플리케이션을 만들고 있습니다.


[TODO 애플리케이션]


그림과 같이 할일과 날짜를 입력한 후 [등록] 버튼을 클릭하게 되면 할일 데이터를 서버로 전송하게 되는데요. 이때 화면이 깜빡 거리는것을 볼 수 있습니다. 깜빡임의 이유는 [등록] 버튼을 클릭하게 되면 서버에 데이터를 전송한 후, 서버에서 todo_model1.jsp로 다시 포워딩을 시키면서 화면이 바뀌게 되기 때문입니다. 이해 되셨죠? 

TODO 애플리케이션의 경우 서버에서 처리하는 시간이 얼마 되지 않기 때문에 잠시 깜빡거리겠지만 실무에서 많은 데이터를 처리할 경우에는 [등록] 버튼을 누른후에도 한참을 화면이 바뀌지 않거나 화면이 바뀌고 난 후에 서버에서 처리가 끝날때까지 브라우저에서 한참 동안 흰색 화면만 표시되는 경우도 있다는걸 아시는분들은 아실겁니다.

이렇게 페이지 전체를 refresh 하게되면 사용자들은 서버의 처리가 끝날때까지 아무것도 하지 못한채 기다려야 하죠. 이런 문제점을 개선하기 위해서 나온 기술이 바로 Ajax(Asynchronous Javascript and XML) 기술입니다. 

Ajax 기술을 통해 페이지 전체를 refresh 하지 않고, 페이지의 일부분에 표시되는 데이터를 서버측으로 부터 받아서 화면의 깜빡임 없이 데이터를 갱신하는것이죠. Ajax 기술로 인해 페이지의 특정 부분의 데이터 또는 UI만 갱신 되므로 페이지 전체가 refresh 될때까지 기다릴 필요가 없게 되었습니다. 

JSP가 처음 등장할 당시 클라이언트측에 표시되는 UI 화면을 구성하는 HTML + Javascript + CSS 소스코드들이 서버측 소스들과 함께 서버측에 위치하는 경우가 많았는데 Ajax 기술이 등장함으로 인해서 슬슬 HTML + Javascript + CSS 등의 소스 코드들은 웹서버에 위치시키고 서버측에는 순수하게 서버측 언어로 구성된 소스 코드들만 위치 시키는 소위 말하는 Front-end와 Back-end로 역할 구분을 하게됩니다.

자기 역할에 충실할 수 있도록 구성되는것은 어찌보면 너무나 당연한것이라고 볼 수 있는건데 말이죠. 

자, 그럼  HTML + Javascript + CSS로 구성된 Front-end 의 소스 코드를 보시겠습니다. Back-end 소스 코드는 여전히 서블릿으로 구성되어 있으므로 손대지 않겠습니다.

 
    
    Todo List
    
    


    

TO DO 등록

TO DO List

todo nametodo date
할 일이 없습니다.

[front_javascript.html]

26번 라인부터 45번 라인까지가 Ajax 기술을 이용해 Back-end 쪽에 할일 데이터를 전송하고 응답으로 할일 목록 데이터를 전송 받는 부분입니다. 조금 복잡해 보이지 않나요? 

어쨌든 여기서 저희는 로드맵에 하나의 기술을 더 추가할 수 있게되었네요.^^ 바로 아래와 같겠죠?

[Ajax 기술이 추가된 개발자 로드맵]


개발자 로드맵에 Ajax 기술이 추가되었습니다. ^^; 

사실 요즘에는 Javascript로 Ajax 기술을 직접적으로 사용하는일은 많지 않습니다. 소스 코드를 보시면 아시겠지만 처음 보는 분들한테는 소스코드가 결코 단순하지는 않습니다. 

그럼에도 불구하고 Ajax 기술을 로드맵에 포함시킨것은 순수 Javascript의 Ajax 기술을 사용하라는 의미는 아니고 최소한 Ajax의 원리는 이해를 해야한다는 의미에서 로드맵에 포함을 시킨거였습니다.

그럼, 다음 시간에는 순수 Javascript의 Ajax 기술의 복잡함을 극복하도록 Front-end 측 소스 코드를 개선해 보도록 하겠습니다.

모두들 즐거운 불금 보내시고 저는 이만 다른 공부를 좀 해야겠습니다. 그럼 다음시간에 뵐게요~






현실적인 개발자 로드맵 - JSP 모델2

# 포스팅에서 사용된 코드의 전체 코드는 https://github.com/ITVillage-Kevin/roadmap-jsp 에서 다운로드 받으실 수 있습니다.

# 해당 포스팅은 IT Village 유튜브 채널(https://www.youtube.com/channel/UCSIvsntWA8aJ3Apoc7kTxig)에서도 시청하실 수 있습니다.


안녕하세요, Kevin입니다. 지난 시리즈에 이어 개발자 로드맵 이야기를 계속 해보겠습니다. 지난 시간에 어떤 이야기를 했는지 기억나시나요?^^ 지난 시간에는 Java 개발자로 입문하면서 필수적으로 배워야 할 것들이 무엇인지 JSP Model1 방식으로 구현한 TO DO 애플리케이션을 통해서 알아보았습니다. 지난 시간까지 알아본 바로는 아래와 같은 기술들을 배워야 한다고 했죠?


[JSP 모델1 방식에서 추출한 기술]


자, 그럼 오늘은 JSP Model1 방식으로 만든 TODO 애플리케이션을 조금 더 개선 해보면서 어떤 기술들을 더 알아야하는지 알아보겠습니다.


클라이언트 + 서버 통합(JSP 모델2)

지난 시간과 비슷하게 오늘은 JSP 모델2 방식의 구성도를 먼저 보도록 하겠습니다.

[JSP 모델2 구성도]


JSP 모델1의 구성도와 어떤 차이가 있는지 느껴지시나요? 모델1의 경우 JSP에서 클라이언트의 요청을 직접 받고 클라이언트에게 응답으로 돌려줄 View 까지 생성했더랬습니다. 그야말로 JSP가 모든 일을 다 하는거라고 보시면 됩니다. 그렇기 때문에 소스 코드 상에서도 요청을 처리하는 Java 코드가 뷰를 구성하는 JSP 코드에 구현 되어 있는것을 보실 수 있었는데요.


모델1에서 요청을 처리하는 코드와 뷰를 구성하는 코드가 JSP에 모두 구성되어 있는 반면에 JSP 모델2 방식은  Servlet이라는 자바 클래스가 요청을 받아서 뷰에 표시될 데이터들만 JSP에게 넘겨 주고, JSP는 이 데이터들을 HTML 코드에 잘 보이도록 적절하게 랜더링한 후, 클라이언트에게 넘겨줍니다. 


한마디로 말해서 각자의 할 일은 각자 하자는 구성 방식이라고 볼 수 있습니다. 요청을 처리하는 역할은 Servlet이 맡고 , JSP는 뷰로써의 역할만 하자는 역할 분리가 이루어진셈입니다.


실제 코드를 보면 조금 더 이해 하시기 쉬울겁니다. 소스 코드를 한번 볼까요?

==== web.xml ====

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>To Do JSP</display-name>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>Todo</servlet-name>
<servlet-class>com.itvillage.servlet.TodoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Todo</servlet-name>
<url-pattern>/todo</url-pattern>
</servlet-mapping>
</web-app>

모델2 방식에서는 클라이언트의 요청을 처리하게 되는 Servlet 설정 정보를 위와 같이 web.xml에 설정해주어야합니다. 이렇게 Servlet 클래스와 URL의 매핑을 해주어야지만 클라이언트에서 /todo URL로 요청을 보냈을때 /todo URL에 매핑되는 TodoServlet 클래스가 요청을 처리할 수 있습니다.


==== ToDoServlet ====

package com.itvillage.servlet;

import com.itvillage.vo.ToDo;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebServlet(name = "TodoServlet")
public class TodoServlet extends HttpServlet {
// Database를 대신한다.
private List<ToDo> todoList;

@Override
public void init() throws ServletException {
super.init();
this.todoList = new ArrayList<>();
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

System.out.println("Hello Servlet doPost!");

String todoName = request.getParameter("todoName");
String todoDate = request.getParameter("todoDate");

todoList.add(new ToDo(todoName, todoDate));

RequestDispatcher dispatcher =
request.getRequestDispatcher("/todo_model2.jsp");
request.setAttribute("todoList", todoList);

dispatcher.forward(request, response);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("Hello Servlet doGet!");

RequestDispatcher dispatcher =
request.getRequestDispatcher("/todo_model2.jsp");
request.setAttribute("todoList", todoList);
dispatcher.forward(request, response);
}
}

클라이언트에게서 받은 요청을 처리하는 TodoServlet 클래스입니다. doPost()에서 할 일을 등록한 후, 등록된 할 일 데이터를 JSP로 넘겨주고 doGet()에서는 단순히 등록된 할일을 JSP로 넘겨줍니다. 

doPost() 안에 있는 소스 코드들은 이전 시간에 봤던 모델1 방식에서 result_model1.jsp 안에 포함되어 있던 코드들인데 이렇게 TodoServlet 클래스 안으로 분리되었습니다.


==== todo_model2.jsp ====

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<meta http-equiv="Content-Language" content="ko"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

<title>TODO 등록</title>
<style>
#todoList {
border: 1px solid #8F8F8F;
width: 500px;
border-collapse: collapse;
}

th, td {
padding: 5px;
border: 1px solid #8F8F8F;
}
</style>
<script>
function registerTodo(){
var todoName = document.getElementById("todoName").value;
var todoDate = document.getElementById("todoDate").value;

if(!todoName){
alert("할일을 입력해주세요.");
return false;
}
if(!todoDate){
alert("날짜를 입력해주세요.");
return false;
}

var form = document.getElementById("todoForm");
form.submit();

}
</script>
</head>
<body>
<h3>TO DO 등록</h3>
<div>
<form id="todoForm" method="POST" action="/todo">
<input type="text" name="todoName" id="todoName" value=""/>
<input type="date" name="todoDate" id="todoDate" value=""/>
<input type="button" id="btnReg" value="등록" onclick="registerTodo()"/>
</form>
</div>
<div>
<h4>TO DO List</h4>
<table id="todoList">
<thead>
<tr>
<td align="center">todo name</td>
<td align="center">todo date</td>
</tr>
</thead>

<tbody>
<c:choose>
<c:when test="${fn:length(todoList) == 0}">
<tr>
<td align="center" colspan="2">할 일이 없습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${todoList}" var="todo">
<tr>
<td>${todo.todoName}</td>
<td align="center">${todo.todoDate}</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</tbody>
</table>
</div>
</body>
</html>

todo_model2.jsp는 todo_model1.jsp와 변한게 없으므로 넘어가겠습니다.


자, 그럼 지난 시간과 마찬가지로 이번에도 우리가 배워야 할 기술들을 추출해 보겠습니다. 눈치채신 분도 계시겠지만 이번 시간에 변화 된것은 딱 한가지 밖에 없습니다. 바로 Servlet입니다. 저희가 배워야 될 기술에 Servlet만 포함시키면 됩니다. 

"오래된 방식인데 꼭 배워야 해?"라고 말씀하시는 분들이 많겠지만 일단 포함을 시켜보겠습니다. Servlet이 포함된 추가된 로드맵은 다음과 같겠죠?


[JSP 모델2 방식에서 추가된 개발자 로드맵]



자, 그럼 Servlet은 과연 배워야 할까요? Servlet을 사용하고 있는 회사라면 당연히 배워야됩니다. 하지만 아직도 Servlet을 사용하고 있는 기업이라면.. 음.. 저 멀리 아주 멀리, 시대에 동 떨어진 회사라고 봐도 될 것 같습니다. 

Servlet을 여전히 메인 방식으로 사용하고 있는 회사라면 과감하게 입사를 포기하든가 아니면 입사하셔서 여러분이 직접 회사를 바꾸시면 되겠습니다. ^^; 


오늘은 이쯤에서 포스팅을 마치기로 하고, 다음 시간에는 오늘 포스팅 한 소스 코드를 살짝만 더 개선해보도록 하겠습니다.


그럼 좋은 주말 보내세요~



+ Recent posts

출처: http://large.tistory.com/23 [Large]