JSP & Servlet : Pojo 1-1

지환·2023년 12월 6일
0

Jsp & Servlet

목록 보기
13/21
post-thumbnail

우선 최종코드를 먼저 공유하겠다.

FrontMVC.java

package com.example.demo.pojo1;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;

/**
 *  * **********@Insert : @int (입력)***********
 * http://localhost:8000/member/memberInsert.gd
 * http://localhost:8000/lecture/lectureInsert.gd
 * http://localhost:8000/notice/noticeInsert.gd
 * 
 * 
 *  * ******@Update : @int ***********
 * http://localhost:8000/member/memberUpdate.gd
 * http://localhost:8000/lecture/lectureUpdate.gd
 * http://localhost:8000/notice/noticeUpdate.gd
 * 
 * 
 * *******@Delete : @int ***********
 * http://localhost:8000/member/memberDelete.gd
 * http://localhost:8000/lecture/lectureDelete.gd
 * http://localhost:8000/notice/noticeDelete.gd
 * 
 * ==============================
 * select(dispatcher(forward)) - false 
 * select - forward - false
 * ********@Select : List<Map> - dispatcher ********** 
 *
 * http://localhost:8000/member/memberSelect.gd
 * http://localhost:8000/lecture/lectureSelect.gd
 * http://localhost:8000/notice/noticeSelect.gd
 * 
 * 
 */

@WebServlet("*.gd")
public class FrontMVC extends HttpServlet {
	Logger logger = LoggerFactory.getLogger(FrontMVC.class);
	private static final long serialVersionUID = 1L;

	protected void doService(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("FrontMVC 클래스에 doService메소드에 들어왔습니다.");
		String  uri = req.getRequestURI(); // => /notice/noticeInsert.gd
		String context = req.getContextPath();// /
		String command = uri.substring(context.length()+1);//-> notice/noticeInsert.gd
		//뒤에 의미없는 확장자 gd를 잘라내기
		int end = command.lastIndexOf(".");//점이 있는 위치정보를 가져온다
		command =  command.substring(0,end);//-> notice/noticeInsert까지만 가져온다. .gd는 빼고서....
		String upmu[] = null;
		upmu = command.split("/");

		ActionForward af = null;
		NoticeController nc = new NoticeController();//결합도가 강하다-별로다-제어역전아니다
		//MemberController mc = new MemberController();
		//LectureController lc = new LectureController();
		////////////////////////[[  어떤 컨트롤러를 태울것인가? ]]/////////////////////////
		//이 지점은 내려가는 방향이다
		if("notice".equals(upmu[0])) {
			//왜 NoticeController클래스에 upmu[]을 넣어주나요? - 메소드
			//메소드 이름을 가지고 NoticeController에서 if문(조건식이 필요함-upmu[1])을 적어야 한다.
			//4가지 - noticeList, noticeInsert, noticeUpdate, noticeDelete
			//왜냐면 NoticeController에서 NoticeLogic클래스를 인스턴스화 해야 하니까
			//왜요? NoticeLogic에 정의된 메소드를 여기서 호출해야 하니까...
			//설계 관점 아쉬움 - 우리는 XXXController에서 부터 메소드를 가질 수 없었나?
			//이유- 나는 아직은 메소드마다 req, res에 대한 객체 주입을 처리할 수 없는 구조이니까
			req.setAttribute("upmu",upmu);
			af = nc.execute(req, res);//NoticeController클래스로 건너감 - upmu[1]-메소드이름이니까...
		}

		else if("member".equals(upmu[0])) {
			
		}
		else if("lecture".equals(upmu[0])) {
			
		}
		
		
		//////////////////////[[ 컨트롤을 타고 난 뒤에 내가 할일은? ]]///////////////////////
		//해당 업무에 대응하는 컨트롤러에서 결정된 페이지 이름을 받아온다
		//위에서 결정된 true 혹은 false값에 따라 sendRedirect와 forward를 통해
		//응답페이지를 호출해준다. - 이것이 FrontMVC의 역할이다.
		//이 지점은 java와 오라클 서버를 경유한 뒤 시점이다.
		if(af !=null) {
			if(af.isRedirect()) {
				res.sendRedirect(af.getPath());
			}
			else{
				RequestDispatcher view = req.getRequestDispatcher(af.getPath());
				view.forward(req, res);
			}
		}/////////// end of if - 응답페이지 호출하기 - 포워드		
		
		//////////////////////////////////////////////////////////////////
		
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		doService(req,res);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		doService(req,res);
	}
	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		logger.info("doPut- 수정할때");
		String n_no = req.getParameter("n_no");
		String n_title = req.getParameter("n_title");
		String n_content = req.getParameter("n_content");
		String n_writer = req.getParameter("n_writer");
		logger.info(n_no+", "+n_title+", "+n_content+", "+n_writer);
	}
	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		logger.info("doDelete- 삭제할때");
		String n_no = req.getParameter("n_no");
		logger.info(n_no);		
	}

}



////////////////////[[ 어떤 컨트롤러를 태울 것인가?]]//////////////////////



////////////////////[[ 컨트롤을 타고 난 뒤에 내가 할일은?]]//////////////////////
// 해당 업무에 대응하는 컨트롤러에서 결정된 페이지 이름을 받아온다.
// 위에서 결정된 true 혹은 false 값에 따라 sendRedirect() 와 forward를 통해
// 응답 페이지를 호출해준다. -  FrontMVC의 역할이다.




NoticeController

package com.example.demo.pojo1;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

// 여기로 넘어왔다는 얘기 자체가 

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/*
 * NoticeController는 서블릿을 상속받지 않았다. 왜냐하면 결합도를 낮추고 싶어서. - 그게 프레임워크의 중요 사상중에 하나 이니까.
 * 서블릿이 아닌데 req와 res는 어디서 주입받죠? - doGet(req, res) 이런게 필요...
 */
public class NoticeController implements Action {
	Logger logger = LoggerFactory.getLogger(NoticeController.class);
	NoticeLogic nLogic = new NoticeLogic();//이른
	//->http://localhost:8000/notice/noticeInsert.gd?n_title=%EC%9D%B4%EB%B2%A4%ED%8A%B8&n_content=%EB%82%B4%EC%9A%A9&n_writer=%EA%B4%80%EB%A6%AC%EC%9E%90
	//-> 저렇게 n_title , n_content,  n_writer 세개의 값을 줬는데 결과값으로 {null,null,null}이 나올까?
	// 어떤 문제를 보는거냐면 jsp - 입력 - action(insert) - 1 - 성공 - action(select) - jsp 이렇게 했을 떄 
	// select를 [자바]logic에서 1로 설정했다.
	// doService[FrontMVC] -> Insert[]를 타고 갔다. -> 
	// logger.info(n_title+", "+n_content+", "+n_writer); null값으로 전부 나옴 왜? 값을 불러오지 않았으니깐 
	// 
	
	
	@Override
	public ActionForward execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		String n_title = req.getParameter("n_title");
		String n_content = req.getParameter("n_content");
		String n_writer = req.getParameter("n_writer");
		logger.info(n_title+", "+n_content+", "+n_writer);	// null,null,null 값이 출력된다.	
		String upmu[] = (String[])req.getAttribute("upmu");
		ActionForward af = new ActionForward();
		StringBuilder path = new StringBuilder();
		boolean isRedirect = false;
		path.append("/notice/");
		if("noticeList".equals(upmu[1])) {//select
			logger.info("NoticeController 클래스에서 if문 noticeList에 들어왔습니다.");
			List<Map<String ,Object>> nList = null;
			nList = nLogic.noticeList();
			//원본에다가 담아 두자
			req.setAttribute("nList", nList);
			path.append("noticeList.jsp");
			isRedirect = false;//false이면 forward처리됨
		}
		//화면 출력을 ReactJS와 같이 다른 언어 다른 라이브러리를 사용하여 처리해야 할땐
		//Back-End에서 해야될 일은 JSON포맷으로 응답이 나가도록 처리해주면 된다.
		//POJO 1-3버전에서는 이 부분도 공통코드로 담아 본다
		else if("jsonNoticeList".equals(upmu[1])) {//select
			logger.info("NoticeController 클래스에서 if문 jsonNoticeList에 들어왔습니다.");
			List<Map<String ,Object>> nList = null;
			nList = nLogic.noticeList();
			//원본에다가 담아 두자
			req.setAttribute("nList", nList);
			path.append("jsonNoticeList.jsp");
			isRedirect = false;//false이면 forward처리됨
		}		
		//jsp - 입력 - action(insert) - 1 - 성공 - action(select) - jsp
		else if("noticeInsert".equals(upmu[1])) {//insert
			logger.info("NoticeController 클래스에서 if문 noticeInsert에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeInsert();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}
		}else if("noticeUpdate".equals(upmu[1])) {//update
			logger.info("NoticeController 클래스에서 if문 noticeUpdate에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeUpdate();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}
			
		}else if("noticeDelete".equals(upmu[1])) {//delete
			logger.info("NoticeController 클래스에서 if문 noticeDelete에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeDelete();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}	
		}
		af.setPath(path.toString());
		af.setRedirect(isRedirect);
		return af;
	}

}

NoticeLogic

package com.example.demo.pojo1;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.util.MyBatisCommonFactory;
//PURE - 다른 디바이스에 넣어도 잘 동작하면 좋겠어
//어떠한 인터페이스나 추상클래스도 상속받지 않았다 - 자랑
public class NoticeLogic {
	Logger logger = LoggerFactory.getLogger(NoticeLogic.class);
	SqlSessionFactory sqlSessionFactory = null;
	public List<Map<String,Object>> noticeList(){
		logger.info("NoticeLogic클래스 안 noticeList에 들어왔습니다.");
		List<Map<String,Object>> nList = new ArrayList<>();
		sqlSessionFactory = MyBatisCommonFactory.getSqlSessionFactory();
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			nList = sqlSession.selectList("noticeList");
			logger.info(nList.toString());
		} catch (Exception e) {
			logger.info(e.toString());
		}
		return nList;
	}
	public int noticeInsert(){
		logger.info("NoticeLogic 클래스 noticeInsert이 실행중입니다.");
		int result = 0;
		result = 1;
		return result;
	}
	public int noticeUpdate(){
		logger.info("NoticeLogic 클래스 noticeUpdate이 실행중입니다.");
		int result = 0;
		return result;
	}
	public int noticeDelete(){
		logger.info("NoticeLogic 클래스 noticeDelete가 실행중입니다.");
		int result = 0;
		return result;
	}
}

ActionForward.java

package com.example.demo.pojo1;

public class ActionForward {
	 private String path = null;
	 private boolean isRedirect = false;
	
	 
	 public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public boolean isRedirect() {
		return isRedirect;
	}
	public void setRedirect(boolean isRedirect) {
		this.isRedirect = isRedirect;
	}
	 
	 
}

Action[추상클래스]

package com.example.demo.pojo1;

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


public interface Action {
	public ActionForward execute(HttpServletRequest req, HttpServletResponse res)
	throws ServletException, IOException;
}

NoticeVO.java

package com.example.demo.pojo1;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class NoticeVO {
	private int n_no = 0;
	private String n_title = null;
	private String n_content = null;
	private String n_writer = null;
}

소스리뷰

Insert 할때

이번 Pojo1-1에선 테스트 케이스에 따라 실행방법이 달라지니 경우를 나눠서 실행하겠다.

  1. Insert 할때,
    Test Case ) http://localhost:8000/notice/noticeInsert.gd?n_title=%EC%9D%B4%EB%B2%A4%ED%8A%B8&n_content=%EB%82%B4%EC%9A%A9&n_writer=%EA%B4%80%EB%A6%AC%EC%9E%90
  • jsp - 입력 - action(insert) - 1 - 성공 - action(select) - jsp 이렇게 진행되는데,

    이 순서로 진행되는데 한 번 증명해보자.

    중요한 부분은 jsp - 입력(insert) - 1로 옮겨졌을 떄, 성공 처리 시 (sendRedirect로 진행된다.)

    로그 순서

    [FrontMVC.java : 51]{FrontMVC 클래스에 doService메소드에 들어왔습니다.}
    
    [NoticeController.java : 47]{이벤트, 내용, 관리자}
    
    [NoticeController.java : 76]{NoticeController 클래스에서 if문 noticeInsert에 들어왔습니다.}
    
    [NoticeLogic.java : 32][32m{NoticeLogic 클래스 noticeInsert이 실행중입니다.}
    
     ==============================Insert 처리 성공 시===========================
    ==============================SendRedirect 했기 때문에 null=====================
    	
     ===============[Select zone[action]]==============
      
    [FrontMVC.java : 51]{FrontMVC 클래스에 doService메소드에 들어왔습니다.}
    
    [NoticeController.java : 47]{null, null, null}
    
    [NoticeController.java : 54]{NoticeController 클래스에서 if문 noticeList에 들어왔습니다.}
    
    [NoticeLogic.java : 19]{NoticeLogic클래스 안 noticeList에 들어왔습니다.}
    
    [NoticeLogic.java : 25]{[{N_TITLE=휴관일, N_WRITER=관리자, N_CONTENT=이번주 일요일은 휴관일입니다., N_NO=1}]}
    

    이 부분에 있어 일대일 대응하여 코드를 설명하겠다.

    FrontMVC에 대한 설명

    	protected void doService(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    			logger.info("FrontMVC 클래스에 doService메소드에 들어왔습니다.");
    			String  uri = req.getRequestURI(); // => /notice/noticeInsert.gd
    			String context = req.getContextPath();// /
    			String command = uri.substring(context.length()+1);//-> notice/noticeInsert.gd
    			//뒤에 의미없는 확장자 gd를 잘라내기
    			int end = command.lastIndexOf(".");//점이 있는 위치정보를 가져온다
    			command =  command.substring(0,end);//-> notice/noticeInsert까지만 가져온다. .gd는 빼고서....
    			String upmu[] = null;
    			upmu = command.split("/");
    
    			ActionForward af = null;
    			NoticeController nc = new NoticeController();//결합도가 강하다-별로다-제어역전아니다
    			if("notice".equals(upmu[0])) {
    				req.setAttribute("upmu",upmu);
    				af = nc.execute(req, res);//NoticeController클래스로 건너감 - upmu[1]-메소드이름이니까...
    			}
    
    			else if("member".equals(upmu[0])) {
    			
    			}
    			else if("lecture".equals(upmu[0])) {
    			
    			}
    		
    		
    			if(af !=null) {
    				if(af.isRedirect()) {
    					res.sendRedirect(af.getPath());
    				}
    				else{
    					RequestDispatcher view = req.getRequestDispatcher(af.getPath());
    					view.forward(req, res);
    				}
    			}/////////// end of if - 응답페이지 호출하기 - 포워드		
    		
    			//////////////////////////////////////////////////////////////////
    		
    		}
    • 사용자가 url창을 화면에 입력하면 FrontMVC 서블릿(서버)에 요청한다.

      • @WebServlet(".gd")라고 하면 "url에 창에 .gd로 끝나는 url은 내가 전부 가로챌게"와 같은 의미이다.

      • 이렇게 URL이 들어오면 배열로 변환해서 저장한다.(이 부분에 관련된 부분은 앞 게시물에 있다)
      					ActionForward af = null;
      					NoticeController nc = new NoticeController();//결합도가 강하다-별로다-제어역전아니다
      					if("notice".equals(upmu[0])) {
      						req.setAttribute("upmu",upmu);
      						af = nc.execute(req, res);//NoticeController클래스로 건너감 - upmu[1]-메소드이름이니까...
      					}
      
      					else if("member".equals(upmu[0])) {
      			
      					}
      					else if("lecture".equals(upmu[0])) {
      			
      					}
      		
      		
      					if(af !=null) {
      						if(af.isRedirect()) {
      							res.sendRedirect(af.getPath());
      						}
      						else{
      							RequestDispatcher view = req.getRequestDispatcher(af.getPath());
      							view.forward(req, res);
      						}
      					}/////////// end of if - 응답페이지 호출하기 - 포워드		
      		
      					//////////////////////////////////////////////////////////////////
      		
      				}
      • 이제 배열로 저장된 upmu[]를 setAttribute로 NoticeController에 전달한다.

      • NoticeController에서 전달하는 과정이 중요한데, NoticeController클래스는 ActionForward를 리턴타입으로 가지고 있다. [Action 구현체 클래스-NoticeController]

      • 왜 Action인터페이스를 설계해서 ActionForward라는 불변객체를 만들고, 경로(SendRedirect , forward)를 담은 결과를 리턴한다. Action을 만든 이유는 클래스들 끼리 결합도를 낮추기 위해 사용했다.

      • 다음 중요한 부분은 FrontMVC는 HttpServlet를 상속받고 있다. 특이점은 일반적으로 구현 시 doGet, doPost를 RESTful Api에 따라 나눠서 처리하지만,

        • doService로 묶어서 doPost/doGET으로 오는 요청을 하나로 묶었다.
      • 추가적으로 req.setAttribute("upmu",upmu); 부분은 noticeController에 배열의 정보를 넘겨주기 위해 사용한다.
        - 이 부분도 유심히 봐야 되는 부분인데, req에 대한 리턴타입이 void이기 때문에 다른 page 및 서블릿끼리의 데이터 전달에 대한 부분을 req.setAttribute("upmu",upmu);, req.getAttribute("upmu")으로 받아온다.

      • 이 부분은 현재 HttpServlet를 상속받은 Tocat이 관리하는 req,res(원본)를 넘겨준다. nc.execute에 (noticeController)에
        excute에 대한 리턴값은 actionForward이다.
      af = nc.execute(req, res);
      
      입장 완료
      [FrontMVC.java : 51]{FrontMVC 클래스에 doService메소드에 들어왔습니다.}
      

execute -> NoticeController 계층을 살펴보자.

url TestCase) http://localhost:8000/notice/noticeInsert.gd?n_title=%EC%9D%B4%EB%B2%A4%ED%8A%B8&n_content=%EB%82%B4%EC%9A%A9&n_writer=%EA%B4%80%EB%A6%AC%EC%9E%90

	@Override
	public ActionForward execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		String n_title = req.getParameter("n_title");
		String n_content = req.getParameter("n_content");
		String n_writer = req.getParameter("n_writer");
		logger.info(n_title+", "+n_content+", "+n_writer);	// null,null,null 값이 출력된다.	
		String upmu[] = (String[])req.getAttribute("upmu");
		ActionForward af = new ActionForward();
		StringBuilder path = new StringBuilder();
		boolean isRedirect = false;
		path.append("/notice/");

여기서 logger.info부분이 찍힌다.
req.getParameter라고하면 url창에서 n_content= ? / n_writer=? 라고 찍은 부분이다. 당연히 이 부분이 로그에 찍히고 그 부분이

[NoticeController.java : 47]{이벤트, 내용, 관리자} 이다.
  • 배열을 FrontMVC에서 넘겨받고, 0번 인덱스, 1번 인덱스를 가지고 있다.

    • ActionForward에 대한 부분을 설명해보자.

    왜? StringBuilder path 와 boolean isRedirect 변수를 선언 했을까?

  • 최종적으로 return af를 하는데, 그 때 if문을 분기한 다음에 결과적으로 나온 경로를 setisRedirect() , setpath() 한다. 이와 같은 이유로 변수를 선언한 것이다.

  • StringBuilder로 쓴 이유는 String으로 new하게 되면 우선 메모리 낭비가 심하기 때문에 StringBuilder로 사용했다.

    • StringBuilder는 기존 문자열을 복사하지 않고 직접 변경하는데, 이로써 성능 상 이점이 있다.
    • 문자열을 동적으로 조작할 수 있게 해주며, 수정이 가능한 가변(mutable)한 문자열을 제공한다.
  • 처음은 당연히

    path.append("/notice/");

    를 한다. url주소를 슬라이싱해서 보면 이해가 쉽다.


if문 부분을 자세히 뜯어보겠다.

if("noticeList".equals(upmu[1])) {//select
			logger.info("NoticeController 클래스에서 if문 noticeList에 들어왔습니다.");
			List<Map<String ,Object>> nList = null;
			nList = nLogic.noticeList();
			//원본에다가 담아 두자
			req.setAttribute("nList", nList);
			path.append("noticeList.jsp");
			isRedirect = false;//false이면 forward처리됨
		}
		//화면 출력을 ReactJS와 같이 다른 언어 다른 라이브러리를 사용하여 처리해야 할땐
		//Back-End에서 해야될 일은 JSON포맷으로 응답이 나가도록 처리해주면 된다.
		//POJO 1-3버전에서는 이 부분도 공통코드로 담아 본다
		else if("jsonNoticeList".equals(upmu[1])) {//select
			logger.info("NoticeController 클래스에서 if문 jsonNoticeList에 들어왔습니다.");
			List<Map<String ,Object>> nList = null;
			nList = nLogic.noticeList();
			//원본에다가 담아 두자
			req.setAttribute("nList", nList);
			path.append("jsonNoticeList.jsp");
			isRedirect = false;//false이면 forward처리됨
		}		
		//jsp - 입력 - action(insert) - 1 - 성공 - action(select) - jsp
		else if("noticeInsert".equals(upmu[1])) {//insert
			logger.info("NoticeController 클래스에서 if문 noticeInsert에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeInsert();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}
		}else if("noticeUpdate".equals(upmu[1])) {//update
			logger.info("NoticeController 클래스에서 if문 noticeUpdate에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeUpdate();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}
			
		}else if("noticeDelete".equals(upmu[1])) {//delete
			logger.info("NoticeController 클래스에서 if문 noticeDelete에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeDelete();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}	
		}
		af.setPath(path.toString());
		af.setRedirect(isRedirect);
		return af;
	}

noticeList

  		if("noticeList".equals(upmu[1])) {//select
			logger.info("NoticeController 클래스에서 if문 noticeList에 들어왔습니다.");
			List<Map<String ,Object>> nList = null;
			nList = nLogic.noticeList();
			//원본에다가 담아 두자
			req.setAttribute("nList", nList);
			path.append("noticeList.jsp");
			isRedirect = false;//false이면 forward처리됨
		}
  • 배열에 저장되어있는 1번방에 있는(메소드명)를 꺼내와서 비교 후 같으면 if문을 실행한다.

  • SELECT문에 대한 결과를 처리하는 곳은 (nLogic- 순수 자바 객체)이다. 그 값을 List형태로 받아온 다음

  • 여기서 req.setAttribute("nList", nList); 한다

    • 왜 여기서 req.setAttribute를하지?

    • jsp 스트리트릿에서 출력해보려면 이 곳에서 req.setAttribute로 보내야된다.

    • 이 곳에서만 가능한가? => yes 만약에 FronMVC에서 하게 된다면, 디비의 값을 받아오지 못하며, 설계상 NoticeController에서 jsp로 값을 보내야된다.

    • 중요한 점은 FrontMVC에서 req.setAttribute를 하지 않았다는 것이다.(시점의 문제가 발생한다)

      jsp에서 어떻게 받아올까?

      이런식으로 받아온다.

  • 다음에 path.append("noticeList.jsp");하고 지금까지 path에 대한 경로는
    path: /notice/jsonNoticeList.jsp 가된다. noticeList에 대한 처리가 완료되면 isRedirect = false; 처리되면

    		af.setPath(path.toString());
    			af.setRedirect(isRedirect);
    			return af;
  • 이렇게 경로를 담고 리턴한다.(NoticeController->FrontMVC)

  • 이 때 경로는 path와 isRedirect 값을 가지고 있다.

if(Insert문)을 살펴보자.

		else if("noticeInsert".equals(upmu[1])) {//insert
			logger.info("NoticeController 클래스에서 if문 noticeInsert에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeInsert();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}
		}
  • Insert문은 다른 DML보다 특이한점이 존재한다. 그 이유는 작동순서를 살펴보자. (큰 틀)

Jsp -> doService -> NoticeController(insert시작) -> nLogic.noticeInsert()시작-> 디비리턴값(1,0) -> (1로 설정 했음(SELECT 때문에) -> (result=1)를 담고 -> doService에서 경로를 탄다. -> SendRedirect 실행한다. (이 때 url 바뀜)

doService 실행->그래서 값이 null, null, null로 받아온다. noticeController -> noticeList에 들어옴 -> 처리 후 화면에 뿌려짐

경로를 한 번 쪼개보자. url창이 언제 바뀌는 것인가?

http://localhost:8000/notice/noticeInsert.gd?n_title=%EC%9D%B4%EB%B2%A4%ED%8A%B8&n_content=%EB%82%B4%EC%9A%A9&n_writer=%EA%B4%80%EB%A6%AC%EC%9E%90 에서

http://localhost:8000/notice/noticeList.gd 왜 이렇게 됐을까?

sendRedirect 주소를 먼저 보자. af의 path와 isRedirect 2가지를 살펴보면 알 수 있는 부분이다.

insert를 처리하면 경로가 path : /notice/noticeList.jsp 되고isRedirect : true이다.

왜? /notice/noticeList.jsp인가?

분명히 Insert인데 noticeList를 경로로 설정하는가?

이 부분을 이해하려면 이 부분 역시 로직을 이해해야한다.

jsp - 입력 - action(insert) - 1 - 성공 - action(select) - jsp 로 진행이 되는데, insert는 디비쪽에서 진행하게 된다

	public int noticeInsert(){
		logger.info("NoticeLogic 클래스 noticeInsert이 실행중입니다.");
		int result = 0;
		result = 1;
		return result;
	}

아직 Dao 클래스가 구현되어 있지 않아서 부족하지만, SELECT문을 보면 비교적 이해하기 쉽다.

	public List<Map<String,Object>> noticeList(){
		logger.info("NoticeLogic클래스 안 noticeList에 들어왔습니다.");
		List<Map<String,Object>> nList = new ArrayList<>();
		sqlSessionFactory = MyBatisCommonFactory.getSqlSessionFactory();
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			nList = sqlSession.selectList("noticeList");
		} catch (Exception e) {
			logger.info(e.toString());
		}
		return nList;
	}

nList를 통해서 오라클에서 값을 받아온다.

이 부분과 동일하게 insert문 실행 시 sqlSession처리를 진행 할 것이고, 처음 로직을 탄 순간부터(NoticeLogic) insert문에 대한 처리를 완료한다. 처리를 완료 했을 떄(1)를 기준으로 result가 기존엔 0이였지만, result를 1로 설정하면서 result =1로 재정의하여 return 한다.

코드로 설명하면,

	else if("noticeInsert".equals(upmu[1])) {//insert
			logger.info("NoticeController 클래스에서 if문 noticeInsert에 들어왔습니다.");
			int result = 0;
			result = nLogic.noticeInsert();
			if(result == 1) {
				path.append("noticeList.gd");
				isRedirect = true;
			}else {
				path.append("noticeError.jsp");
				isRedirect = true;
			}
		}  
  
  • result = nLogic.noticeInsert(); 이 부분에서 insert문을 진행한다. result값을 받아온 다음에(insert문에 대한 처리는 끝남)

  • 그 값으로 SELECT문을 진행하는 것이다. 경로를 SELECT로 잡아야 되기 때문에 (result ==1) 로 잡고 url를 추가한다.
    path.append("noticeList.gd"); 리다이렉트를 위해 ture로 변환를 한 것이다.

  • 그렇다면 insert문을 실행하게 되면 마지막에 return af에 대한 경로는

    path : /notice/noticeList.gd로 되어있고
    isRedirect : true 이다.

    이 값을 가지고 (NoticeController -> FrontMVC)

  • execute에 대한 리턴값을 받고 경로 설정에 대한 if문 분기에 들어간다.

    🎇🎇🎇 이 때 로그를 읽으면 (SendRedirect 실행합니다~)이다. 이 때 url 변동이 일어난다.🎇🎇🎇

Step2

  • 그리고 나서 변동된 url : /notice/noticeList.gd 로 다시 url 쪼개기를 진행하고

  • notice[0] || noticeList[1] 이렇게 또 noticeController에 넘겨준다. -> 넘겨준 배열에서 1번 인덱스를 비교하고

  • 맞는 if문에 들어가서 nLogic를 수행한다. 이 때 SELECT는 forward 방식으로 진행되며, 디비에서 꺼내온 값을 브라우저에 뿌린다.

    • 브라우저에 뿌린다. 브라우저에 뿌릴 떄, req.setAttribute는 NoticeController 계층에서 작동한다는점 절대 잊으면 안 된다.
    		if("noticeList".equals(upmu[1])) {//select
    				logger.info("NoticeController 클래스에서 if문 noticeList에 들어왔습니다.");
    				List<Map<String ,Object>> nList = null;
    				nList = nLogic.noticeList();
    				//원본에다가 담아 두자
    				req.setAttribute("nList", nList);
    				path.append("noticeList.jsp");
    				isRedirect = false;//false이면 forward처리됨
    			}
    

만약에 리액트랑 연동한다면?

jsonNotice.jsp

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ page import="java.util.*, com.google.gson.Gson" %>
<%
	//서블릿(FrontMVC)을 경유[NoticeController-> NoticeLogic]하고 
	//select한 결과를 돌려(List<Map>) 받아서 request객체에 담아 두었다
	//                                                    req.setAttribute("xList", nList);
	//out.print("<br>");
	List<Map<String,Object>> nList = (List)request.getAttribute("nList");
	Gson g = new Gson();
	String temp = g.toJson(nList);
	out.print(temp);
%>     
  • 마임타입 유심히 봐라

http://localhost:8000/notice/jsonNoticeList.gd

이렇게 호출하면

이렇게 나옴


POST맨 이용방법

우리가 목업을 사용할 때, post 방식으로 전달 할 떄,

이런식으로 단위테스트가 가능하다.

delete 방식

만약에 http://localhost:8000/notice/noticeDelete.gd 이렇게 send를 누르면 서버에서 응답값을 내보낸다.

	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		logger.info("doDelete- 삭제할때");
		String n_no = req.getParameter("n_no");
		logger.info(n_no);		
	}

put 방식

  	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		logger.info("doPut- 수정할때");
		String n_no = req.getParameter("n_no");
		String n_title = req.getParameter("n_title");
		String n_content = req.getParameter("n_content");
		String n_writer = req.getParameter("n_writer");
		logger.info(n_no+", "+n_title+", "+n_content+", "+n_writer);
	}
  

profile
아는만큼보인다.

0개의 댓글