우선 최종코드를 먼저 공유하겠다.
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의 역할이다.
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;
}
}
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;
}
}
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;
}
}
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;
}
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;
}
이번 Pojo1-1에선 테스트 케이스에 따라 실행방법이 달라지니 경우를 나눠서 실행하겠다.
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}]}
이 부분에 있어 일대일 대응하여 코드를 설명하겠다.
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 서블릿(서버)에 요청한다.
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")
으로 받아온다.
af = nc.execute(req, res);
입장 완료
[FrontMVC.java : 51]{FrontMVC 클래스에 doService메소드에 들어왔습니다.}
@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번 인덱스를 가지고 있다.
왜? StringBuilder path 와 boolean isRedirect 변수를 선언 했을까?
최종적으로 return af를 하는데, 그 때 if문을 분기한 다음에 결과적으로 나온 경로를 setisRedirect() , setpath() 한다. 이와 같은 이유로 변수를 선언한 것이다.
StringBuilder로 쓴 이유는 String으로 new하게 되면 우선 메모리 낭비가 심하기 때문에 StringBuilder로 사용했다.
처음은 당연히
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;
}
}
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/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 변동이 일어난다.🎇🎇🎇
그리고 나서 변동된 url : /notice/noticeList.gd 로 다시 url 쪼개기를 진행하고
notice[0] || noticeList[1] 이렇게 또 noticeController에 넘겨준다. -> 넘겨준 배열에서 1번 인덱스를 비교하고
맞는 if문에 들어가서 nLogic를 수행한다. 이 때 SELECT는 forward 방식으로 진행되며, 디비에서 꺼내온 값을 브라우저에 뿌린다.
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처리됨
}
<%@ 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 방식으로 전달 할 떄,
이런식으로 단위테스트가 가능하다.
만약에 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);
}
@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);
}