카테고리 없음

7/8 Contoller FrameWork Spring의 구조를 만들어보자.

02O2 2022. 7. 8. 18:28

Controller들의 공통점은 멀까?

 -request를 가지고논다.

-viewresolver를 쓴다. 그치만 vo가 다르다. 

-반복적인 행위가 들어간다. 

 

각방에서 반복적인 수행을하지말고 공통적인..? 정문에서 한번만 수행하는식으로 한다. 

그 정문을 FrontController라고 칭한다. 

한번만든건 고치지않는다 라는 오래된 규칙때문에 이 의존관계를 끌어야하는데 . 

결합도를 낮춰야 좋은 개발이다. 

Handler Adapter랑 HandlerMapping 중간에있는 결합을 끊기위해 중요한 역할

FrongControlleㄱ 요청 종류 상관없이 모두 받고

뒤에있는 ㅐㅂㄱ엔드 컨트롤러는 하나의 요청만 처리해서 하나의 핸들러라고한다.

앞에서 요청을 받고 요청을 판단해서 뒷단에있는 백엔드컨트롤러로 보낸다.

작업을 분리시키는게 HandlerMapping 이다. (내부에 맵이하나있는데 어떤 요청을 보낼지 맵에다가 기록이 되어있다. 키와밸류로 이루어진 핸들러 매핑 )

핸들러 매핑이 요청을 가지고 자기가가지고있는 현재요청을 맵안에서 처리할 핸들러를 찾는다.  

 프론트는 어떤핸들러인지를 찾으면 그 핸들러를 호출하는데 직접호출하지안흔ㄴ다. 왜냐하면 결합력이 생기니깐 

->그래서 requestmappinginfo안에 핸들러가잇는데 adapter를 이용해서 호출한다. 

 

 

@MultipartConfig ->이게있어야 파일업로드가능 , 그러면 모든 servlet에 다있어야하는데

이게 프론트컨트롤러로 옮기면 중복 줄어듬 !

 

ProdVO prod = new ProdVO();
req.setAttribute("prod", prod);
try {
BeanUtils.populate(prod, req.getParameterMap());
//모든 프로퍼티가 vo로 들어감 
//이거머지?
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServletException(e);
}



new DelegatingViewResolver().viewResolve(viewName, req, resp);

컨트롤러에서 첫번째부분과 마지막부분이 중복되는데 이걸 프론트컨트롤러로 빼낼거다.

 

with@Controller은 완전한 형태의 POJO ( Plain Old Java Object) 완전평번한 자바객체라는뜻 

 

<servlet>
<servlet-name>FrontController</servlet-name>
<servlet-class>kr.or.ddit.mvc.FrontController</servlet-class>
<multipart-config>
<max-file-size>-1</max-file-size>
</multipart-config>
</servlet>

 

@MultipartConfig  중복해결 

 

모든컨트롤러에서는 로직컬뷰네임이 반환되어야한다.

--리팩토링 중

 

	if("/member/memberList.do".equals(uri)) {
			MemberListController controller = new MemberListController();
			viewName =	controller.memberList(req, resp);
		}else if("/member/memberInsert.do".equals(uri)) {
			MemberInsertController controller = new MemberInsertController();
			viewName = controller.memberForm(req, resp);
		}else if("/prod/prodInsert.do".equals(uri)) {
			ProdInsertController controller = new ProdInsertController();
			
		}

1:1구조 -->Map 이용하면 저런 if문을 안써도 될지도.. ? 

.do 는 get방식이거나 post방식인데 . 이 요청은 메소드를 쓰는게아니라 주소를 쓰고있다.

저 두개를 해결해야함 . 

 

- 이구조는 프론트컨트롤러가 백엔드 컨트롤을 직접적으로 호출하는거다. - 결합도가 높아서 좋지않은 구조 

@Controller

마커어노테이션을 쓰고싶다.  -> 밑에있는 메소드들이 핸들러 .

컨트롤러 식별한느거

 

@RequestMapping("/member/memberList.do")

특정요청처리하고싶을때 어떤요청처리할건지 식별하는거

 

두개의 어노테이션을 만들어 사용하고싶다. 그러면 저런 if문이 필요없음 .

 

어노테이션을 만들어서 if문을 없애는게 우리의 목표 . 

 

RequesetMappingHandlerMapping

 

매핑에서 가져오지만 쓰진않고 그대로 

로지컬뷰네임이 프론트가 가져가고 프론트는 다시 그걸 뷰리졸버로 준다. 

 

//		String uri = req.getRequestURI();
//		uri = uri.substring(req.getContextPath().length());
//		uri = uri.split(";")[0];
//		String viewName = null;

//		if("/member/memberList.do".equals(uri)) {
//			MemberListController controller = new MemberListController();
//			viewName =	controller.memberList(req, resp);
//		}else if("/member/memberInsert.do".equals(uri)) {
//			MemberInsertController controller = new MemberInsertController();
//			viewName = controller.memberForm(req, resp);
//		}else if("/prod/prodInsert.do".equals(uri)) {
//			ProdInsertController controller = new ProdInsertController();
//			
//		}
//		new DelegatingViewResolver().viewResolve(viewName, req, resp);
/WebStudy04_MVC 로딩 완료
12:35:03.310 [localhost-startStop-1] INFO  k.o.d.m.a.RequestMappingHandlerMapping - 요청 매핑 정보 [uri=/member/memberInsert.do, method=GET] : 핸들러(Controller) 정보 [handler=kr.or.ddit.member.web.MemberInsertController@40860ee3, handlerMethod=public java.lang.String kr.or.ddit.member.web.MemberInsertController.memberForm(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException]
12:35:03.318 [localhost-startStop-1] INFO  k.o.d.m.a.RequestMappingHandlerMapping - 요청 매핑 정보 [uri=/member/memberInsert.do, method=POST] : 핸들러(Controller) 정보 [handler=kr.or.ddit.member.web.MemberInsertController@40860ee3, handlerMethod=public java.lang.String kr.or.ddit.member.web.MemberInsertController.insertProcess(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException]
12:35:03.319 [localhost-startStop-1] INFO  k.o.d.m.a.RequestMappingHandlerMapping - 요청 매핑 정보 [uri=/member/memberList.do, method=GET] : 핸들러(Controller) 정보 [handler=kr.or.ddit.member.web.MemberListController@72584aa7, handlerMethod=public java.lang.String kr.or.ddit.member.web.MemberListController.memberList(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException]
12:35:03.319 [localhost-startStop-1] INFO  k.o.d.m.a.RequestMappingHandlerMapping - 요청 매핑 정보 [uri=/member/memberView.do, method=GET] : 핸들러(Controller) 정보 [handler=kr.or.ddit.member.web.MemberViewController@503dfb4e, handlerMethod=public java.lang.String kr.or.ddit.member.web.MemberViewController.memberView(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException]
12:35:03.319 [localhost-startStop-1] INFO  k.o.d.m.a.RequestMappingHandlerMapping - 요청 매핑 정보 [uri=/prod/prodInsert.do, method=GET] : 핸들러(Controller) 정보 [handler=kr.or.ddit.prod.web.ProdInsertController@40ec7f10, handlerMethod=public java.lang.String kr.or.ddit.prod.web.ProdInsertController.prodForm(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException]
12:35:03.319 [localhost-startStop-1] INFO  k.o.d.m.a.RequestMappingHandlerMapping - 요청 매핑 정보 [uri=/prod/prodInsert.do, method=POST] : 핸들러(Controller) 정보 [handler=kr.or.ddit.prod.web.ProdInsertController@40ec7f10, handlerMethod=public java.lang.String kr.or.ddit.prod.web.ProdInsertController.insertProcess(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException]
7월 08, 2022 12:35:05 오후 org.apache.jasper.servlet.TldScanner scanJars
정보: 적어도 하나의 JAR가 TLD들을 찾기 위해 스캔되었으나 아무 것도 찾지 못했습니다. 스캔했으나 TLD가 없는 JAR들의 전체 목록을 보시려면, 로그 레벨을 디버그 레벨로 설정하십시오. 스캔 과정에서 불필요한 JAR들을 건너뛰면, 시스템 시작 시간과 JSP 컴파일 시간을 단축시킬 수 있습니다.
/WebStudy03_Framework 로딩 완료

핸들러 맵이 정상적으로 만들어졌음 

어떤특정요청을 받았을때 그거에 맞는 핸들러를 찾아가야함 !!

RequestMappingInfo mappingInfo = handlerMapping.findCommandHandler(req);
//특정요청을 처리할수있는 매소드

 


컨트롤러의 책임분리 

parameterValue = parameterType.newInstance();// MemberVO member = new MemberVO();

// req.setAttribute("member", member);
// // member.setMemId(req.getParameter("memId"));
// try {
// BeanUtils.populate(member, req.getParameterMap());
//
// } catch (IllegalAccessException | InvocationTargetException e) {
// throw new RuntimeException(e);
// }

 

ModelAttribute annotation = parameter.getAnnotation(ModelAttribute.class);
Class<?> parameterType = parameter.getType();
Object parameterValue;
try {
parameterValue = parameterType.newInstance();
//모델 어노테이션에 이름을 숨겨놓음 어노테이션이 필요! 
String attrName = annotation.value();
request.setAttribute(attrName, parameterValue);
BeanUtils.populate(parameterValue, request.getParameterMap());
return parameterValue;
} catch (Exception e) {
throw new ServletException(e);
}

 

 

 

(@RequestParam(name="who", required=true)

매퍼클래스에 이거쓰고싶은거 

 

 

 

String searchType = req.getParameter("searchType");
String searchWord = req.getParameter("searchWord");

 

@RequestParam(value="searchType", required=false) String searchType
, @RequestParam(value="searchWord" required=false) String searchWord

 

 

 

int currentPage = 1;
if (StringUtils.isNumeric(pageParam)) {
currentPage = Integer.parseInt(pageParam);
}

 

, @RequestParam(value="page", required=false, defaultValue="1") int currentPage

 

package kr.or.ddit.member.web;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import kr.or.ddit.member.service.MemberService;
import kr.or.ddit.member.service.MemberServiceImpl;
import kr.or.ddit.mvc.DelegatingViewResolver;
import kr.or.ddit.mvc.InternalResourceViewResolver;
import kr.or.ddit.mvc.annotation.RequestMethod;
import kr.or.ddit.mvc.annotation.resolvers.RequestParam;
import kr.or.ddit.mvc.annotation.stereotype.Controller;
import kr.or.ddit.mvc.annotation.stereotype.RequestMapping;
import kr.or.ddit.vo.MemberVO;
import kr.or.ddit.vo.PagingVO;
import kr.or.ddit.vo.SimpleSearchCondition;

/**
 * 회원 목록을 조회하기 위한 Controller Layer
 *
 */

//@WebServlet("/member/memberList.do")
@Controller
public class MemberListController {

private static final Logger Log = LoggerFactory.getLogger(MemberListController.class);

MemberService service = new MemberServiceImpl();

private String processHTML() {
return "/member/memberList.tiles";// member/memberList가 로직컬 뷰 네임

}

private String processJsonData(
@RequestParam(value="searchType", required=false) String searchType
, @RequestParam(value="searchWord", required=false) String searchWord
, @RequestParam(value="page", required=false, defaultValue="1") int currentPage
, HttpServletRequest req) {


SimpleSearchCondition searchVO = new SimpleSearchCondition(searchType, searchWord);
Log.info("searchType : {}, searchWord : {}", searchType, searchWord);

PagingVO<MemberVO> pagingVO = new PagingVO<>(5, 3);
pagingVO.setCurrentPage(currentPage);
pagingVO.setSimpleCondition(searchVO);

service.retrieveMemberList(pagingVO);

req.setAttribute("pagingVO", pagingVO);

return "forward:/jsonView.do";// member/memberList가 로직컬 뷰 네임

}

@RequestMapping(value="/member/memberList.do", method = RequestMethod.GET)//얘가 value 현재 메소드는 get 
//얘를 포조라고 부른다.
public String memberList (
@RequestParam(value="searchType", required=false) String searchType
, @RequestParam(value="searchWord", required=false) String searchWord
, @RequestParam(value="page", required=false, defaultValue="1") int currentPage
, HttpServletRequest req
){
String accept = req.getHeader("accept");
String viewName = null;
if (StringUtils.containsIgnoreCase(accept, "json")) {
viewName = processJsonData(searchType, searchWord, currentPage, req);
} else {
viewName = processHTML();
}
return viewName;
}
}