프로젝트
밀키트 쇼핑몰 프로젝트(2)
코딩하는망아치
2021. 2. 27. 22:10
실행 흐름
OOO.do라는 것이 호출 되었을 때.
1. FrontController.java
// 이런류의 url사이트 처리, 시작하기전에 미리 준비 1순위로
@WebServlet(urlPatterns = "*.do", loadOnStartup = 1)
public class FrontController extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
System.out.println("init() 호출됨");
// application 객체 가져와서 필요한 데이터 저장
ServletContext application = config.getServletContext();
application.setAttribute("aa", "안녕");
String hello = (String) application.getAttribute("aa");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet() 호출됨");
// 요청 주소
// http://localhost:80/funweb-model2/index.do
// > 이 이후 부분이 URI, 실제웹서비스를하면 유일한 주소여야함
// 위치를 나타내는 것이 아니라 식별하는 부분, 통상적으로 URL이라고 얘기를 하지만 정확하게는 URI
// http://localhost:80/index.do
/* 1단계) 명령어 command 구하기 */
// URI 주소 가져오기
String requestURI = request.getRequestURI();
System.out.println("URI 주소: " + requestURI);
// URI 주소: /funweb-model2/index.do
// 프로젝트 이름 경로 가져오기
String contextPath = request.getContextPath(); // 없으면 빈문자열 "" 들어옴
System.out.println("contextPath: " + contextPath);
// contextPath: /funweb-model2
// 요청 명령어 구하기
String command = requestURI.substring(contextPath.length());
// command: /index.do
command = command.substring(0, command.indexOf(".do"));
System.out.println("command: " + command);
// command: /index
/* 2단계) 명령어 실행하기 */ // << 요눔을 우리가 코딩(키맵)
// 이런식(if else)로하면 필요없는코드도 다 노출되어서 좋은게 아님
Controller controller = null;
ControllerFactory factory = ControllerFactory.getInstance(); // new! 객체생성은 동시접속자를 고려해야함 -> 중요한 싱글톤
String strView = null; // 한번 뉴로등록한 컨트롤러객체는 자체가 싱글톤이라 걍 꺼내쓰면됨
// 그치만 컨트롤러팩토리는 아니니가 싱글톤 해줘야겠지
// 명령어에 해당하는 컨트롤러 객체 구하기
controller = factory.getController(command);
if (controller == null) {
System.out.println(command + "를 처리하는 컨트롤러가 없습니다.");
return; // return이니까 여까지하구 서버끝남
}
try {
// 키맵에서의 new 어쩌구Controller에 해당하는 컨트롤러 객체 실행하기
strView = controller.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
/* 3단계) 화면응답(jsp실행) 또는 리다이렉트(.do) 이동 */
if (strView == null) {
System.out.println("이동할 화면정보(View)가 없습니다.");
return;
}
if (strView.startsWith("redirect:")) { // .do로 끝나는 경로
String redirectPath = strView.substring("redirect:".length());
response.sendRedirect(redirectPath);
// index.do?
} else { // index.jsp?
String jspPath = "/WEB-INF/views/" + strView + ".jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(jspPath);
dispatcher.forward(request, response); // 해당 jsp 바로 실행하기 ( 갔다오는 리다이렉트랑은 다름 )
}
} // doGet
2.ControllerFactory.java
//컨트롤러마다 생성자를 프라이빗으로 감추고 세터게터하기 좀 에바니까 싱글톤으로 관리함
public class ControllerFactory {
/* 싱글톤, 스프링가면 애노테이션 한개로 해결가능 */
private static ControllerFactory instance = new ControllerFactory();
public static ControllerFactory getInstance() {
return instance;
}
//////////////////////////////////////////////////////////// 맵을 한개 선언
private Map<String, Controller> map = new HashMap<>();
private ControllerFactory() {
// 키값은 .do로 끝나는 요청 URL주소의 일부 - 명령어
// 명령어와 명령어를 처리하는 컨트롤러 객체를 쌍으로 등록
// 사용자로부터 "" 이러한 요청이오면 new ~ 가 실행된다!
map.put("/index", new IndexController());
// user
map.put("/userJoin", new UserJoinController());
map.put("/joinIdDupCheck", new JoinIdDupCheckController());
map.put("/userJoinPro", new UserJoinProController());
map.put("/userLogin", new UserLoginController());
map.put("/userLoginPro", new UserLoginProController());
map.put("/userLogout", new UserLogoutController());
map.put("/MyPage", new MyPageController());
map.put("/UserUpdate", new UserUpdateController());
map.put("/UserUpdatePro", new UserUpdateProController());
map.put("/UserDelete", new UserDeleteController());
} // 생성자
public Controller getController(String command) {
// Map 컬렉션: 키값없는, 존재하지않는 값을 꺼내면 null을 리턴함
Controller controller = map.get(command);
return controller;
}
}