실무에서 사용하는 프레임워크는 크게 3가지로 나눌 수 있다.
1) 스프링
2) 전자정부프레임워크
3) 스프링 기반 자체 프레임워크
위 3가지는 구조가 다 똑같다.
controller.jsp는 어짜피 java이면서 컴파일 될 때 servlet파일로 된다
그럼 java단에서 servlet파일로 만들 수 있는데 이름을 FrontController로 명칭한다.
설정을 적용하는 방법은 xxx.xml (==설정파일)을 등록하면 된다.( Tomcat의 경우 web.xml )
.xml은 무겁고 다루기 어려운(스키마 분석이 어렵다) 단점이 있다.
이 단점을 해결하기 위해 @ (==어노테이션, 애너테이션) webservlet을 등록한다.
다음은 webservlet을 활용한 코드이다.
<FrontController.java>(서블릿 파일)
package controller.common;
import java.io.IOException;
import controller.board.MainAction;
import controller.member.JoinAction;
import controller.member.LoginAction;
import controller.member.LogoutAction;
import controller.page.JoinPageAction;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("*.do") // 어쩌구 저쩌구 .do로 끝나면 여기로 와~! // 서버 start할 때 바로 알아듣는다. // 어노테이션
// 톰캣(server)이 구동될때, xxx.do로 끝나는 요청에 대하여 FC를 호출하게됨
// 설정이 궁금하면 Web.xml을 까봐야 하는데 그게 어려우니까... // xml과 같이하면 충돌이 일어남
// 어노테이션은 반드시 클래스 위에 붙어있어야 함
// servlet파일 만들면 web.xml이 자동으로 생성
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public FrontController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response); // doAction으로 실행
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response); // doAction으로 실행
}
private void doAction(HttpServletRequest request, HttpServletResponse response) { // get으로 오든 post로 오든 다 얘로 실행해줘 // 요즘은 doAction대신 execute로 명칭
// 요청 정보 == request
// 1. 사용자가 무슨 요청을 했는지 추출 및 확인
String uri=request.getRequestURI(); // 무슨 요청을 했나 uri로 확인
String cp=request.getContextPath(); // /xxx.do 전에 경로 // 요청한 uri중 프로젝트 명(경로)을 제거
String command=uri.substring(cp.length()); // uri에서 cp길이(나머지 경로)만큼 잘라버려~ == action number, menu number
System.out.println("command : "+command);
// 2. 요청을 수행
ActionForward forward=null; // forward 다 new해줘야하니까 스코프 밖에서 null로 설정 // 초기화
if(command.equals("/main.do")) { // 요청값이 .do로 끝난다면
/*
// main.jsp에서 보여줘야하는 데이터들이 있나? 확인해봐야함
// 로그인 여부(session에 저장하기 때문에 여기서하는게 아니다!)
BoardDAO boardDAO=new BoardDAO(); // 그동안 jsp에서는 useBean을 통해 4개의 new를 진행했었다.
BoardDTO boardDTO=new BoardDTO(); // servlet에서는 new 2번만 사용한다. == 백단이 가벼워진다, 경제적이다. == 뭐가 사용되었는지 직관적으로 보인다.
ArrayList<BoardDTO> datas=boardDAO.selectAll(boardDTO);
request.setAttribute("datas", datas);
// 게시글 목록만 보여주면됨
pageContext.forward("main.jsp"); // 전달할게 있다 == forward // 내장객체가 없다. 그러므로 pageContext xx
// main.jsp 페이지로 이동
*/
MainAction mainAction=new MainAction();
forward=mainAction.execute(request, response);
}
else if(command.equals("/login.do")) {
/*
MemberDAO memberDAO=new MemberDAO();
// jsp로 작성할떄는 페이지 지시어로 모든 데이터를 new(객체생성, 메모리할당) 해야하지만
// 서블릿으로 작성할때는 필요한 데이터만 new 하면되서 경제적이고, 가벼워진다
// 어떤 데이터가 사용됬는지 직관적으로 확인가능해서 가독성도 증가한다
MemberDTO memberDTO=new MemberDTO();
memberDTO.setMid(request.getParameter("mid"));
memberDTO.setPassword(request.getParameter("password")); // Model에서 뭐가 필요한지 직관적으로 보이기 시작한다.
memberDTO=memberDAO.selectOne(memberDTO);
if(memberDTO!=null) { // 로그인에 성공했을 때
seeeion.setAttribute("loginInfo", memberDTO.getMid)// session에 로그인 정보를 저장
}
*/
LoginAction loginAction=new LoginAction();
forward = loginAction.execute(request, response); // 기존의 요청을 유지해주는 역할을 한다.
}
else if(command.equals("/loginPage.do")) {
JoinPageAction joinPageAction=new JoinPageAction();
forward = joinPageAction.execute(request, response);
}
else if(command.equals("/join.do")) {
JoinAction joinAction=new JoinAction();
forward = joinAction.execute(request, response);
}
else if(command.equals("/logout.do")) {
// new가 0개
LogoutAction logoutAction=new LogoutAction();
forward = logoutAction.execute(request, response);
}
if(command==null) { // 에러페이지로 이동 // 주소가 없을때 // 이상한애가 들어온다면~
// 등록되지 않은 요청입니다.
try {
response.sendRedirect("error.jsp"); // 바로 에러페이지로 이동
} catch (IOException e) {
e.printStackTrace();
}
}
else { // 주소가 있다면, // 이상한 애가 아니라면
if(forward.isRedirect()) { // true면 리다이렉트 방식
try {
response.sendRedirect(forward.getPath());
} catch (IOException e) {
e.printStackTrace();
}
}
else { // false면 포워드 방식
RequestDispatcher dispatcher=request.getRequestDispatcher(forward.getPath());
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
} // 이렇게 되면 controller.jsp가 필요 없어지게 된다.
// 3. 응답(페이지 이동 중) == 어떤 코드를 뜯어봐도 이런 흐름으로 진행된다.
// 한번에 전달한다.
// 1) 전달할 데이터가 있니? 없니? == 포워드? 리다이렉트?
// 2) 그래서 어디로 갈까? == 경로 // 이렇게 2가지만 알면 다 보내줄 수 있다.
// 현재의 FC코드는 응집도가 낮은 상태...
}
}
위 코드로 .do의 모든 요청을 다 받는 서블릿파일을 생성했다.
서블릿 파일에서 모든 요청들을 다 처리할 수도 있지만
위 파일에서 다 처리하게 되면 FC 코드는 응집도가 낮은상태가 된다.
한마디로 서로 관련없는 코드들이 한곳에 저장되어 있게 된다.
그렇게 되면 공동작업이 어렵고 코드작업중에는 해당 페이지 내용 전부 접근 및 이용불가하다.( 가용성이 낮음 )
가용성이 낮아져서 사용자가 이용을 못하는 경우에는
반드시 그 사실을 고지해야 한다.
응집도를 높이려면 XxxAction.java로 나눠서 관리한다.
POJO(프레임 오브 자바 오브젝트)이기 때문에 엄청 가볍다는 장점이 있다.
Not POJO인 서블릿 파일은 FrontController 하나만 있으면된다.
<MainAction.java>( POJO )
package controller.board;
import java.util.ArrayList;
import controller.common.Action;
import controller.common.ActionForward;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import model.dao.BoardDAO;
import model.dto.BoardDTO;
public class MainAction implements Action { // 밖에있는 execute들을 받아와야한다. // 인터페이스에서 메서드 강제
@Override // 오버라이드로 execute메서드 가져온다~!!
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) {
BoardDAO boardDAO=new BoardDAO();
BoardDTO boardDTO=new BoardDTO();
ArrayList<BoardDTO> datas=boardDAO.selectAll(boardDTO);
request.setAttribute("datas", datas);
ActionForward forward=new ActionForward();
forward.setRedirect(false); // 포워드 방식
forward.setPath("main.jsp");
return forward;
}
}
작업중에 많은 Action이 생기게 될 때 메서드를 강제할 수 있게 인터페이스를 사용한다.
<Action.java>( 인터페이스 )
package controller.common;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public interface Action { // 메서드를 강제할 필요가 생겼다.
ActionForward execute(HttpServletRequest request, HttpServletResponse response); // interface action을 써야하는 것이 핵심이다.
}
이 때 Action을 통해 반환해야 하는 것은 2가지로
1. 보내는 방식, 2. 보내는 주소 이다.
JAVA에서 2개이상 반환하기 위해서는 클래스를 만들어야 한다.
<ActionForward.java>( 아웃풋이 2개 이상이라 생성한 클래스 )
package controller.common;
public class ActionForward {
private boolean redirect; // 어떻게 갈지? == 방식 // true면 redirect방식으로 false면 forward방식으로
private String path; // 어디로 갈지? == 경로
public boolean isRedirect() { // getter,setter 해준다
return redirect;
}
public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
2024.08.20
'WEB' 카테고리의 다른 글
| [WEB] 11. 비동기 처리 (0) | 2024.08.23 |
|---|---|
| [WEB] 10. 핸들러맵핑과 싱글톤 패턴 (0) | 2024.08.22 |
| [WEB] 08. jQuery (0) | 2024.08.19 |
| [WEB] 07. JavaScript, xml (0) | 2024.08.16 |
| [WEB] 05. SQL 정규화 (0) | 2024.08.14 |