열심히 끝까지
디바이스 융합 자바(Java) day51 - FrontController 패턴,Request Dispatcher 본문
디바이스 융합 자바(Java) day51 - FrontController 패턴,Request Dispatcher
노유림 2022. 8. 23. 18:24<%@ %>
---------------------
<%@ tag %>
<%@ page %>
<% %>
---------------------
<% out.println(); %>
<%= %>
<jsp: >
V : EL식 / 커스텀태그 / JSTL
M : 리스너 / 트랜잭션
C : 필터 FrontController(FC)
[ C - FrontController 패턴 ]
MVC 패턴 + FC 패턴 => MVC 모델 2
MVC 패턴 : JDBCUtil을 이용해서 db와 관련된 일을 해냄 = ~.java로 작업
M : .java
V : .jsp -> JAVA 코드가 없어야 함
C : ctrlB.jsp | ctrlM.jsp
>> .jsp에서 작업한 C는 결합도가 높음...
-> 분할 관리 => FC 서블릿 파일을 생성해서 관리
-> .jsp vs .java
= 분할 관리 시, .java 이용하는 것이 맞음!
: setProperty 액션을 일일히 해야되나?
>> 네... 일일히 써야 함..
Spring 프레임워크에서 자동매핑 지원해줌!
: request.Xxx() 사용해야되는데???
>> Servlet(서블릿) 파일을 이용할 예정이라 request 사용 가능!
★ 낮은 결합도 & 높은 응집도 => '유지보수에 용이'한 코드 ★
>> FrontController 에서...
public FrontController() { // 기본 생성자
super();
// TODO Auto-generated constructor stub
}
- 서블릿들은 기본 생성자 필수!
> ★ 기본 생성자가 필수인 이유
>> FrontContrller fc = new FrontController();를 한번도 쓴 적이 없음
.. 객체화를 하지 않았는데, 메서드를 사용할 수 있었다...??
>> 서블릿 컨테이너(==객체를 관리하는 것)
== 웹 서버
== 톰캣이 서블릿을 객체화해주고 있었음!
>> 기본 작업
package ctrl;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FrontController
*/
@WebServlet("*.do") // *.do 요청을 수행하면 해당 어노테이션(애노테이션)에 의해 FC로 오게 됨!!!
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public FrontController() { // 서블릿들은 기본 생성자 필수!
// ★ 기본 생성자가 필수인 이유 >> FrontContrller fc = new FrontController();를 한번도 쓴 적이 없음
// 객체화를 하지 않았는데, 메서드를 사용할 수 있었다...??
// 서블릿 컨테이너(==객체를 관리하는 것) == 웹 서버 == 톰캣이 서블릿을 객체화해주고 있었음!
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
actionDO(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
actionDO(request, response);
}
// 직접 만드는 액션
private void actionDO(HttpServletRequest request, HttpServletResponse response) {
String uri=request.getRequestURI();
System.out.println(uri);
}
}
index.jsp---------------------------
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.sendRedirect("index.do"); // ctrlB.jsp?action=main
%>
>> 실행 시
- 화면은 아무것도 안뜸
- 하지만 콘솔은?
FrontController.java의 actionDO------------------
private void actionDO(HttpServletRequest request, HttpServletResponse response) {
String uri=request.getRequestURI();
String cp=request.getContextPath();
System.out.println(uri);
System.out.println(cp);
}
>> 실행결과
FrontController.java의 actionDO------------------
private void actionDO(HttpServletRequest request, HttpServletResponse response) {
String uri=request.getRequestURI();
String cp=request.getContextPath();
String command=uri.substring(cp.length());
System.out.println(uri);
System.out.println(cp);
System.out.println(command);
if(command.equals("/index.do")) {
// 메인 보여주는 C 블러와... 라고 요청
}
}
>> 실행 결과
>> 사용자가 요청하면 그 요청에 맞는 Action 가져옴
/login.do >> LoginAction
/main.do >> MainAction
/logout.do >> LogoutAction
/insertB.do >> InsertBoardAction
/deleteR.do >> DeleteReplyAction
.
.
.
XxxAction => 그냥 일반적인 Controller 역할의 클래스 파일(.java)
>> 내부에는 execute(){} 메서드 존재
execute(){
1. request 요청 정보로부터 데이터를 추출
2. vo 객체에 setter
3. dao 객체에 vo 전달
4. 결과값을 다음 V에게 전달
}
>> ctrl.jsp 에서 하던 작업 순서
>> 2 -> 1 -> 3 -> 4
>> XxxAction에 있는 메서드가 있을 때 필요한 것
: request, response가 반드시 필요함
execute(request, response){
1. request 요청 정보로부터 데이터를 추출
2. vo 객체에 setter
3. dao 객체에 vo 전달
4. 결과값을 다음 V에게 전달
}
>> 반환 타입이 어떤 경로, 어떤 방식으로 보내는가?
: 두개를 동시에 보내지 못한다....
>> 어떤 경로, 어떤 방식을 저장하는 클래스를 생성
: ActionForward 라는 클래스 생성
: String 어떤 경로
boolean 어떤 방식
ActionForward execute(request, response){
1. request 요청 정보로부터 데이터를 추출
2. vo 객체에 setter
3. dao 객체에 vo 전달
4. 결과값을 다음 V에게 전달
}
>> 메서드를 강제하는 "인터페이스(추상 메서드)" 필요!!!
index.jsp---------------
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.sendRedirect("main.do"); // ctrlB.jsp?action=main
// action이라는 파라미터를 쓰지 않아도 되기 때문에
// 파라미터를 하나 덜 씀
%>
[ Request Dispatcher ]
- Spring을 기반으로하는 Dispatcher이지만
Spring에서 쓰는 Dispatcher랑 똑같지는 않음
: 특정 자원에 처리를 요청하고,
그 결과를 얻어오는 기능을 수행하는 클래스
: 사용자(Client, 브라우저)로부터 오는 요청을 처리해서,
그 결과를 설정된 페이지에 출력하는 역할
ex ) RequestDispatcher dispatcher=request.getRequestDispatcher(forward.getPath());
>> forward.getPath() : 어느 페이지로 갈지 언급해주는 부분
>> dispatcher.forward(request, response);
: 타겟페이지(forward.getPath())(미리 작성해 놓은 인자)로
request, response 객체를 전달하는 메서드
: 페이지 제어권을 넘겨줌 -> 클라이언트가 응답을 확인할 수 있음
FrontController.java--------------------------------------
package ctrl;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FrontController
*/
@WebServlet("*.do") // *.do 요청을 수행하면 해당 어노테이션(애노테이션)에 의해 FC로 오게 됨!!!
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public FrontController() { // 서블릿들은 기본 생성자 필수!
// ★ 기본 생성자가 필수인 이유 >> FrontContrller fc = new FrontController();를 한번도 쓴 적이 없음
// 객체화를 하지 않았는데, 메서드를 사용할 수 있었다...??
// 서블릿 컨테이너(==객체를 관리하는 것) == 웹 서버 == 톰캣이 서블릿을 객체화해주고 있었음!
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
actionDO(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
actionDO(request, response);
}
// 직접 만드는 액션
private void actionDO(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
String uri=request.getRequestURI();
String cp=request.getContextPath();
String command=uri.substring(cp.length());
System.out.println(uri);
System.out.println(cp);
System.out.println(command);
ActionForward forward = null;
if(command.equals("/main.do")) {
// 메인 보여주는 C 블러와... 라고 요청
try {
forward = new MainAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/logout.do")){
try {
forward = new LogoutAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/login.do")){
try {
forward = new LoginAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/insert.do")){
try {
forward = new InsertMemberAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/insertB.do")){
try {
forward = new InsertBoardAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/insertR.do")){
try {
System.out.println("R들어옴");
forward = new InsertReplyAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/deleteB.do")){
try {
forward = new DeleteBoardAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/deleteR.do")){
try {
forward = new DeleteReplyAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(command.equals("/fav.do")){
try {
forward = new FavAction().execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
if(forward==null) { // forward가 null이면 error 페이지로 가!
forward=new ActionForward();
forward.setPath("error/error.jsp");
forward.setRedirect(false);
}
RequestDispatcher dispatcher=request.getRequestDispatcher(forward.getPath());
try {
dispatcher.forward(request, response);
// : 타켓페이지(인자)로 request, response 객체를 전달하는 메서드
// : 제어권을 넘겨줌 -> 클라이언트가 응답을 확인할 수 있음
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
if(forward!=null) {
// 디스패쳐 만들어서 타겟페이지로 이동
if(forward.isRedirect()) {
response.sendRedirect(forward.getPath());
}
else {
RequestDispatcher dispatcher=request.getRequestDispatcher(forward.getPath());
dispatcher.forward(request, response); // 정확하게 언급 했을 때 수행
}
}
// 권장하지 않음(script는 jsp에서 쓰는것이 맞음)
// alert창을 쓰고 싶으면 java가 아닌 서블릿에서 작성해야 함
PrintWriter out = response.getWriter();
out.println("<script>alert('요청처리 실패!');history.go(-1);</script>");
}
}
InsertBoardAction.java-----------------------
package ctrl;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import board.BoardDAO;
import board.BoardVO;
public class InsertBoardAction implements Action{
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
BoardDAO dao = new BoardDAO();
BoardVO vo = new BoardVO();
vo.setMsg(request.getParameter("msg"));
vo.setMid(request.getParameter("mid"));
System.out.println("로그 : vo.mid값 = " + vo.getMid());
if(dao.insert(vo)) {
ActionForward forward= new ActionForward();
forward.setPath("main.do");
forward.setRedirect(true);
return forward;
}
else {
System.out.println("로그 : 글 추가 실패");
throw new Exception("InsertB 오류");
}
}
}
DeleteBoardAction.java-----------------------
package ctrl;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import board.BoardDAO;
import board.BoardVO;
public class DeleteBoardAction implements Action{
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward=null;
BoardDAO dao = new BoardDAO();
BoardVO vo = new BoardVO();
vo.setBid(Integer.parseInt(request.getParameter("bid")));
if(dao.delete(vo)) {
forward = new ActionForward();
forward.setPath("main.do");
forward.setRedirect(false);
}
else {
System.out.println("로그 : 글 삭제 오류");
throw new Exception("DeleteB 오류");
}
return forward;
}
}
mainAction.java-----------------------
package ctrl;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import board.BoardDAO;
import board.BoardSet;
import board.BoardVO;
public class MainAction implements Action{
@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 요청정보 인코딩을 안했다면 꼭 해줄 것
// request.setCharacterEncoding("UTF-8");
// response.setCharacterEncoding("UTF-8");
// 2. 로직 처리
// 2-1. Board 필요
BoardDAO dao= new BoardDAO();
BoardVO vo = new BoardVO();
// 2-2. 요청정보 세팅 - main은 cnt만 받아와서 세팅하면 됨
// vo.setCnt(Integer.parseInt(request.getParameter("cnt")));
String paramCnt=request.getParameter("cnt");
if(paramCnt==null) {// cnt 파라미터에 정보가 있어?
vo.setCnt(2);
}
else {
vo.setCnt(Integer.parseInt(request.getParameter("cnt")));
}
ArrayList<BoardSet> datas = dao.selectAll(vo);
request.setAttribute("datas", datas);
request.setAttribute("cnt", vo.getCnt());
// 3. 정보 보내주기
ActionForward forward = new ActionForward();
forward.setPath("/main.jsp");
forward.setRedirect(false);
return forward;
}
}
/*
ArrayList<BoardSet> datas = bDAO.selectAll(bVO);
request.setAttribute("datas", datas);
request.setAttribute("cnt", bVO.getCnt());
pageContext.forward("main.jsp");
*/
'디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)' 카테고리의 다른 글
디바이스 융합 자바(Java) day53 - AJAX 이용한 아이디 중복 체크 (0) | 2022.08.25 |
---|---|
디바이스 융합 자바(Java) day52 - 팀프로젝트 작업 및 frontController 질문 및 답변 (0) | 2022.08.24 |
디바이스 융합 자바(Java) day50 - 회원가입 새 창 띄우기,더보기 갯수 한 곳에서 지정,커스텀태그 (0) | 2022.08.22 |
디바이스 융합 자바(Java) day49 - 설계 작업 + 게시판(SNS) + 댓글 넣는 작업 (0) | 2022.08.19 |
디바이스 융합 자바(Java) day48 - 리스너(Listener)(초기화 매개변수),필터(Filter) (0) | 2022.08.18 |