본문 바로가기
IT Study/Spring

Spring - Spring MVC

by hhyyyjun 2023. 1. 2.

Spring 형식의 FrontController 역할을 하는 서블릿을 DispatcherServlet이라 한다.

DispatcherServlet을 생성하는 순간

web.xml 파일에서 자동으로 서블릿 매핑을 하고 있다.(오류가 있는 경우 스키마의 j를 대문자로 변경하자)

DispatcherServlet

- DispatcherServlet는 Action 역할을 수행하는 Controller 들을 호출해서 사용자의 요청을 처리함

- 자신이 직접 C들을 호출하지 않고, HandlerMapping을 통해서 호출함

package com.kim.biz.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class DispatcherServlet
 */
public class DispatcherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	//의존관계
	private HandlerMapping handlerMapping;
	private ViewResolver viewResolver;
    // init()메서드를 통해 DI
	public void init() throws ServletException{
		// 핸들러 매핑을 통해 컨트롤러를 제공받을 것임
    	handlerMapping = new HandlerMapping();
    	viewResolver = new ViewResolver();
    	viewResolver.setPrefix("./");
    	viewResolver.setSuffix(".jsp");
    }
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DispatcherServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doAction(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		doAction(request, response);
	}
	private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String command=request.getRequestURI();
		command = command.substring(command.lastIndexOf("/"));
//		String cp=request.getContextPath();
//		String command=uri.substring(cp.length());
		System.out.println("DS:현재 들어온 명령어"+command);
		
		Controller ctrl = handlerMapping.getConteroller(command);
		String viewName = ctrl.handleRequest(request, response);
		
		String view=null;
		if(viewName.contains(".do")) {
			view = viewName;
		}
		else {
			view = viewResolver.getView(viewName);
		}
		response.sendRedirect(view);
	}
}

 

HandlerMapping

package com.kim.biz.controller;

import java.util.HashMap;
import java.util.Map;

//객체의 무분별한 생성을 막기 위해 = 싱글톤 패턴을 유지할 수 있기 때문에 핸들러 매핑을 사용한다.
public class HandlerMapping {
	//input 어떤 요청에 대해 == string
	//output 무슨 controller 객체를 제공해야 하는지 == controller
	
	//핸들러 매핑을 사용하는 이유가 요청에 대해 적절한 컨트롤러 객체를 반환하려고 사용
	// 어떤 요청에 대해 뭘 반환해야하는 지를 mappings가 가지고 있고
	private Map<String, Controller> mappings; //mappings에 생성자 주입

	// 이걸 New 해야 쓸 수 있으니 생성자로 뉴 해준것
	public HandlerMapping() {
		mappings = new HashMap<String, Controller>();
		mappings.put("/login.do", new LoginController()); //한번만 new 하므로 싱글톤 패턴이 유지됨
	}

	public Controller getConteroller(String command) {
		return mappings.get(command);
	}
}
​

 

Controller

package com.kim.biz.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//컨트롤러
public interface Controller {
	//기존에는 ActionForward의 execute 였는데 이젠 응답만 하면 된다
	String handleRequest(HttpServletRequest request, HttpServletResponse response);
	
}

 

ViewResolver

package com.kim.biz.controller;

public class ViewResolver {
	public String prefix; //의존관계 > DI > setter 주입
	public String suffix; //의존관계 > DI > setter 주입
	
	//setter 주입을 사용할 예정임
	public String getPrefix() {
		return prefix;
	}
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}
	public String getSuffix() {
		return suffix;
	}
	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}
	
	public String getView(String viewName) {
		return prefix+viewName+suffix;
	}
}

요청 순서

사용자의 요청 > *do > DispatcherServlet(이 때 web.xml을 보고 간다) > HandlerMapping > Controller호출 > 경로정보를 반환 > ViewResolver > 사용자에게 화면을 제공

Spring MVC의 장점

* 기존의 FrontController 패턴이 메모리를 불필요하게 사용하던 객체들이 현저히 줄어든다.

* 하드코딩이 줄어듦 (코드의 불필요한 반복패턴이 줄어듦) -> 코드가 간결해진다.

* 결합도가 낮아지고 응집도가 높아짐 -> 유지보수 용이

댓글