-
기본객체2, scope-0621웹프로그래밍 2022. 6. 21. 23:54728x90
<오늘의 복습>
왭리소스 확보 하려면 5. application(ServletContext)사용
<오늘의 학습 목표>
1. 기본객체마무리
2. 라이프사이클 스코프 영역
3. 데이터베이스
9. pageContext(PageContext,****) : 현재 JSP 페이지에 대한 모든 객체를 소유한 객체.
09/pageContextDesc.jsp : PageContext pageContext
: 기본객체 중 가장 먼저 생성되며, 나머지 기본객체에 대한 레퍼런스를 가진 객체
특징 : 제일먼저 생성이됨 ,나머지 모든정보(기본객체) 가지고 있다.
4개의영역을 건드리는것과 같음
1)자기가 소유하고 있는 scope
2)자기가 소유하는것이아니라 여타에 다른 객체가 소유하고 있는 scope
1. 기본객체 확보(EL), ${pageContext}
2. attribute 관리기능(setAttribute, getAttribute) : 4개의 기본객체가 가진 scope를 참조할 수 있는 기능.
a. request.setAttribute("reqAttr", "요청속성"); b. request.getAttribute("reqAttr"); pageContext.setAttribute("reqAttr", "요청속성", PageContext.REQUEST_SCOPE); a대체가능 pageContext.getAttribute("reqAttr",PageContext.REQUEST_SCOPE); b대체가능
3. 에러 데이터 확보
<% ErrorData ed =pageContext.getErrorData(); int sc =ed.getStatusCode(); out.println(sc); %>
에러를 처리할 목적이 있는곳에서 사용 ,exception(Throwable)에서도 사용
4. 흐름제어 (dispatch)
pageContext.forward("/09/implicitObject.jsp");
<% request.getRequestDispatcher("/09/ImplicitObject.jsp").include(request, response); // pageContext.include("/09/ImplicitObject.jsp"); %>
=> 위치가다름
버퍼를 어떻게 쓰느냐에 따라 인클루드 위치 달라짐
<% // request.getRequestDispatcher("/09/ImplicitObject.jsp").include(request, response); pageContext.include("/09/ImplicitObject.jsp"); %> 추가 코드
a플러쉬 먼저 하고 (버퍼를 방출시키고) b만들어냄 그걸 다시 가지고 a로 돌아와 남은 코드 출력
버퍼방출여부에 따라 인클루드 달라짐
문제점: 방출 이후 예외 발생하면 예외처리 불가능
<커스텀 태그>
커스텀태그 커스텀 태그 : 코드의 가독성 높음 자바 코드 모르는 사람도 include사용 가능
백엔드에서 작동하는 서버사이드 코드 프론트 브라우저 x
- 서버사이드 태그
- 서버사이드에서 서버사이드 코드가 실행될때 태그가 번역되어 응답데이터에는 포함되지 않는다
custom tag 사용방법 : <prefix : 태그명 속성명="속성값" /><jsp:include page="/09/ImplicitObject.jsp"/>
https://getbootstrap.com/docs/5.1/getting-started/download/
버전은 5.1.3
제이쿼리 플러그인 이라했는데 뻥이다 => 5버전부터 스탠드얼론으로 바뀜 jquery없어도 사용가능해짐
4버전이면 플러그인 형태로 사용해야함
<preScript.jsp> css
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <link rel="stylesheet" href="<%=request.getContextPath()%>/resources/js/bootstrap-5.1.3-dist/css/bootstrap.min.css"/> <script src="<%=request.getContextPath()%>/resources/js/jquery-3.6.0.min.js"></script>
<postScrpit.> bootstrap.bundle
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <script src="<%=request.getContextPath() %>/resources/js/bootstrap-5.1.3-dist/js/bootstrap.bundle.min.js"></script>
같은방법 <jsp:include page="/includee/postScript.jsp"/>
pageContextDesc.jsp에서 이것(2개)을 해줌으로써 부트스트랩 사용가능해짐
저 파란부분 나오는곳은 정상적인 코드가 아니지만 PageContextDesc에서 부트스트랩 사용할 수 있게해줬으므로 사용이 가능한것이고
부트스트랩 쓸 수 있을지말지는 브라우저에 띄어놓고 판단
저 노란색 html코드와 제이쿼리 또 로딩되고 이렇게 또 들어가면 인터프리팅언어이기에
위에 선언한 제이쿼리 사라질것이다. 에러 주의
한페이지안에서 제이쿼리는 반드시 한번만 로딩
템플릿
웰컴페이지 ui를 테마 적용해보는 예제
https://getbootstrap.com/docs/5.1/examples/dashboard/
마우스 오른쪽 소스보기 한 후 소스 복사해서 template.jsp에 붙여넣기
-> 추후 template.jsp에 넣고 메뉴바는 분리함
<leftMenu.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse"> <div class="position-sticky pt-3"> <ul class="nav flex-column"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="#"> <span data-feather="home"></span> Dashboard </a> </li> <li class="nav-item"> <a class="nav-link" href="#"> <span data-feather="file"></span> 회원관리 </a> </li> <li class="nav-item"> <a class="nav-link" href="#"> <span data-feather="file"></span> 상품관리 </a> </li> <li class="nav-item"> <a class="nav-link" href="#"> <span data-feather="file"></span> 거래처관리 </a> </li> <li class="nav-item"> <a class="nav-link" href="#"> <span data-feather="file"></span> 자유게시판 </a> </li> <li class="nav-item"> <a class="nav-link" href="#"> <span data-feather="file"></span> 방명록 </a> </li> </ul> <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted"> <span>Model1 Service</span> <a class="link-secondary" href="#" aria-label="Add a new report"> <span data-feather="plus-circle"></span> </a> </h6> <ul class="nav flex-column mb-2"> <li class="nav-item"> <a class="nav-link" href="<%=request.getContextPath() %>/04/factorial.jsp"> <span data-feather="file-text"></span> Factorial </a> </li> <li class="nav-item"> <a class="nav-link" href="<%=request.getContextPath() %>/06/calendar.jsp"> <span data-feather="file-text"></span> Calendar </a> </li> </ul> </div> </nav>
<template.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.88.1"> <title>Dashboard Template · Bootstrap v5.1</title> <%-- <jsp:include page="/includee/preScript.jsp"/> --%> <%@include file="/includee/preScript.jsp" %> <meta name="theme-color" content="#7952b3"> <style> .bd-placeholder-img { font-size: 1.125rem; text-anchor: middle; -webkit-user-select: none; -moz-user-select: none; user-select: none; } @media (min-width: 768px) { .bd-placeholder-img-lg { font-size: 3.5rem; } } </style> <!-- Custom styles for this template --> <link href="dashboard.css" rel="stylesheet"> </head> <body> <%-- <iframe src="<%=request.getContextPath() %>/includee/preScript.jsp"></iframe> --%> <header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow"> <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#">Company name</a> <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search"> <div class="navbar-nav"> <div class="nav-item text-nowrap"> <a class="nav-link px-3" href="#">Sign out</a> </div> </div> </header> <div class="container-fluid"> <div class="row"> <jsp:include page="/includee/leftMenu.jsp"/> <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4"> <jsp:include page='<%=(String)request.getAttribute("contents") %>'/> </main> </div> </div> <jsp:include page="/includee/postScript.jsp"></jsp:include> <script src="https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/feather.min.js" integrity="sha384-uO3SXW5IuS1ZpFPKugNNWqTZRRglnUJK6UAZ/gxOX80nxEkN9NcGZTftn6RzhGWE" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha384-zNy6FEbO50N+Cg5wap8IKA4M/ZnLJgzc6w2NqACZaK0u0FXfOWRRJOnQtpZun8ha" crossorigin="anonymous"></script><script src="dashboard.js"></script> </body> </html>
Factorial누르면 나오는데 근데 템플릿 적용하고싶어
<leftMenu.jsp>
command로 날라오는 값 받아서 처리해주기
<Model1AlterServlet .java>
package kr.or.ddit.servlet08; 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; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang3.StringUtils; /** * enum은 그 자체로 immutable object의미를 포함함 * 상수는 바귈 수 없어 그래서 set안만들어줌 */ @WebServlet("/model1/service.do") public class Model1AlterServlet extends HttpServlet { public static enum ServiceType{ FACTORIAL("/04/factorial.jsp"), CALENDAR("/06/calendar.jsp"); private String jspPath; private ServiceType(String jspPath) { this.jspPath = jspPath; } public String getJspPath() { return jspPath; } } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String cmdParam =req.getParameter("command"); if(StringUtils.isBlank(cmdParam)) { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "필수하라미터 누락"); return; } try { ServiceType command = ServiceType.valueOf(cmdParam); String contents= command.getJspPath(); req.setAttribute("contents", contents); String view ="/WEB-INF/views/template.jsp"; req.getRequestDispatcher(view).forward(req, resp); }catch (IllegalArgumentException e) { resp.sendError(HttpServletResponse.SC_NOT_FOUND,"제공하지 않는 서비스임"); } } }
에를들어서 캘린더의 form post할때 :
action 어디로 가는지 안써주면 그냥 그 페이지로 다시 보내지는 것 처럼? 모델1은 자기자신 될 수도 있지만 모델2의 상대기준은 브라우저
1.<jsp:include page="/includee/preScript.jsp"/>
2.<%@include file="/includee/preScript.jsp" %>
차이 : 1. 동적 2는 정적
1:실행시점에들어오는구조 , 런타임에 남아있는건 결과일것이다. 즉 런타임의 실행결과를 가져오는 구조
2: 소스가 그대로 어느시점에 들어왔냐 소스를 작성하는 과정
실행하기전에 소스를 파싱하는 단계에서 소스를 합친다.
iframe : 클라이언트 사이드 모듈화, 서버가 감당해야할 부하가 커지므로 잘 사용하진않음
<iframe src="<%=request.getContextPath() %>/includee/preScript.jsp"></iframe>
8. exception(Throwable) : 발생한 예외 정보를 가진 객체(isErrorPage가 설정된 에러처리 페이지에서 사용) 에러 처리 목적
여기에 붙여넣기
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>
isErrorPage를 ture로 바꿔준다.
사용자에게 이게 뜨면 좋지 않음
<error404.jsp>
<p class="desc_error"> <% ErrorData ed = pageContext.getErrorData(); %> 방문 원하시는 페이지의 (<%=ed.getRequestURI() %>)가 잘못 입력되었거나,<br> 변경 혹은 삭제되어 요청하신 페이지를 찾을 수가 없습니다. 상태코드 : <%=ed.getStatusCode() %> </p>
<error404.jsp>
한글을 입력했을경우 디코딩 해줘야함
Scope(영역)
: 웹 어플리케이션 데이터를 공유하는 방법, 공유할 데이터(attribute)를 저장하는 공간(scope)
-뚜렷한 생명주기를 가진 기본 객체들이 자기 생명주기와 동일하게 관리하고 있는 map(name/value).
setAttribute(name, value), getAttribute(name), removeAttribute(name)
Enumeration getAttributeNames
1. page scope : PageContext와 동일한 생명주기를 갖고, 해당 jsp 페이지 내에서만 사용되는 영역(custom 태그에서 주로 사용).공유범위 좁음- pageContext 라는 기본객체가 관리하는 맵
- 한 페이지 내에서만 공유되는 영역
- 한 페이지에서만 쓸 수 있기 때문에 공유의 의미에서 살짝 벗어나 있음
- 커스텀태그 만들 때 주로 사용함
2. request scope : HttpServletRequest 와 생명주기가 동일, 한 요청에서만 제한적으로 사용되는 영역.
3. session scope : HttpSession와 생명주기가 동일하며, 해당 세션의 클라이언트가 사용할 수 있는 영역.//만명클라이언트 접속 서버 부하 됨 제한적 사용
- seesion 이 관리하는 Map<String, Object>
- session과 생명주기 동일
- 한 사람의 유저가 자기만의 데이터를 넣기 위한 저장 공간
- 서로의 세션 스코프에 접근할 수 없음
4. application scope : ServletContext와 생명주기가 동일한 저장구조로 어플리케이션 전체에 걸쳐 공유되는 영역.
공유범위: 한번만들면 그데이터는 사라지지않는다는것과 같음 어플리케이션 전체 영역공유가능//잘 사용x 계속만들면 무거워짐
- servletContext가 관리하는 Map<String, Object>
- servletContext와 생명주기 동일
- 하나의 어플리케이션은 사용하고있는 모든 클라이언트가 동시에 접근할 수 있는 영역
- 가장 큰 공유범위이기때문에 '부하'를 신경써서 접근해야함
- 경우에 따라서는 스코프에 속성 데이터를 넣을 수도 있지만, 부하를 줄이기 위해서는 속성데이터를 지울 수도 있음 (removeAttribute)
<destination.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <div class="bg-primary"> <pre> <%=pageContext.getAttribute("pageAttr") %> <%=request.getAttribute("requestAttr") %> <%=session.getAttribute("sessionAttr") %> <%=application.getAttribute("applicationAttr") %> </pre> </div> </body> </html>
코드 이어서 ... <forward사용>
<% pageContext.setAttribute("pageAttr", "페이지 속성"); request.setAttribute("requestAttr", "요청 속성"); session.setAttribute("sessionAttr", "세션 속성"); application.setAttribute("applicationAttr", "어플리케이션 속성"); pageContext.forward("/10/destination.jsp"); %>
<include사용>
<% pageContext.setAttribute("pageAttr", "페이지 속성"); request.setAttribute("requestAttr", "요청 속성"); session.setAttribute("sessionAttr", "세션 속성"); application.setAttribute("applicationAttr", "어플리케이션 속성"); pageContext.include("/10/destination.jsp"); %>
<redirect 사용>
<% pageContext.setAttribute("pageAttr", "페이지 속성"); request.setAttribute("requestAttr", "요청 속성"); stateless때문에 안보임 response나가서 session.setAttribute("sessionAttr", "세션 속성"); application.setAttribute("applicationAttr", "어플리케이션 속성"); response.sendRedirect(request.getContextPath()+"/10/destination.jsp"); %>
getContextPath():요청이 한번더 들어와야하기에 클라이언트가 사용함
요청이 두쌍이 필요하기에
새로고침하면 세션은 계속 유지중임 세션을 없애고싶어 방법은?
크롬애서 쿠키 저장 차단 설정하면
session.setAttribute("sessionAttr", "세션 속성"); //flash attribute :한번사용하고 나면 없어짐 -> 스프링에서는 FlashMap Manager 사용할것임
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <div class="bg-primary"> <pre> <%=pageContext.getAttribute("pageAttr") %> <%=request.getAttribute("requestAttr") %> <%=session.getAttribute("sessionAttr") %> <% session.removeAttribute("sessionAttr"); %> <%=application.getAttribute("applicationAttr") %> </pre> </div> </body> </html>
질문1: 로그인안했어 예스24 책 장바구니 담았어 session사용(저장위치 양 사이드(서버와 클라이언트) )
그런데 장바구니 책 너무 많이들어가 여기에 만명 클라이언트 접속? 무거움.... 그러면 장바구니를 클라이언트저장소(쿠키)
서버이렇게 나눠가짐
질문2: 네이버 다음 카페 활성 내가 어떤 카페 가입해서 들어감 현재 동작자 리스트 같이 채팅
내가먼저 로그인했어 정현이 반석이 들어옴 정보를 3명다 공유 session나밖에못보거나 정현이밖에 못보거나 반석이밖에 못보거나 세션과 세션사이에서 데이터 공유 할 수 있어햐함 즉 application.setAttribute사용해야함
누적방문자수 어디에넣을까? application scope에
scope 영역 선택 기준
1.공유할 데이터 특성
2. 생명주기
3. 모델2일때 이동방식
728x90'웹프로그래밍' 카테고리의 다른 글
로그인처리, 템플릿맛보기-0622 (0) 2022.06.22 JDBC-22.06.21 (0) 2022.06.22 ServletContext,File explorer -22.06.20 (0) 2022.06.21 로그인,기본객체 -22.06.16~06.17 (0) 2022.06.17 Reponse -0616 (0) 2022.06.16 - 서버사이드 태그