프로그래밍

[Spring] day61 : Spring MVC로 변경하기 본문

자바/Spring

[Spring] day61 : Spring MVC로 변경하기

시케 2023. 8. 12. 23:25
728x90
반응형

2023.08.03.목

Spring MVC로 변경하기

지금까지 작성한 코드를 Spring MVC 방식으로 변경해보도록 하자

스프링 프레임워크의 특성인 IoC를 이용하여

우리가 직접 클래스를 만드는 것이 아닌 Spring에서 제공하는 클래스를 활용할 것이다

 

현재 가장 무거운 객체는 dispatcher이다

상대적으로 무거운 파일인 dispatcher의 코드가 변경되지 않으면
재컴파일 할 일 없어지며

기능 추가시 컨트롤러만 구현해서 넣으면 되므로

유지보수에 유리해진다

 

web.xml
기존에는 우리가 만든 'dispatcher'를 넣었지만
우리는 스프링에서 제공하는 dispatcher를 넣을것이다

※ 스프링 프레임워크 활용
Resolver
: 특정 역할을 자동으로 처리
: 반드시 id를 명시해줘야 함
ViewResolver
String을 보고 어디로 어떻게 가야하는지 구분하는 역할
: Controller류의 객체가 .handleRequest()의 수행결과로 String을 반환했을때
'어떻게 갈지'와 '어디로 갈지'를 판단해서 처리해주는 주체
즉, View 이동을 자동으로 처리

자신의 멤버변수를 setter로 받는다
경로를 받으면 어디로/어떻게 갈지 앞뒤에 붙여서 반환(prefix, suffix)

 

Spring MVC로 변경

1. web.xml에서 내가 만든 클래스를 spring에서 제공하는 클래스로 변경

컨테이너를 구동할 것이기 때문에 설정파일인 .xml 필요

DispatcherServlet-servlet.xml

해당 이름은 우리가 web.xml에 지정한것에 -servlet으로 이름 규칙이 지정되어 있기 때문이다

※ web.xml에 스프링이 제공하는 필터 클래스 추가(인코딩)

 

2. 스프링이 제공하는 클래스로 Controller 변경

반환이 String -> ModelAndView로 변경

 

3. HandlerMapping 생성

@RequestMapping
Method 형식을 사용하여 GET/POST 에 따른 작동 여부 결정 가능
(에러처리 / 보안 / 등을 이유로)

사용자의 xxx.do 요청에 대해 수행할 Controller 클래스까지 구현이 완료된 상태

HM이 요청에 대한 Controller 객체 반환을 수행하므로,
HM 생성할 차례이다


HM은 DS에서 DI 되는 클래스(객체)
※ DS는 init()에서 초기화
즉, DispatcherServlet-servlet.xml에서 초기화
※ HM은 POJO니까 web.xml에서 설정할 수 없다
 HM은 생성자 주입이 아니라 setter 주입

ViewResolver를 통한 페이지 은닉

jsp 페이지임에도 WEB-INF 하위 폴더에 위치시키는 경우가 있다

이러한 페이지들은 주로 '해당페이지를 열때 경유해야 하는 페이지가 있는 경우'이다

페이지를 열때 어떠한 데이터가 오지 않을 경우 에러가 발생할 수 있는 경우에는

ViewResolver를 통해 페이지를 은닉한다

 

해당 방식을 이용하면

사용자의 직접 접근을 차단(URL 조작 차단)할 수 있다
※※※이렇게 은닉된 페이지는 오직 VR 통해서만 갈 수 있다!!!!※※※

 

package test2;

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;
	}
}
package test2;

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("./");	//setter 주입
		viewResolver.setSuffix(".jsp");	//setter 주입
	}
	
    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를 가는게 아니라 ctrl를 한번 더 수행하는거
    	// 그래서 .do.jsp와 같은 경우 발생
    	// 다형성 형성(피카츄)
    	
    	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);
	}
}
@Controller
public class MainController {

	@RequestMapping(value="/main.do")
	public ModelAndView main(BoardDAO bDAO, ModelAndView mav) {
		System.out.println("MainController 로그");
		
		mav.addObject("datas", bDAO.selectAll(null));
		mav.setViewName("main.jsp");
		// /WEB-INF/views/ + main + .jsp
		return mav;
	}

}

https://github.com/jihyean/Spring/tree/main/day61

 

728x90
반응형
Comments