본문 바로가기

대덕공부/Spring

**Spring Menual

//실제코드랑 같이 보면서 공부하기

기존의 Servlet, JSP를 통한 MVC Pattern의 한계점

  • 뷰 렌더링과 컨트롤러 역할을 분리한 건 좋지만 페이지가 늘어남에 따라 컨트롤러 내 중복 코드 다량 발생
  • View로 이동하는 Forward 코드 중복 
  • View 주소 즉, ViewPath 설정하는 코드 중복
  • 별도 응답을 보낼 필요가 없는 경우 서블릿 내 response 코드가 사용되지 않음
  • HttpServletRequest, HttpServletResponse를 사용하는 테스트 코드 작성하기 쉽지 않음
  • 정리하자면, 공통 처리가 어려운 것이 문제 (이를 해결하기 위해 Front Controller 패턴 도입)

 

 

@FrontController

서블릿 하나로 클라이언트의 요청을 받음

프런트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출프런트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 됨정리하자면, FrontController는 공통 코드를 처리하고 요청에 맞는 컨트롤러를 매핑해주는 역할 (앞서 언급한 Servlet, JSP를 통한 MVC 패턴의 단점 해결)ex) 스프링 웹 MVC의 DispatcherServlet

 

Front Controller가 제역할을 수행하도록 처리해줘야 하는 절차

1. Front Controller가 URL 매핑 정보에서 적합한 컨트롤러를 조회하여 호출하도록 처리

2. 기존에는 View로 이동하는 Forward 코드가 중복되었으므로 별도로 뷰를 처리하는 객체를 생성하여 컨트롤러에서 ModelAndView를 반환하면 Front Controller에서 렌더링 하도록 처리

3. Front Controller를 제외한 나머지 컨트롤러들은 서블릿 기술을 몰라도 동작될 수 있도록 처리 즉, 서블릿 종속성 제거

4. 뷰의 이름을 전부 명시하지 않고 논리 이름만 반환해도 되도록 처리 (ViewResolver 구현)

/**
 * Front Controller Pattern 을 적용하고 모든 요청에 대한 사전 처리를 담당 /member/memberInsert.do
 * /member/memberList.do
 * 
 * @author 306-25
 *
 */
public class FrontController extends HttpServlet {

	private HandlerMapping handlerMapping;
	private HandlerAdapter handlerAdapter;
	private ViewResolver viewResolver;

	@Override
	public void init() throws ServletException {
		super.init();
		handlerMapping = new RequestMappingHandlerMapping("kr.or.ddit");
		handlerAdapter = new RequestMappingHandlerAdapter();
		viewResolver = new DelegatingViewResolver();
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 요청이 핸들러 매핑으로 넘어감
		RequestMappingInfo mappingInfo = handlerMapping.findCommandHandler(req);
		// 특정요청을 처리할수있는 매소드
		// 어댑터사용해서 매핑인포를 넘겨줘야함
		int sc = 200;
		String message = null;
		if (mappingInfo != null) { // 핸들러를 찾았다는 의미
			try {
				String viewName = handlerAdapter.invoikeHandler(mappingInfo, req, resp);
				// 여기까지가 7번
				if (viewName != null) {// 로직컬뷰네임있음
					// 로지컬뷰네임을 안 만든거 핸들러에서 반드시 로지컬뷰네임이 정해져야함
					viewResolver.viewResolve(viewName, req, resp);// 논리이름 넘겨줌
				} else {
					if (!resp.isCommitted()) {
						sc = 500;
						message = "요청을 처리하는 과정에서 문제가 발생했습니다.(LVN이 없습니다.)";
					}
				}
			} catch (BadRequestException e) {
				sc = 400;
				message = e.getMessage(); 
				//400에러를 직접 발생시키지않고 badexception을 발생시킴
			}
		} else {
			sc = 404;
			message = "현재 요청은 제공하지 않는 서비스입니다.";
		}

		if (sc != 200) {// 문제있다는거
			resp.sendError(sc, message);// 응답에러
		}
	}
}

init()

- RequestMappingHandlerMapping

- RequestMappingHandlerAdapter

- DelegatingViewResolver

service()

-요청이 Handler Mapping으로 넘어감 

-RequestMappingInfo로 특정요청메소드를 부러줌 

 


 

@RequestMappingHandlerMapping

private Map<RequestMappingCondition, RequestMappingInfo> handlerMap;

- Map에 handlerMap들을 담아준다. 

 

public RequestMappingInfo findCommandHandler

 

	public RequestMappingInfo findCommandHandler(HttpServletRequest req) {
		String uri = req.getRequestURI();
		uri = uri.substring(req.getContextPath().length());
		uri = uri.split(":")[0];
		RequestMethod method = RequestMethod.valueOf(req.getMethod().toUpperCase());
		RequestMappingCondition mappingCondition = new RequestMappingCondition(uri, method);
		RequestMappingInfo mappingInfo = handlerMap.get(mappingCondition);
		log.info("현재요청 : {} , \n 요청 처리 핸들러 : {} ", mappingCondition, mappingInfo);
		return mappingInfo;

	}

파란색이 MappingCondition, 초록색이 MappingInfo 

 


@RequestMappingCondition

@RequestMapping 에서 설정된 핸들러의 매핑가능한 요청 정보 (uri, method)

RequestMappingCondition

@Override
public String toString() {
return "요청 매핑 정보 [uri=" + uri + ", method=" + method + "]";
}

uri랑 method 가져와서 toString에 담은 값을 Request


@InternalResourceViewResolver @ViewResolver

@HandlerMapping

@RequestMappingHandlerMapping

 

 

 

@RequestMethod

@RequestMappingInfo

@HandlerAdapter

@RequestMappingHandlerAdapter

@HandlerMethodArgumentResolver 

 

 

'대덕공부 > Spring' 카테고리의 다른 글

Spring - CoreContainer  (0) 2022.07.14
RedirectAttributes, Model, ModelAttribute (feat.dditStudentCont)  (0) 2022.07.12
보안프레임워크2  (0) 2022.07.06
WAS와 Server의 차이? 그리고 Web Container 란?  (0) 2022.07.05
Filter  (0) 2022.07.05