☘️ Spring

[Spring] Day61 - Spring MVC 변경

harveydent 2023. 8. 3. 16:50
728x90

Spring MVC

Spring Framework의 특성인 IoC를 이용하여 개발자가 직접 클래스를 만들지 않고 Spring에서 제공하는 클래스를 활용하여 Spring MVC 방식으로 코드를 작성할 수 있습니다.

web.xml

기존에는 개발자가 직접 생성한 DispatcherServlet.java를 사용하였지만 스프링에서 제공하는 DispatcherServlet-servlet.xml을 사용할 수 있습니다.

 

Resolver

Resolver는 주로 뷰(View)와 컨트롤러(Controller) 사이에서 데이터를 변환하거나 처리하는 데 사용됩니다. 특정 역할을 자동으로 처리하며 반드시 id를 명시해줘야 합니다.

ViewResolver

ViewResolver는 사용자에게 보여질 뷰를 결정하는 역할을 합니다. 주로 컨트롤러에서 반환된 뷰 이름을 기반으로 실제 뷰 템플릿의 위치를 찾아서 렌더링하도록 지시합니다. Contoller류의 객체가 .handleRequest()의 수행결과로 String을 반환했을 때 prefix(접두사)와 suffix(접미사)를 판단해서 처리합니다. Spring에서는 다양한 ViewResolver 구현을 제공합니다.

 

Spring MVC 변경

  1. web.xml에서 직접 생성한 DispatcherServlet.java를 Spring에서 제공하는 클래스로 변경
    • 컨테이너를 구동할 것이기 때문에 컨테이너 설정 등을 정의하는 xml 파일이 필요
    • DispatcherServlet-servlet.xml
  2. Spring이 제공하는 Controller 클래스로 변경
    • 반환타입을 String에서 ModelAndView로 변경
  3. HandlerMapping 생성
    • HandlerMapping이 요청에 대한 Controller 객체 반환을 수행
    • HandlerMapping은 DispatcherServlet에서 DI되는 객체
    • DispatcherServlet-servlet에서 초기화
    • HandlerMapping은 POJO이기 때문에 web.xml에서 설정할 수 없음
    • HandlerMapping은 생성자 주입이 아니라 setter 주입

ViewResolver 페이지 은닉

해당 페이지를 열 때 경유해야 하는 페이지가 있는 경우에는 WEB-INF 하위 폴더에 jsp 파일을 위치시킵니다. 페이지를 열 때 어떠한 데이터가 오지 않을 경우 에러가 발생할 수 있으므로 ViewResolver를 통해 페이지를 은닉합니다. 해당 방식은 사용자의 직접 접근(URL 조작)을 차단할 수 있고 오직 ViewResolver를 통해서만 이동할 수 있습니다.

실습

package com.spring.view.controller;

public class ViewResolver {
	public String prefix;
	public String suffix;
	
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}
	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}
	
	public String getView(String viewName) {
		return prefix+viewName+suffix;
	}
}

ViewResolver.java

 

package com.spring.view.controller;

import java.io.IOException;

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

public class DispatcherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	private HandlerMapping handlerMapping;
	private ViewResolver viewResolver;
	
	public void init() {
		handlerMapping = new HandlerMapping();
		viewResolver = new ViewResolver();
		viewResolver.setPrefix("./");
		viewResolver.setSuffix(".jsp");
	}
	
    public DispatcherServlet() {
        super();
    }

    private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	String uri=request.getRequestURI();
    	String command=uri.substring(uri.lastIndexOf("/"));
    	System.out.println("command: "+command);
    	
    	Controller ctrl=handlerMapping.getController(command);
    	String viewName=ctrl.handleRequest(request, response);
    	// viewName이 .do를 가지고있으면 VIEW로 가는것이 아니다
    	
    	String path=viewName;
    	if(!viewName.contains(".do")) {
    		path=viewResolver.getView(viewName);      
    	}
    	
    	response.sendRedirect(path);
    }
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doAction(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doAction(request, response);
	}
}

DispatcherServler.java

 

package com.spring.view.controller;

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

public class HandlerMapping {
	// FrontController에서 사용되는 factory 클래스의 이름
	// 팩토리 패턴을 사용하기때문에 싱글톤이 유지됨
	private Map<String,Controller> mappings;
	
	public HandlerMapping() {
		mappings=new HashMap<String,Controller>();
		mappings.put("/main.do", new MainController());
		mappings.put("/login.do", new LoginController());
		mappings.put("/logout.do", new LogoutController());
	}
	
	public Controller getController(String command) {
		Controller ctrl=mappings.get(command);
		return ctrl;
	}	
}

HandlerMapping.java

package com.spring.view.controller;

import java.io.IOException;

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

import com.spring.biz.board.BoardDAO;

public class MainController implements Controller {

	@Override
	public String handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("MainController 로그");
		
		BoardDAO bDAO=new BoardDAO();
		request.setAttribute("datas", bDAO.selectAll(null));
				
		return "main"; // main.jsp(VIEW)로 가려고함
	}
}

MainController.java

GitHub

https://github.com/Qkrwnsgus0522/Spring

 

GitHub - Qkrwnsgus0522/Spring

Contribute to Qkrwnsgus0522/Spring development by creating an account on GitHub.

github.com

 

728x90