본문 바로가기
학원수업/3월

03/17 국비 개발자 과정-76회차 쿠키(회원관리), Spring, React

by 코딩마스터^^ 2023. 3. 17.

쿠키생성하기

첫번째 파라미터 : 이름 (key생각-유일무이)

두번째 파라미터 : 값(문자열 가능함)

생성을했다고 해서 실제 로컬 PC에 내려가지 않는다.

별로도 응답을 내려 보내야한다.

 

Cookie c =new Cookie("cmem_id", "tomato");

쿠키 타임에 대한 설정이 가능하다.

장바구니에 보관은 3일 동안만 

API로는 

setMaxAge();//단위는 초 단위이다. 

 

쿠키의 적용범위

c.serPath();//생략이 가능하다.

 

http://localhost:9000/member/cindex.jsp

upmu[0]

upmu[1]=cindex.jsp

 

요청으로 시작해서 응답으로 끝난다->웹페이지

Void ->doGet(req,res), doPost(req,res)

String->"redirect:upmu[0]/메소드의 이름 or 페이지 이름"

 

ModelAneView

pageMove[0]=member===upmu[0]

pageMove[1]=memberList or memberList.jsp or XXX.st3->또다른 URL

 

action(select) - > jsp -> 글쓰기버튼 -> jsp(폼) -> 저장 -> Action(insert) ->1(성공)

->0(실패)

->1 ->action(select) ->(forward)

리액트의 핵심적인 컨셉

return이 useState가 바뀌면 리렌더링이 일어난다.

페이지를 여러개의 컴포넌트로 쪼갠다.(클래스를 여러개 쪼개는것처럼)

HackerNewsPAge -> HAckerNewsList.jsx(select - n건) -> map -> HAckerNewsRow.jsx(select -1건) -> 출력

공통적으로  return을 갖고 있다.

return(<><h3></h3><>);

useState가 바뀌면 React는 비교 알고리즘을 통해 Dataset을 비교하고 바뀐 값이 있으면 return을 다시 호출 한다.

useState(0)

useState({}) -객체 ->한개 -> select *from member where mem_id=tomato, MemberVO, Map<String, Object>

useState([]) - 객체배열

위의 아이들이 변하면 화면도 리 렌더링이 된다.

 

글쓰기

jsp(form) -> action(insert) -> action(select:memberList.st3) ->(forward):ModeandAndView, serAttribute, Model, ModelMap, ViewResolver)jsp

 

글수정 - 글 상세보기에서 시작

action(select-1건) -> jsp(입력화면) -> action(update) -> action(select) -> jsp

실시간으로 반영이 되어야한다. 그것이 서버사이드를 쓰는 이유이다.

 

 

글삭제-글 상세보기에서 시작

비번입력하는경우

jsp(비번을 비교함-오라클비번과 상세보기에서 가져온 사용자가 쓴 비번) ->action(delete from member where mem_id ="tomato")->action(select)->jsp(새로고침)->window.location.href="a.jsp"; F5 -> JSP가 아님 ->react->useState() ->화면출력 -> return(랜더링되는 부분. 태그가 오는 부분 화면이 그려지는 부분)

 

 

 

비번 입력 안하는 경우도 있다.

 

 

글조회

글 목록 -> 키워드입력 ->조회버튼 ->action -> jsp

 

 

 

쿠키 읽기

 

쿠키 삭제하기(로그아웃 담당)

로그인

절대경로 - 처음부터 다 적음

상대경록 - 현재 내가 바라보는 경로에서부터 적음

./  -> 현재 내가 작성하는 페이지 경로를 의미

../ -> 현재 내가 있는 폴더에서 상위폴더를 의미

상대경로 : window.loaction.href="./login.st3"

절대경로 : window.loaction.href="/member/login.st3"

 

로그아웃

st3번 앞에 있는 이름은 메소드 명이다.

logout은 MemberCotroller.java에 선언된 메소드 이름이다!!

톰캣에 XXX.st3으로 요청이 오면 ActionSupport에서 인터셉트를 함

upmu[0]=member

upmu[1]=logout

액션 서포트에서 잘라낸다.

Contoller3.java(Interface) -> 추상클래스 중심, 인터페이스 중심의 코드 권장한다.

logout을 등록한다.

//Contoller3을 implements하는 class가 여러개있다.
//Board3Controller(게시판), CommonController(우편번호), MemberController(회원관리)

implements를 한 클래스가 메소드 추가하면 터진다. implement는 제약조건이다. add해준다.

 

이것을 핸들러매핑으로 연결한다.

HandelerMapping.java

*st.3 -> web.xml

 

window.loaction.href="./logout.st3"

 

 

쿼리문을 작성해 보면 화면정의서 등등의 파라미터 갯수를 알 수 있다.

 

장바구니에서 사용자 이름을 불러줄때 등등...

아이디와 비번이 일치하는지 확인-아이디 비번->파라미터 두개이구나!!

사용자가 화면에 입력한 값을 담아주는 어노테이션

@RequestParam 

 

화면정의서->기능정의서 -쿼리문을 단위 테스트해서 화면정의서 붙인다.

 

프로젝트 시에 로그인 컨셉

쿠키에서만 끝내는 것이 아니라 세션도 사용해야된다. 당연 유지해야지...

 

React

1. index.html

2. index.js

<BrowswerRouter><App/></BrowserRouter> 브라우저 라우터로 감싸주어야한다.

3. GymApp.jsx

<Routeres>

       <Router path=" " exact="true이면 path반드시 정확해야">

</>

 

@GetMapping ->라우터 패스랑 같은 급이다..

@PostMapping

 

AuthController에서 쿠키와 세션이 필요하다.

세션을 사용할 때에는  요청객체가 필요하다.

쿠키는 제공이 된다. 요청따로 필요없다.

 

elements는 태그들이다. jsx로 만들어진 컴포넌트들이다.

그 밑에 여러개의 메뉴트리가 올 수 있다.

 

Route 를 동해서 이동한다.

화면안에서 연결(전환)을 할 때에는

React기준으로 React-router-dom이 제공하는 link사용

Hook인 useNavigate를 반드시 사용해야한다.

spa가 파괴가 된다??? 뭔말이죠?

규칙이라 이대로 해야된다...location.href이런거 쓰지 마라....

 

로그인과 관련된 페이지 2개

  • 1일때-True
  • 0일때-False

1일때

쿠키값==null

인증하기 이전

 

0일때

쿠키가 값을 가짐

 

로그아웃 구현하기

 

MemberController에 Controller3에서 추가한 logout을 가져와서 오버라이딩 해준다.

 

 

리액트에서는 useNavigate를 쓴다.

리액트에서 사용하는 훅이다.

화면을 부분적으로 전환해준다.

가상의 돔을 이용한다.

useState가 바뀔때 전환이 된다.

 

Member관리 코드 정리-로그인, 로그아웃

package com.pojo.step3;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
 
import com.pojo.step2.Board2Controller;
 
public class ActionSupport extends HttpServlet {
	Logger logger = Logger.getLogger(ActionSupport.class);
 
	protected void doService(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("doService 호출");
		String uri = req.getRequestURI();
		logger.info(uri); // /board3/boardList.st3가 찍힘
 
		String context = req.getContextPath();
		logger.info(context); // "/" -> server.xml에 들어있음
 
		String command = uri.substring(context.length() + 1);
		System.out.println(command); // board3/boardList.st3
 
		int end = command.lastIndexOf(".");
		System.out.println(end); // 16(board3의 경우)
 
		command = command.substring(0, end);
		System.out.println(command); // board3/boardList
 
		String upmu[] = null; // upmu[0]=업무명(폴더명), upmu[1]=요청기능이름(메소드명)
		upmu = command.split("/"); // /기준으로 문자열 잘라서 upmu 배열에 담기
		logger.info(upmu[0] + ", " + upmu[1]);
		// upmu req에 담기
		req.setAttribute("upmu", upmu);
		Object obj = ""; // null이 맞지만 String이 들어온다는 전제로 ""
 
		try {
			// 아래 코드는 DB쪽으로 가는 길
			obj = HandlerMapping.getController(upmu, req, res);
		} catch (Exception e) {
			logger.info("Exception: " + e.toString());
		}
 
		// 페이지 이동처리 공통코드
		// obj 형식 예시 -> redirect:XXX.jsp or forward:XXX.jsp
		// 아래 코드는 응답으로 나가는 길
		if (obj != null) {
			String pageMove[] = null; // 응답페이지의 위치, 페이지이름
			ModelAndView mav = null;
 
			// obj가 String인 경우 -> webapp
			if (obj instanceof String) {
				// obj에 :이 포함된 경우
				if (((String) obj).contains(":")) {
					logger.info(": 포함되어 있음");
					pageMove = obj.toString().split(":");
				}
				// objdp /가 포함된 경우
				else if (((String) obj).contains("/")) {
					logger.info("/ 포함되어 있음");
					pageMove = obj.toString().split("/");
				}
				// obj에 :과 /이 포함되지 않은 경우
				else {
					// spring boot -> @RestController 사용
					// spring4 -> ResponseBody 사용(@RestController 미지원)
					logger.info(":과 / 포함되어 있지 않음"); // 마임타입 text/plain
					pageMove = new String[1];
					pageMove[0] = obj.toString();
					logger.info(obj.toString());
				}
			}
			
			// obj가 ModelAndView인 경우 -> WEB-INF
			else if (obj instanceof ModelAndView) {
				mav = (ModelAndView) obj;
				pageMove = new String[2];
				pageMove[0] = ""; // forward가 들어있으면 안됨 -> 있으면 webapp로 향함
				pageMove[1] = mav.getViewName();
				logger.info(pageMove[0] + ", " + pageMove[1]);
			}
			
			logger.info("Object가 String, ModelAndView일 경우가 끝난 지점");
			// pageMove가 null이 아닐 경우 각 방식으로 페이지 이동처리
			if (pageMove != null && pageMove.length == 2) {
				// pageMove[0] = redirect or forward or ""
				// pageMove[1] = XXX
				logger.info(pageMove[0] + ", " + pageMove[1]);
				new ViewResolver(req, res, pageMove);
			}
			// pageMove배열이 한 개인 경우는 리턴값이 String인 경우일때
			// -> @RestController, 스프링부터 이전엔 ResponseBody
			else if (pageMove != null && pageMove.length == 1) {
				res.setContentType("text/plainl;charset=UTF-8");
				PrintWriter out = res.getWriter();
				out.print(pageMove[0]);
			}
		} // end of 페이지 이동처리 공통코드
	}
 
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("doGet호출");
		doService(req, res);
	}
 
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info("doPost호출");
		doService(req, res);
	}
}
package com.pojo.step3;
 
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
 
import com.util.HashMapBinder;
 
public class MemberController implements Controller3 {
	Logger logger = Logger.getLogger(MemberController.class);
	MemberLogic memberLogic = new MemberLogic();
	
	@Override
	public Object login(HttpServletRequest req, HttpServletResponse res) {
		logger.info("login 호출");
		Map<String, Object> rMap = new HashMap<>();
		Map<String, Object> pMap = new HashMap<>();
		HashMapBinder hmb = new HashMapBinder(req);
		hmb.bind(pMap);
		rMap = memberLogic.login(pMap);
		logger.info(rMap);
		Cookie cmem_id = new Cookie("cmem_id", rMap.get("MEM_ID").toString());
		cmem_id.setPath("/");
		cmem_id.setMaxAge(60*60);
		res.addCookie(cmem_id);
		Cookie cmem_name = new Cookie("cmem_name", rMap.get("MEM_NAME").toString());
		cmem_name.setPath("/");
		cmem_name.setMaxAge(60*60);
		res.addCookie(cmem_name);
		return "redirect:./cindex.jsp"; // => member.cindex.jsp
	}
 
	@Override
	public Object logout(HttpServletRequest req, HttpServletResponse res) {
		logger.info("logout 호출");
		//쿠키는 삭제하는 메소드가 따로 없다.
		//생성자의 두번째 파라미터에 빈 문자열로 처리 해 주세요.-컨벤션
		//시간을 0으로 초기화 해줘야함 
		//도메인도 동일하게 맞춰야 삭제가 됨(주의)
		Cookie cmem_id = new Cookie("cmem_id", "");
		cmem_id.setPath("/");
		cmem_id.setMaxAge(0);
		res.addCookie(cmem_id);
		Cookie cmem_name = new Cookie("cmem_name","");
		cmem_name.setPath("/");
		cmem_name.setMaxAge(0);
		res.addCookie(cmem_name);
		//navigate=useNavigate("./cindex.jsp")-리액트에서는
		return "redirect:./cindex.jsp";//==>/member/cindex.jsp
	
	}
	@Override
	public Object zipcodeList(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object jsonBoardList(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object boardList(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object boardDetail(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object imageUpload(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object imageDownload(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object imageGet(HttpServletRequest req, HttpServletResponse res) {
		return null;
	}
 
	@Override
	public Object boardInsert(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		return null;
	}
 
	@Override
	public Object boardUpdate(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		return null;
	}
 
	@Override
	public Object boardDelete(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		return null;
	}

}
package com.pojo.step3;
 
import java.util.Map;
 
import org.apache.log4j.Logger;
 
public class MemberLogic {
	Logger logger=  Logger.getLogger(MemberLogic.class);
	MemberDao memberDao = new MemberDao();
 
	public Map<String, Object> login(Map<String, Object> pMap) {
		Map<String, Object> rMap = null;
		rMap = memberDao.login(pMap);
		return rMap;
	}
}
package com.pojo.step3;
 
import java.util.Map;
 
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
 
import com.util.MyBatisCommonFactory;
 
public class MemberDao {
	Logger logger = Logger.getLogger(MemberDao.class);
	MyBatisCommonFactory mcf = new MyBatisCommonFactory();
	
	public Map<String, Object> login(Map<String, Object> pMap) {
		Map<String, Object> rMap = null;
		// MyBatisConfig.xml문서를 통해 스캔한 오라클 서버정보로 연결통로 확보
		SqlSessionFactory sqlSessionFactory = null;
		// 위에서 SqlSessionFactory가 생성되면 쿼리문을 요청하는 selectOne 메소드가 필요한데
		// 그 메소드를 제공하는 클래스 및 commit, rollback 지원
		SqlSession sqlSession = null;
		try {
			// 공통코드에서 연결통로 확보
			sqlSessionFactory = mcf.getSqlSessionFactory();
			// 연결통로 확보로 생성된 객체로 SqlSession 로딩하기
			sqlSession = sqlSessionFactory.openSession();
			rMap = sqlSession.selectOne("login", pMap);
			logger.info(rMap);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rMap;
	}
}
package com.pojo.step3;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
 
public class HandlerMapping {
	static Logger logger = Logger.getLogger(HandlerMapping.class);
	
	/***************************************
	 * @param upmu[](upmu[0]=업무명,폴더명 | upmu[1]=메소드명, 기능명, 페이지이름)
	 * @param request -> 1-1, 1-2와는 다르게 인터페이스를 implements하지 않는다
	 * @param response -> HttpServlet
	 * Q. 어디서 받아오는가?
	 * @return Object
	 * 테스트 -> http://localhost:9000/board3/boardList.st3
	 ***************************************/
	
	public static Object getController(String[] upmu, HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		logger.info(upmu[0]+", "+upmu[1]);
		Controller3 controller = null;
		String path = null;
		Object obj = null;
		ModelAndView mav = null;
		
		// common
		if("common".equals(upmu[0])) {
			controller = new CommonController();
			// 우편번호 조회
			if("zipcodeList".equals(upmu[1])) {
				obj = controller.zipcodeList(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			} // end if zipcodeList if문
		}
		
		// 게시판 구현
		else if("board3".equals(upmu[0])) {
			controller = new Board3Controller();
			
			// 게시글 전체 목록 -> html 화면 출력(text/html)
			if("boardList".equals(upmu[1])) {
				obj = controller.boardList(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// json 게시글 전체 목록 -> json 화면 출력(application/json)
			else if("jsonBoardList".equals(upmu[1])) {
				obj = controller.jsonBoardList(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 입력 - 새글쓰기와 댓글쓰기
			else if("boardInsert".equals(upmu[1])) {
				obj = controller.boardInsert(req, res);
				// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 이미지 업로드 - 리액트 quill editor 이미지 추가
			else if("imageUpload".equals(upmu[1])) {
				obj = controller.imageUpload(req, res);
				logger.info("imageUpload 호출 => " + obj instanceof String);
				// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 이미지 다운로드 - 리액트 quill editor 이미지 추가
			else if("imageDownload".equals(upmu[1])) {
				obj = controller.imageDownload(req, res);
				logger.info("imageDownload 호출 => " + obj instanceof String);
				// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 리액트 -
			else if("imageGet".equals(upmu[1])) {
				obj = controller.imageGet(req, res);
				logger.info("imageGet 호출 => " + obj instanceof String);
				// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 수정 - 첨부파일 수정 유무 고려하기
			else if("boardUpdate".equals(upmu[1])) {
				obj = controller.boardUpdate(req, res);
			// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 삭제 - 첨부파일 삭제 유무 고려하기
			else if("boardDelete".equals(upmu[1])) {
				obj = controller.boardDelete(req, res);
			// 리턴타입이 String인 경우
				if(obj instanceof String) {
					return (String)obj;
				}
			}
			
			// 글 상세보기
			else if("boardDetail".equals(upmu[1])) {
				obj = controller.boardDetail(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}
		} // end of 게시판 구현
		
		// 인증 관리 구현
		else if("auth".equals(upmu[0])) {
		}
		
		// 회원 관리 구현
		else if("member".equals(upmu[0])) {
			controller = new MemberController();
			if("login".equals(upmu[1])) {
				obj = controller.login(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}//end of login
			else if("logout".equals(upmu[1])) {
				obj = controller.logout(req, res);
				// 리턴타입이 ModelAndView인 경우
				if(obj instanceof ModelAndView) {
					return (ModelAndView)obj;
				}
				// 리턴타입이 String인 경우
				else if(obj instanceof String) {
					return (String)obj;
				}
			}//end of logout
		}//end of 회원관리
		
		// 주문 관리 구현
		else if("order".equals(upmu[0])) {
		}
		
		return obj;
	}
}
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
String cmem_id = null;
String cmem_name = null;
// 서버측에서 클라이언트(사용자) 쿠키값 보내달라는 요청
Cookie cs[] = request.getCookies();
int size = 0;
// NullPointerException 방어코드
if (cs != null) {
	size = cs.length;
}
for (int i = 0; i < size; i++) {
	// 쿠키이름을 가져온다 - 셍성자의 첫번째 파라미터 자리값
	String c_name = cs[i].getName();
	// 서버측에서 클라이언트로부터 넘겨받은 문자열을 비교함
	if ("cmem_id".equals(c_name)) {
		// 쿠키이름이 cmem_id인 쿠키의 값을 담기
		cmem_id = cs[i].getValue();
	}
	// 한 번더 쿠키값을 꺼내온다 -> 사용자의 이름을 불러줌
	if ("cmem_name".equals(c_name)) {
		cmem_name = cs[i].getValue();
	}
}
out.print("쿠키에서 꺼내 온 값 ===> " + cmem_id + "   ,   " + cmem_name);
if (cmem_id == null) {
%>
<script>
	alert("로그인을 먼저 해주세요")
</script>
<%
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web application[쿠키인증실습 webapp]</title>
<%@ include file="../common/easyUI_common.jsp"%>
<style type="text/css">
a {
	text-decoration: none;
}
</style>
<script>
	const login =() =>{
		/*
		테스트: com.mvc.dao.MemberDao.java
		xml: com.mybatis.mapper에 member.xml
		SELECT mem_name FROM book_member
		WHERE mem_id =:id
		AND mem_pw =:pw
		*/
		// 사용자가 입력한 아이디 가져오기
		const user_id = $("#_easyui_textbox_input1").val();
		// 사용자가 입력한 비밀번호 가져오기
		const user_pw = $("#_easyui_textbox_input2").val();
		console.log(user_id + user_pw);
		window.location.href = "./login.st3?mem_id=" + user_id + "&mem_pw=" + user_pw;
	}
</script>
<script>
	const logout =() =>{
		//여기서 ./가 없으면 pageMovew배열에 매칭이 안되니까 조심하세요
		window.location.href = "./logout.st3";
	}
</script>
</head>
<body>
	<h2>웹 어플리케이션 실습</h2>
	<div style="margin: 20px 0;"></div>
	<div class="easyui-layout" style="width: 1000px; height: 500px;">
		<!-- =============== 메뉴 구성 [로그인화면과 트리메뉴] 시작 =============== -->
		<div id="p" data-options="region:'west'" title="KH정보교육원"
			style="width: 200px; padding: 10px">
			<%
			// 쿠키값이 null인 경우 - 로그인을 아직 안함
			if (cmem_id == null) {
			%>
			<!-- =============== [[ 로그인 화면 ]] =============== -->
			<div id="d_login" align="center">
				<div style="margin: 3px 0"></div>
				<!-- create table member mem_id varchar2(10) DB에서 이런형식 -->
				<input id="tb_id" type="text" style="width: 170px">
				<script>
					$('#tb_id').textbox({
						iconCls : 'icon-man',
						iconAlign : 'right',
						prompt : '아이디'
					})
				</script>
				<div style="margin: 3px 0"></div>
				<input id="pb_pw" type="text" style="width: 170px">
				<script>
						$('#pb_pw').textbox({
							iconCls: 'icon-lock',
							iconAlign: 'right',
							prompt : '비밀번호'
						});
				</script>
				<div style="margin: 3px 0"></div>
				<a id="btn_login" href="javascript:login()">로그인</a>
				<script>
					$('#btn_login').linkbutton({
						iconCls : 'icon-man'
					});
				</script>
				<a id="btn_member" href="javascript:memberShip()">회원가입</a>
				<script>
					$('#btn_member').linkbutton({
						iconCls : 'icon-add'
					});
				</script>
			</div>
			<!-- =============== [[ 로그인 화면 ]] =============== -->
			<%
			} else { // 로그인을 한 상태일 경우
			%>

			<!--============= [[ 로그아웃 화면 ]]  ==============-->
			<div id="d_logout" align="center">
				<span><%=cmem_name%>님 환영합니다.</span> <br />
				<div style="margin: 3px 0;"></div>
				<!-- 외부여백을 위, 아래에 3px만큼 주세요 -->
				<a id="btn_logout" href="javascript:logout()">로그아웃</a>
				<script>
							$('#btn_logout').linkbutton({
							    iconCls: 'icon-remove'
							});        	
			        	</script>
				<a id="btn_memberedit" href="javascript:memberEdit()">정보수정</a>
				<script>
							$('#btn_memberedit').linkbutton({
							    iconCls: 'icon-edit'
							});        	
			        	</script>
			</div>
			<!--============= [[ 로그아웃 화면 ]]  ==============-->
			<%
			}
			%>
			<!-- =============== 메뉴 구성 [로그인화면과 트리메뉴] 끝 =============== -->
			<div style="margin: 3px 0"></div>
			<ul id="tre_gym" class="easyui-tree">
				<li data-options="state:closed"><span>회원관리</span>
					<ul>
						<li><a href="#">회원목록</a></li>
						<li><a href="#">회원등록</a></li>
						<li><a href="#">회원삭제</a></li>
					</ul></li>
				<li data-options="state:'closed'"><span>쪽지관리</span>
					<ul>
						<li><a href="#">받은쪽지함</a></li>
						<li><a href="#">보낸쪽지함</a></li>
					</ul></li>
				<li data-options="state:'closed'"><span>기타</span>
					<ul>
						<li><a href="#">우편번호검색기</a></li>
						<li><a href="#">게시판</a></li>
					</ul></li>
			</ul>
		</div>
		<!-- 메인화면 [게시판, 온라인시험, 쪽지관리(받은쪽지함, 보낸쪽지함), 회원관리(회원목록, 회원등록, 회원삭제), 우편번호검색기] 시작 -->
		<div data-options="region:'center', iconCls:'icon-ok'"
			title="TerrGYM2023">
			<div style="margin: 5px 0;"></div>
			Home > 회원관리 > 회원목록
			<hr>
			<div style="margin: 25px 0;"></div>
		</div>
		<!-- 메인화면 [게시판, 온라인시험, 회원관리, 우편번호검색기] 끝 -->
	</div>
</body>
</html>
<!-- 
	부트스트랩 - 리액트수업 -> Spring과 리액트 연계 수업 -> 프로젝트적용
		반응형 지원, CSS라이브러리 사용
		CSS - JS거의없음
	
	jEasyUI
		이벤트처리(jquery - 레거시시스템)
		자바스크립트 - 표준아님 -> jquery기반이라서
		자바스크립트 기반의 UI솔루션 사용하기 - 큰 도움
		개발자도구 활용 - 디버깅 -> 왜냐하면 html을 래핑하기때문에
		vue.js, reactjs
		jEasyUI는 html으로 화면처리, html+js 섞어쓰기, js(최소한의 태그선언 필요)로 화면처리 가능
		
	JSTL - 1.1 -> 1.2 -> 소개(사용x)
	
	로그인 테스트 흐름도
		1. intro 아래 index.jsp 실행
		2. 아이디와 비밀번호를 입력받는다
		3. 로그인 버튼을 누른다 -> 자바스크립트의 login() 호출
		4. login.do 호출한다 -> 로그인 처리를 하는 서블릿 호출 - doGet(), doPost()
		5. com.mvc.dao.MemberDao 클래스의 인스턴스화
		6. 메소드 호출 - 로그인처리
		7. MemberDao의 login(Map[member_id(사용자가 입력한 아이디)와 mem_pw(사용자가 입력한 비번)가 있음]) 호출
		8. 리턴타입으로 Map을 받아온다(mem_id, mem_name)
		9. 8번에서 돌려받은 Map에서, 오라클 서버에서 조회된 아이디와 이름을 세션에 담기
		10. 페이지 이동은 sendRedirect나 forward 둘 다 모두 가능하다
				단, forward로 응답을 처리한 경우, 인증 후에 다른 서비스를 forward로 처리하는것이 불가하다(주의!)
 -->

댓글