일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- SSAFY 9기
- 모두를 위한 컴퓨터 과학(CS50)
- 삼성청년SW아카데미
- WebProgramming
- 객체지향
- 기초프로그래밍
- 데이터베이스 모델링
- CS 기초
- exception
- SW
- java
- CS 기초지식
- ERD
- edwith
- 알고리즘
- 모두를 위한 컴퓨터 과학
- 관계형 데이터베이스
- 예외처리
- Computer Science
- 상속
- 부스트코스
- w3schools
- CS기초지식
- ssafy
- 면접을 위한 CS 전공지식 노트
- til
- CS50
- Compute Science
- Java Programming
- 이진법
- Today
- Total
Joslynn의 하루
MSA Full-Stack 개발자 양성 과정 - JSP&Servlet MVC 구조 Refactoring_221014 본문
MSA Full-Stack 개발자 양성 과정 - JSP&Servlet MVC 구조 Refactoring_221014
Joslynn 2022. 10. 14. 18:02MVC 구조
version1
1. View
< a href= "front?key=insert/update/delete/select">
등록 / 수정 / 삭제 / 조회
</a>
: key를 보냄으로써 Sevlet에서 어떤 기능인지 구분할 수 있음
2. DispatcherServlet: 진입점 서블릿(Controller 역할)
class DispatcherServlet extends HttpServlet{
@webServlet("/front")
Xxxservice(request, response){
String key = request.getParameter("key");
Controller con = null;
if (key.equals("insert"){
con = new InsertConroller();
} else if (key.equals("update")){
con = new UpdateConroller();
} else if....
ModelAndView m = con.handleRequest(request, response);
if(m.isRedirect(){
//true이면 redirect 방식
response.sendRedirect(m.getViewName());
} else {
//false이면 forward 방식
request.getRequestDispatcher(m.getViewName()).forward(request, response);
}
}
}
: 수많은 등록 삭제 조회 수정 요청을 service에서만 담당하면 한 메소드가 너무 많은 역할을 담당하게됨
: 분산 필요 → Controller(interface)를 만듦
3. Interface Controller
public interface Controller{
ModelAndView handleRequest(request, response); // 요청을 받고 응답하는 역할을 가장 많이 담당함
//ModelAndView를 리턴
}
: Controller 인터페이스를 implements 하는 InsertController, SelectController, UpdateController, DeleteController.....
: 각각 메소드 재정의
: 확장된 모든 Impl 클래스들은 Controller라고 부를 수 있음 (다형성) → 유지보수에 유리
4. class ModelAndView
class ModelAndView{
String viewName; //최종적으로 이동할 뷰의 page이름
boolean isRedirect; //이동 방식 결정 (true이면 redirect 방식, false면 forward방식)
}
Version 2: Listener 사용
1. ServletContexLister
public class AppListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
//~.propertiest 파일 로딩
while(){
//1. key와 value를 분리
//2. String을 객체로 만든다 -> 생성 (Reflection 개념 적용)
//3. Map에 저장(key: <String>, value: <Controller>) // map.put(key, value);
}
ServletContext application = sce.getServletContext();
application.setAttribute("map", map);
}
}
**~.properties 파일
#key = value
insert = InsertController
delete = DeleteController
select = SelectController
update = UpdateController
**Reflection 개념
: String의 문자열을 Controller라는 객체로 생성해야 함
: Class<?>는 어떤 객체가 가지고 있는 필드, 생성자, 메소드의 정보를 동적으로 가져올 수 있도록 도와주는 객체
: relection 개념은 동적으로, 즉, 실행도중에 필요한 객체를 적절하게 생성하고, 그 객체가 가지고 있는 생성자나 메소드를 동적으로 호출할 수 있도록 도와주는 개념
: 자바에서 이러한 개념을 적용해놓은 API가 Class<?>이다.
2. DispatcherServlet 변경
class DispatcherServlet extends HttpServlet{
Map<String, Controller> map;
Xxxinit(){
map = application.getAttribute("map");
}
Xxxservice(request, response){
String key = request.getParameter("key");
Contoller con = map.get(key);
ModelAndView m = con.handleRequest(request, response);
if(m.isRedirect(){
//true이면 redirect 방식
response.sendRedirect(m.getViewName());
} else {
//false이면 forward 방식
request.getRequestDispatcher(m.getViewName()).forward(request, response);
}
}
}
Version 3: 여러 기능 추가
1. 시나리오
1) Version2
㉮ 회원관리
- 가입, 로그인, 로그아웃, 정보수정, 탈퇴 → 각각 XxxController 적용
㉯게시판 관리
- 게시판 등록, 수정, 삭제 → 각각 XxxController 적용
㉰ 상품관리
- 상품 등록, 수정 삭제 → 각각 XxxController 적용
2) Version3
㉮ 회원관리 → 기능별로 XxxController 적용
- 가입, 로그인, 로그아웃, 정보수정, 탈퇴 -- 메소드
㉯게시판 관리
㉰ 상품관리
: 뷰에서 요청시 front?key=select&methodName=login
: parameter 정보 중 key는 어떤 XxxController를 실행해야 하는 객체를 찾아주는 정보, methodName은 찾은 XxxController의 어떤 메소드를 호출해야 하는지 찾아주는 정보이다.
HandlerMappingListener
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import kosta.mvc.controller.Controller;
/**
* 서버가 시작될 때, 각 Controller의 구현 객체를 미리 생성해서 Map에 저장한 후, ServletContext영역에 map을 저장
*
*/
@WebListener
public class HandlerMappingListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent sce) {
}
public void contextInitialized(ServletContextEvent sce) {
ResourceBundle rb = ResourceBundle.getBundle("actionMapping"); // actionMapping.properties 로딩
try {
Map<String, Controller> map = new HashMap<String, Controller>();
Map<String, Class<?>> clzMap = new HashMap<String, Class<?>>();
for (String key : rb.keySet()) {
String value = rb.getString(key);
Class<?> className = Class.forName(value);
Controller con = (Controller) className.getDeclaredConstructor().newInstance();
map.put(key, con);
clzMap.put(key, className);
}
// 현재 프로젝트의 모든 영역에서 map을 사용할 수 있도록 ServletContext영역에 저장한다.
ServletContext applcation = sce.getServletContext();
applcation.setAttribute("map", map);
applcation.setAttribute("clzMap", clzMap);
applcation.setAttribute("path", applcation.getContextPath());
} catch (Exception e) {
e.printStackTrace();
}
}
}
DispatcherServlet
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 모든 사용자 요청을 처리할 진입점 Controller의 역할 : loadOnStartup -> 서버 올릴때,
* DispatcherServlet을 사전 초기화(진입점이므로 사전 생성이 좋음)
*/
@WebServlet(urlPatterns = "/front", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Map<String, Controller> map;
private Map<String, Class<?>> clzMap;
@Override
public void init() throws ServletException {
ServletContext application = super.getServletContext();
map = (Map<String, Controller>) application.getAttribute("map");
clzMap = (Map<String, Class<?>>) application.getAttribute("clzMap");
}
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String key = request.getParameter("key"); // user, board, goods
String methodName = request.getParameter("methodName");
System.out.println("key = " + key);
System.out.println("methodName = " + methodName);
try {
Controller con = map.get(key);
Class<?> className = clzMap.get(key);
Method method = className.getDeclaredMethod(methodName, HttpServletRequest.class,
HttpServletResponse.class);
// 호출
ModelAndView mv = (ModelAndView) method.invoke(con, request, response);
if (mv.isRedirect()) {
response.sendRedirect(mv.getViewName());
} else {
request.getRequestDispatcher(mv.getViewName()).forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
'MSA Full-Stack 개발자 양성과정 > JSP&Servlet' 카테고리의 다른 글
MSA Full-Stack 개발자 양성 과정 - JSP&Servlet Paging(페이징) 처리_221018 (1) | 2022.10.18 |
---|---|
MSA Full-Stack 개발자 양성 과정 - JSP&Servlet 자료 Up-Download_221012 (0) | 2022.10.12 |
MSA Full-Stack 개발자 양성 과정 - JSP&Servlet Listener(이벤트 핸들러)_221012 (0) | 2022.10.12 |
MSA Full-Stack 개발자 양성 과정 - JSP&Servlet Filter(필터), log 기록_221011 (1) | 2022.10.11 |
[Servlet] annotation과 xml 설정 (0) | 2022.10.11 |