2020.06.09
ServletContext
1) Attribute 역할
2) Container 차원에서의 초기화
- DB 연결을 하지 않고 DB처럼 사용 할 수 있습니다.
- servletContext를 리턴 하려면 servletConfig에 있습니다. getServletContext
메소드
하위 디렉토리 접근할때
1. DD파일(WEB.XML)
1) servlet Mapping 정보
2) Initialization
<init-param>
<p n>
<p v>
</init-param>
- 기본 생성자가 호출되기 때문 필드초기화가 안됩니다.
3) servletConfig 생성됩니다.
4) init(servletConfig)호출
요청이 있기 전이기 때문에 값을 받아 올수 없습니다.
--------------------------------------------------------load-on-startup----------
5)req, res, thread
6) doget(), dopost() 호출
7) doget(), dopost()수행, 응답-> req, res, thread가 death
5-7 번 반복
서블릿 컨텍스트
1. DB 대신에
2. 글로벌한 초기화
리스너 개념
servlet을 초기화하기 위해서 DB 연결을 하는 것은 조금 의미가 안맞습니다. 제일 먼저 생성되는 객체인 servletContext를 통해서 servlet 객체의 필드 초기화를 할 수 있습니다. 그러려면 그 정보를 servletContext에 먼저 정보가 저장 되어 있어야 합니다. 그것은 servletContext에서 setAttribute로 biding합니다. 그리고 servlet에서 getAttribute로 받습니다. servletContext는 어디에서 그 정보를 받냐면, 바로 xml입니다.
<Context-param>
<Param-name>파일경로 네임(ex: "VIPFile")
<Param-value>파일 경로(정보가 저장되어 있는 곳)
</Context-param>
사용: filePath=context.getInitParameter("VIPFile");
(servletConig는 상대 경로가 안먹힘)
그럼 저 메소드는 servlet의 라이프 사이클 중에서 어디에서 해야하는가요?
init(a servlet instance initializaion), service, 생성자 -> 이중 아무것도 아닙니다.
서블릿의 라이프 사이클과는 상관이 없습니다. 왜냐면 먼저 저런것은 서블릿이 존재하기 전에 존재하고 있기 때문입니다. 이런 것을 처리하는 기법이 이벤트입니다.
이벤트
xml에 값을 만들어 놨습니다. 이 값을 ServletContext에서 끌어와서 초기화를 하려고합니다. 이때 servletcontext에서 제공하는 getInitparameter를 쓰면 extra Resource에 있는 값을 context에 할당에서 initiallization할 수 있는데, 우리가 알고 있는 life-cylcle엔 없습니다. 새로운 값이 servletContext에 들어가는 것을 사건, 즉 이벤트로 간주합니다. ServletContextEvent이 만들었습니다. 이 이벤트를 감지하는 CCTV같은 역할을 하는 것을 Listener라고합니다. servletContext 이벤트를 감지하는 것을 ServletContextListner라고 합니다. 이벤트가 일어나기 전에 ServletContextListner가 먼저 부착 되어 있어야합니다. 리스너는 먼저 부착 하고, 외부자원을 가져와서 값을 바꾸려고하면, 리스너가 그 이벤트를 감지하고 메소드를 호출 합니다.
이벤트 자체를 인자값으로 받습니다.
코드작성
vip정보 txt로 저장
kim07|james
lee123|Lessan
nbnb12|Juliet
samsung66|LJY
1234|encore
web.xml에 넣습니다.
<context-param>
<param-name>vipFile</param-name>
<param-value>WEB-INF\vipmember.txt</param-value>
</context-param>
그리고 리스너도 넣어줍니다.
<context-param>
<param-name>vipFile</param-name>
<param-value>WEB-INF\vipmember.txt</param-value>
</context-param>
<listener>
<listener-class>servlet.listener.MyServletListener</listener-class>
</listener>
<filter>
그리고 이름을 잘 카피하고 리스너 클래스를 만드어 줍니다.
package: servlet.listener
class 이름: MyServletListener
ServletContextListener implements 해줍니다.
dd읽고->ServletContext 생성-> servletContextEvent 발생- 리스너 감지-호출
load on 되야 하기 때문에 xml에 load on 다 해줍니다.
<load-on-startup>1</load-on-startup>
(config의 getinitParameter: 서블릿 하나하나의 초기화:거의 안씀, context getinitparameter:글로벌한 초기화:많이 씀)
package servlet.listener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletListener implements ServletContextListener{
private ServletContext context;
//dd읽고->ServletContext 생성-> servletContextEvent 발생- 리스너 감지-호출
// 컨테이너 차원의 초기화 로직은 여기서 작성
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized....");
//1. sce에서 ServletContext하나 받아 온다.
context = sce.getServletContext();
//2. dd파일에 설정된 정보를 읽어 온다.
String filePath=context.getInitParameter("vipFile");
System.out.println("filePath: "+filePath);
//3. filePath에 들어있는 파일의 내용을 읽어들임...getResourceAsStream()
InputStream is =null;
BufferedReader br = null;
try {
System.out.println("getResourceAsStream() call");
is = context.getResourceAsStream(filePath);
br = new BufferedReader(new InputStreamReader(is));
String line=null;
System.out.println("파일의 내용을 읽어들입니다...");
while((line=br.readLine())!=null) System.out.println(line);
}catch(IOException e) {
System.out.println("파일을 읽어들이지 못했습니다.");
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed");
}
}
JSP
목표 현업: restfull, datascience, framwork
servlet controller 하는일
1. form값
2. vo생성
3. DAO 리턴
4. Biz
5. Binding(-> Biz 리턴값있으면 Attribute에 binding)
6. 네이게이션
-> 서블릿은 비지니스로직을 수행하는 역할, 결과값을 받아서 서블릿에서 출력하면 안됨, 이러면 컴포넌트 분화가 잘 안일어납니다. 제대로 된 기술은 각각의 역할이 분리되어 있어야함.
- > 단순 조회 request, 로그인 되는 동안 session, 글로벌한 초기화 제외하고는 context에 binding할 일이 거의 없음.
결과출력(tag중심->화면, jsp)
Attribute한테 정보를 받아서 출력합니다.
jsp는 java code가 있으면 안되는데, attribute에서 받아오는 코드(<% request.getAttribute("")%>는 생략하고 싶어도 생략할 수 없다. 그러나 해결하는 방법이 나왔다. 이걸 해결하기 위한 것이 EL 입니다. (expression language)
request.getAttribute("vo(이건, 변수가 아니라 맵핑된 string입니다.)") 이걸 tag로 vo로 만들어야합니다.
(request, session, application(context))
EL
Attribute의 우선순위(같은 binding name이면,)
request-> session->application-> 없으면 아무것도 출력 안함.(에러를 도출 하지 않음)
<%@ 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>
<%
int sum = 0;
for(int cnt=0;cnt<=50;cnt++){
sum+=cnt;
}
request.setAttribute("RESULT", new Integer(sum));
session.setAttribute("RESULT", "세션");//jsp에서는 session은 내장객체임
request.getRequestDispatcher("EL1_view.jsp").forward(request, response);
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!--
EL:: Attribute에 binding된 값을 찾아 오는 로직을 태그로 바꾼 기술
변수명이 아니라, 객체를 binding한 ${이름}이 사용된다.
${이름}== attribute.getAttribute("이름")
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>Attribute에 바인딩된 값을 받아 오겠습니다.</h2>
<B>(1~50까지의 합산 결과 값 1)::</B>
<%=request.getAttribute("RESULT") %>
<hr><p>
<B>(1~50까지의 합산 결과 값 2)::</B>
${requestScope.RESULT}<br><!-- RESULT는 변수가 아니라, 바인딩된 이름이다. 그리고 Attribute는 Scope가 붙어야합니다. -->
${sessionScope.RESULT}<br>
${RESULT}<br><!-- Attribute명도 생략할 수있다. -->
${RESULT+100000}<br><!-- 연산이 가능함 -->
${NAME}<br><!-- 없으면 에러를 발생시키는것이아니라, 출력을 안합니다.-->
</body>
</html>
EL로 폼값 받아 오기
<%@ 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>
<h2>form값을 EL로 받아오기</h2>
<form action="EL2_view.jsp" method="post">
ID<input type="text" name="userID"><br><br>
<strong>좋아하는 메뉴</strong><p>
<input type="checkbox" name ="menu" value="spagetii">spagetii
<input type="checkbox" name ="menu" value="haser">haser
<input type="checkbox" name ="menu" value="curry">curry
<input type="checkbox" name ="menu" value="pizza">pizza
<br><br>
<hr>
<input type="submit" value="dataSend">
</form>
</body>
</html>
<%@ 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>
<b>1. jsp 기본 태그로 받아오기 :</b>
<%=request.getParameter("userID")%><br>
<b>2. EL로 받아오기 :</b>
${param.userID}<br>
<hr>
<%
String[] menues=request.getParameterValues("menu");
for(String menu : menues){
%>
<%= menu %>
<%
}
%>
<P>
<b>2. EL로 받아오기 </b><br>
선택한 메뉴:
${paramValues.menu[0]}
${paramValues.menu[1]}
${paramValues.menu[2]}
${paramValues.menu[3]}
<!-- for문을 해결 하지 못합니다. jstl -->
</body>
</html>
for문을 해결하지 못합니다. 그래서 jstl까지 사용할 줄 알아야합니다.
Jsp〃[EL]과 [JSTL] 한방에 정리 + Core
JSP파일에 자바형식의 코드를 사용하면 불편한 점을 한방에 해결할 수 있는 EL (Expression Language) 과 JSTL (Jsp Standard Tag Library)를 이용해 코드를 간결하게 사용하는 방법에 대해 포스팅하도록 하겠..
hunit.tistory.com
<%@page import="java.util.ArrayList"%>
<%@page import="model.MemberVO"%>
<%@ 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>
<%
MemberVO vo = new MemberVO("11","11", "하바리", "서현동");
request.setAttribute("vo", vo);
request.getRequestDispatcher("EL3_view.jsp").forward(request, response);
%>
</body>
</html>
<%@ 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>
<h2>vo정보 출력</h2>
아이디: ${vo.id}<br>
이름: ${vo.name}<br>
주소: ${vo.address}<br>
${vo}
</body>
</html>
<%@page import="java.util.ArrayList"%>
<%@page import="model.MemberVO"%>
<%@ 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>
<%
ArrayList<MemberVO> list = new ArrayList<>();
MemberVO vo1 = new MemberVO("11","11", "하바리", "서현동");
MemberVO vo2 = new MemberVO("22","22", "하바리2", "서현동2");
list.add(vo1);
list.add(vo2);
request.setAttribute("list", list);
request.getRequestDispatcher("EL3_view.jsp").forward(request, response);
%>
</body>
</html>
<%@ 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>
<hr>
<h2>list 정보 출력</h2>
아이디1: ${list[0].id}
이름1: ${list[0].name}
주소1: ${list[0].address}
<hr>
아이디2: ${list[0].id}
이름2: ${list[0].name}
주소2: ${list[0].address}
</body>
</html>
JSTL,독자적으로 안쓰임+EL
jstl은 el이 하지 못하는 if, for를 할 수 있습니다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- core 등등 여러가지가 있는데, core를 씁니다.prefix c의 약자 -->
c:set은 attribute를 지정해주는 것입니다. page, request, session, application중에 선택해서 맵핑해서 저장할 수 있씁니다.
<!--
1. 라이브러리 추가: standard.jar}jstl.jar
2. taglib 속성을 지정
-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- core 등등 여러가지가 있는데, core를 씁니다.prefix c의 약자 -->
<!-- c:set::변수를 지정 -->
<!-- num1이라는 변수를 선언, 여기에 7이라는 값을 할당-->
<c:set var="num1" value="7"/>
<c:set var="num2" value="9"/>
<!-- multiple 변수 선언 num1*num2 곡합 값을 할당-->
<c:set var="multiple" value="${num1*num2}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<b>${num1}과 ${num2}의 곱은 ${multiple} 입니다. </b>
</body>
</html>
7과 9의 곱은 63 입니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="CODE" value="1004" scope="request"/>
<c:set var="NAME" value="encore"/>
<c:set var="PRICE" value="220000"/>
<!-- 객체를 var로 mapping하는 것입니다. 어떤 attribute인지는 아직 모릅니다. -->
<jsp:forward page="cset2_view.jsp"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
상품코드: ${CODE}
</body>
</html>
scope=" 이걸 안해주면 이 페이지에서만 사용 가능하다.
scope="page"이게 디폴트입니다.
page=this랑 비슷함.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="CODE" value="1004" scope="request"/>
<c:set var="NAME" value="encore" scope="request"/>
<c:set var="PRICE" value="220000" scope="request"/>
<!-- 객체를 var로 mapping하는 것입니다. 어떤 attribute인지는 아직 모릅니다. -->
<jsp:forward page="cset2_view.jsp"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
상품코드: ${CODE}
</body>
</html>
sesssion, application 이것으로 바꿔주면 그렇게 됩니다.
<%@ 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>
<h2>cset2.jsp에서 바인딩된 값을 찾아오겠습니다.</h2>
상품코드: ${CODE}<br>
상품명:${NAME}<br>
상품가격:${PRICE}<br>
</body>
</html>
c:if
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="cIf3_view.jsp">
num1:<input type="text" name="num1"><br>
num2:<input type="text" name="num2"><br>
<input type="submit" value="send">
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:if test="${param.num1=='1'}">
<h2>1값이 들어왔습니다.</h2>
</c:if>
<c:if test="${param.num2=='2'}">
<h2>2값이 들어왔습니다.</h2>
</c:if>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
c:choose->if, else if, else랑 같음
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="cChoose4_view.jsp">
num1:<input type="text" name="num1"><br>
num2:<input type="text" name="num2"><br>
<input type="submit" value="send">
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:choose>
<c:when test="${param.num1=='1'}">
안녕하세요 반갑습니다.
</c:when>
<c:when test="${param.num1=='2'}">
처음 뵙겠습니다.
</c:when>
<c:otherwise>
크크킄크크크큭
</c:otherwise>
</c:choose>
</body>
</html>
조건문
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:forEach var ="cnt" begin="1" end="10" step="2">
<font size="${cnt}">Hello~~~jstl</font><br>
</c:forEach>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String[] arr={"삼계탕", "순두부찌개", "설렁탕", "김치찌개", "곰탕", "두루치기"};
request.setAttribute("arr", arr);
%>
<jsp:forward page="cForEach6_view.jsp"></jsp:forward>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>오늘 선택할 수 있는 저녁 메뉴들입니다.</h2>
<ul>
<c:forEach items="${arr}" var="dish">
<li>${dish}</li>
</c:forEach>
</ul>
</body>
</html>