상세 컨텐츠

본문 제목

6. HTML을 작성하기가 너무 불편하다.

Tech - 웹 개론

by Nested World 2021. 10. 22. 15:00

본문

Spring MVC

이제 충분히 쓸만하도록 서버 개발 환경을 구성했다. 사실, 이미 누군가 이렇게 해 두었고, 그것을 Spring 프레임워크라고 부른다. 프레임워크는 게임 엔진과 비슷한 역할을 한다. 게임 엔진은 어렵고 복잡한 그래픽스 연산을 대신 해서 랜더링을 책임지고, 빌드환경을 제공하며, Update같은 프레임단위 콜백 메소드를 제공해서 개발자가 오로지 게임 컨텐츠에만 집중할 수 있게 한다. 웹 개발에도 이런 것이 있는데, 웹 개발의 '엔진'이라 할 수 있는 것이 바로 Spring 프레임워크다.

Spring프레임워크를 사용해 보았다면 알고 있겠지만, 여기서는 웹 서비스를 제공하기 위해 기본적으로 앞서 우리가 만들었던 controller 메소드만 만들면 된다. 즉, 비즈니스 로직만 구현하면 된다는 뜻이다.

@Controller
public class BuisnessLogic {
@GetMapping("/process1")
  public String processRequest1(Model model){
      //비즈니스 로직
      model.set("items", "영화정보 리스트");
      
      return "process1";// -> resource/templates/process1.html을 사용
  }

  @GetMapping("/process2")
  public String processRequest2(@RequestParam String param1, Model model){
      //비즈니스 로직
      return "process2";
  }
}

@Controller라는 애노테이션을 통해, 이것이 컨트롤러에 사용될 클래스임을 명시한다. 이렇게 하면 Spring의 Front Controller (즉, Dispatcher Servlet)에서 이 클래스 하위의 @GetMapping따위로 명시된 메소드들을 각각 명시된 URL에 따른 컨트롤러로 사용한다. 우리가 앞에서 서블릿의 service메소드에서 구현했던 controllerMap[URL](param, model) 로직이 여기에 해당한다.

앞으로는 직접 만든 프레임워크보다는, 그냥 Spring을 사용하도록 하자.

 

Model 데이터는 뷰에서 어떻게 사용하나?

간단한 프레임워크를 직접 만들어 보면서, 서버에서 벌어지는 일들 중에서 중요한 내용은 모두 살펴보았다. HTTP 요청 메시지가 들어오면 Front Controller가 이를 수신하고, 적절한 비즈니스로직 컨트롤러를 호출한 후, 모델뷰 객체를 생성해서 dispatcher의 forward메소드를 통해 뷰에 전달한다.

그러면 이제 뷰에서 이렇게 전달된 모델을 어떻게 사용할지 생각해보자. 사실, 순수 html만으로는 이렇게 전달된 model 데이터를 사용할 수 없다. 따라서 뷰 리졸버를 개선해서, html파일을 한번 전처리 해야 한다. html파일에서 모델에 집어넣은 값을 사용하는 예약어를 사용하고, 뷰 리졸버는 원본 html파일을 읽어들여 이러한 예약어들을 처리한 다음, 처리된 html파일을 응답으로 내려보내 주면 된다.

ModelView {
	String path;
    
    render(model, request, respone){
    	request.setAttribute(model);//controller에 있던 로직이 이 공통 클래스로 옮겨왔다!
    	request.dispatcher.forward(path);
    }
}

service(request, response){
	Map paramMap <- request.param
    Map model = new Map();

	String viewName = controllerMap[request.URL](paramMap, model);
    
    ViewResolver.viewResolverProcess(model, viewName, request, response);
}

controller(paramMap, model){
	//비즈니스 로직
    model.set('뷰에서 그리고 싶은 값들')//비즈니스 로직의 결과 보여주고 싶은 값들
    
    return "content1"//그냥 뷰의 논리적 이름만 반환한다.
}

ViewResolver {
	map = {
    	"content1": "/path/context1.html"
        "content2": "/content2.html"
    }
    viewResolverProcess(model, viewName, request, response){
    	html = file.read(map[viewName]);
        
        //html에서 예약어들을 찾아서, 거기에 명시된 'items'가 model에 있는지 찾는다.
        //있다면 들어있는 갯수만큼 <div>'item.movieName'</div> 이러한 html코드를 생성한다(v-for의 대상이 div이므로)
        //임시로 사용할 convertedHtml파일을 작성하고, 여기에 결과물을 쓴다.
        
        Modelview mv = new ModelView(convertedHtml경로)
        mv.render(model, request, response)
    }
}

이런식으로 개선한다면, html에 아래와 같이 예약 키워드를 사용해서 model의 값을 html에 그릴 수 있다.

<div id="list1">
	<div>{{items[0].movieName}}</div>
    <div>{{items[1].movieName}}</div>
    <div>{{items[2].movieName}}</div>
    <div>{{items[3].movieName}}</div>
    <div>{{items[4].movieName}}</div>
</div>

 

이렇게 html을 작성해두면, 이 자체로는 html표준이 아니지만 VieResolver의 viewResolverProcess메소드를 통해 한번 전처리 되어 아래과 같은 html로 바뀌게 되고, 최종적으로는 이것이 브라우저로 응답된다.

<div id="list1">
	<div>타이타닉</div>
    <div>반지의 제왕 - 왕의 귀환</div>
    <div>반지의 제왕 - 두개의 탑</div>
    <div>반지의 제왕 - 반지 원정대</div>
    <div>자전차왕 엄복동ㅋ</div>
</div>

물론, 이것으로는 완벽하지 않고, 예약어에 for문같은 키워드도 추가해서 더 편하게 사용할 수 있다.

<div id="list1">
	<div myfor="item in items">{{item.movieName}}</div>
</div>

 

'Tech - 웹 개론' 카테고리의 다른 글

8. Javascript 환경과 모듈  (0) 2021.11.01
7. 뷰 템플릿  (0) 2021.10.22
5. 로직을 더 개선하기  (0) 2021.10.21
4. 구매완료 페이지 보내주기  (0) 2021.10.21
3. 웹 서버와 서블릿  (0) 2021.10.21

관련글 더보기