2023.04.04 48일차 JSP
48일차 JSP EL 객체
4개영역의 attribute를 꺼내는 방식이다. 자바와 유사한데 자바와는 다른 언어이다.
리스트일때는 att[index] 맵은 attr.키 javabean은 attr.프로퍼티명으로 가져온다.
EL에 기본적으로 제공하는 객체가 있다. 거의 다 Map처럼 사용하면된다.
param은 get방식이던 post방식이던 같은 사용방법이었다.
11.27 paramValues
request는 체크박스나 셀렉트인 경우 같은 이름으로 여러 값이 올 수 있었다.
같은 이름으로 여러개 넘어오는 값을 paramValues으로 처리할 수 있다.
Map으로 파라미터이름과 String배열로 이루어져있다.
paramValues.파라미터이름[인덱스]로 값을 가져올 수 있다.
<!-- ?address=seoul&email=son@gmail.com&food=pizza&food=choco -->
<h1>paramValues</h1>
<p>${param.address}</p>
<p>${param.email}</p>
<p>${paramValues.food[0] }</p> <!-- pizza -->
<p>${paramValues.food[1] }</p> <!-- choco -->
11.28 paramValues
쿼리스트링을 직접 붙일일이 없으니 form element를 활용해보자.
<h1>14번파일</h1>
<form action="15process.jsp">
이름 :<input type="text" name="name" value="강백호" /> <br />
취미 : <br />
<input type="checkbox" name="hobby" value="농구" /> 농구
<input type="checkbox" name="hobby" value="축구" /> 축구
<input type="checkbox" name="hobby" value="독서" /> 독서
<input type="checkbox" name="hobby" value="영화" /> 영화
<br />
<input type="submit" value="전송" />
</form>
<p>이름 : ${param.name } </p>
<p> 취미:
<ul>
<li>${paramValues.hobby[0]}</li>
<li>${paramValues.hobby[1]}</li>
<li>${paramValues.hobby[2]}</li>
<li>${paramValues.hobby[3]}</li>
</ul>
</p>
11.28 paramValues 연습
17번파일을 보고 예상해서 코드를 작성해보자.
<h1>17번</h1>
<p>이메일 : ${param.email }</p>
<p>
좋아하는 음식:
<ul>
<li>${paramValues.food[0]}</li>
<li>${paramValues.food[1]}</li>
<li>${paramValues.food[2]}</li>
<li>${paramValues.food[3]}</li>
<li>${paramValues.food[4]}</li>
</ul>
</p>
<form action="17process.jsp">
이메일 : <input type="text" name="email"/> <br />
좋아하는 음식 : <br />
<input type="checkbox" name="food" value="피자"/>피자
<input type="checkbox" name="food" value="치킨"/>치킨
<input type="checkbox" name="food" value="탕수육"/>탕수육
<input type="checkbox" name="food" value="돈까스"/>돈까스
<input type="checkbox" name="food" value="김치찌개"/>김치찌개
<br />
<input type="submit" value="전송"/>
</form>
11.29 label
input박스를 좀더 편하게 사용할 수 있다.
label의 for attribute와 input의 id attribute를 같게하면 라벨을 클릭하면
해당 input element로 포커싱이 옮겨간다.
체크박스의 경우 라벨을 누르기만해도 체크를 할 수 있다.
<h1>label 요소</h1>
<form action="">
<label for="input1">이메일</label>
<input type="text" id="input1" />
<br />
<!-- (label[for=check$]+input#check$[type=checkbox]+br)*5 -->
<label for="check1">피자</label>
<input type="checkbox" id="check1" />
<br />
<label for="check2">케잌</label>
<input type="checkbox" id="check2" />
<br />
<label for="check3">비빔밥</label>
<input type="checkbox" id="check3" />
<br />
<label for="check4">커피</label>
<input type="checkbox" id="check4" />
<br />
<label for="check5">우유</label>
<input type="checkbox" id="check5" />
<br />
</form>
11.30 paramValues
checkbox뿐만이 아니라 select박스로도 설정할 수 있다.
<h1>19번</h1>
<form action="20process.jsp">
<!-- label[for=input1]+input[name=name][value=강백호]#input1+br -->
<label for="input1">이름</label>
<input type="text" name="name" value="강백호" id="input1" />
<br />
<!-- label[for=select1]+select[name=position][multiple]#select1>option[value]*5 -->
<label for="select1">포지션</label>
<select name="position" id="select1" multiple="">
<option value="guard">guard</option>
<option value="center">center</option>
<option value="forward">forward</option>
<option value="manager">manager</option>
<option value="coach">coach</option>
</select>
<br />
<input type="submit" value="전송" />
</form>
<h1>20번</h1>
<p>이름: ${param.name }</p>
<p>
포지션 :
<ul>
<li>${paramValues.position[0] }</li>
<li>${paramValues.position[1] }</li>
<li>${paramValues.position[2] }</li>
<li>${paramValues.position[3] }</li>
<li>${paramValues.position[4] }</li>
</ul>
</p>
11.31 paramValues post
get방식이 아니라 post방식으로 값을 전달해도 출력하는 방법은 같다.
<h1>23번 post</h1>
<form action="24process.jsp" method="post">
<!-- label[for=input1]+input#input1[name=name][value=서태웅]+br -->
<label for="input1">이름 </label>
<input type="text" id="input1" name="name" value="서태웅" />
<br />
좋아하는 음식 <br />
<!-- (input#check$[name=food][value][type=checkbox]+label[for=check$])*5+br -->
<input type="checkbox" id="check1" name="food" value="pizza" />
<label for="check1">pizza</label>
<input type="checkbox" id="check2" name="food" value="cake" />
<label for="check2">cake</label>
<input type="checkbox" id="check3" name="food" value="latte" />
<label for="check3">latte</label>
<input type="checkbox" id="check4" name="food" value="americano" />
<label for="check4">americano</label>
<input type="checkbox" id="check5" name="food" value="burger" />
<label for="check5">burger</label>
<br />
<input type="submit" value="전송" />
</form>
<h1>24번</h1>
<p>이름 : ${param.name }</p>
<p>
좋아하는 음식
<ul>
<li>${paramValues.food[0] }</li>
<li>${paramValues.food[1] }</li>
<li>${paramValues.food[2] }</li>
<li>${paramValues.food[3] }</li>
<li>${paramValues.food[4] }</li>
</ul>
</p>
11.32 pageScope
page영역에 있는 attribute를 꺼내서 사용할때 사용한다.
EL은 가장 작은영역부터 찾아서 그냥 attribute를 하면되지만
특정 영역의 attribute임을 나타내기 위해서 사용한다.
pageContext에 저장한 attribute들이 map으로 저장된다.
pageScope map에서 키값으로 추출 할 수 있다.
<h1>pageScope</h1>
<%
//page영역에 attribute 추가하는 코드
pageContext.setAttribute("key1", "집에가고싶다.");
pageContext.setAttribute("my-key", "개같다");
pageContext.setAttribute("attr1", "somebody help me");
%>
<p>${pageScope.key1 }</p>
<p>${pageScope["my-key"]}</p>
<p>${pageScope.attr1}</p>
11.33 requestScope
request영역에 있는 attribute를 map에 넣어서 사용하는 것이다.
그대로 사용해도 되는데 이런 것들을 어떨때 사용하나?
my request attr같이 띄어쓰기로 attribute명이 지어져있다면
Scope를 사용할 수 밖에 없다.
<h1>requestScope</h1>
<%
request.setAttribute("attr1", "value1");
request.setAttribute("my request attr", "value2");
%>
<p>${attr1 }</p>
<p>${requestScope.attr1}</p>
<p>${requestScope["my request attr"] }</p>
11.33 requestScope - 2
우연히 pageContext와 request의 attribute명이 같다면
좁은 영역부터 찾게 되어 pageContext의 attribute가 되게 된다
그래서 Scope를 사용하면 특정 영역의 attribute를 콕 찝어서 사용할 수 있게 된다.
<%
pageContext.setAttribute("attr1", "page value");
request.setAttribute("attr1", "request value");
%>
<p>${attr1}</p> <!-- page value -->
<p>${requestScope.attr1 }</p> <!-- request value -->
11.34 sessionScope
session에 담긴 attribute들이 map형태로 sessionScope에 담긴다.
<h1>sessionScope</h1>
<%
pageContext.setAttribute("attr1", "서태웅");
request.setAttribute("attr1", "강백호");
session.setAttribute("attr1", "채치수");
session.setAttribute("session attribute", "정대만");
%>
<p>${attr1 }</p> <!-- 서태웅 -->
<p>${pageScope.attr1 }</p> <!-- 서태웅 -->
<p>${requestScope.attr1 }</p> <!-- 강백호 -->
<p>${sessionScope.attr1 }</p> <!-- 채치수 -->
<p>${sessionScope["session attribute"]}</p> <!-- 정대만 -->
11.35 applicationScope
application영역에도 같다.
<h1>applicationScope</h1>
<%
pageContext.setAttribute("attr1", "이한나");
request.setAttribute("attr1", "채소연");
session.setAttribute("attr1", "송태섭");
application.setAttribute("attr1", "서태웅");
application.setAttribute("app value", "정대만");
%>
<p>${attr1 }</p> <!-- 이한나 -->
<p>${pageScope.attr1 }</p> <!-- 이한나 -->
<p>${requestScope.attr1}</p> <!-- 채소연 -->
<p>${sessionScope.attr1}</p> <!-- 송태섭 -->
<p>${applicationScope.attr1 }</p> <!-- 서태웅 -->
<p>${applicationScope["app value"] }</p> <!-- 정대만 -->
11.36 pageContext
EL의 기본 객체 중 pageContext는 JSP의 pageContext기본 객체와 동일하다.
pageContext의 기본타입은 javax.servlet.jspPageContext이다.
JSP 페이지에 대한 정보를 저장한다.
pageContext객체가 getXXx 메소드를 가지고 있어서 get을제거하고 앞글자를 소문자로 바꾼 property가 있다.
errorData exception request response session servletConfig servletContext등등의 속성을 볼 수 있다.
EL에서 이런 것들을 왜 사용하는지에 대해서 알아야한다.
JSP에서 사용하는 기본 객체들을 가지고 오는 메소드들이 pageContext에 들어있다.
EL을 거쳐서 기본객체에 접근하고 싶다면 pageContext를 사용하면된다.
혹시 필요할까봐 마련해둔 객체이다.
표현식으로 객체를 출력하나 EL의 pageContext로 출력하나 같은 객체이다.
JSP 기본 객체 (8개)를 el에서 사용할 수 있게 pageContext를 제공하는 것이다.
EL로 각 객체를 가져왔으니 그 객체를 통해서 각 메소드를 사용할 수 있다.
<h1>JSP 기본 객체 (8개)</h1>
<p><%= request %></p>
<p><%= response %></p>
<p><%= pageContext %></p>
<p><%= session %></p>
<p><%= application %></p>
<p><%= out %></p>
<p><%= config %></p>
<p><%= page %></p>
<hr />
<p>request : ${pageContext.request}</p>
<p>response : ${pageContext.response}</p>
<p>pageContext : ${pageContext }</p>
<p>session : ${pageContext.session}</p>
<p>servletContext : ${pageContext.servletContext}</p>
<p>out : ${pageContext.out}</p>
<p>servletConfig : ${pageContext.servletConfig}</p>
<p>page : ${pageContext.page}</p>
11.37 pageContext - 2
프로젝트의 path를 찾아갈때 request.getContextPath를 했었다.
EL을 사용해서 request객체를 얻고 property를 사용해서 접근할 수도 있다.
<p>${pageContext.session.id}</p>
<p>${pageContext.session.creationTime}</p>
<p>${pageContext.session.lastAccessedTime}</p>
<p>${pageContext.request.contextPath}</p>
11.38 EL 산술 연산자
EL안에서 연산자를 사용할 수 있다.
먼저 수치 연산(산술) 연산에 대해서 알아보자.
+, -, *, /, %
EL은 연결연산이 없다.
문자열 int값과 문자열 int값을 덧셈연산하면 integer로 변환되어 계산된다.
만약 없는 값을 연산하면 0으로 판단한다.
그런데 문자열을 숫자 연산을 하려하면 nubmer format exception이 발생한다.
<h1>+</h1>
<p>${3 + 4 }</p> <!-- 7 -->
<p>${'3' + '4' }</p> <!-- 7 -->
<p>${"3" + "4" }</p> <!-- 7 -->
<%
pageContext.setAttribute("num1", 30);
pageContext.setAttribute("num2", 40);
%>
<p>${num1 + num2 }</p> <!-- 70 -->
<%
pageContext.setAttribute("num3", "50");
pageContext.setAttribute("num4", "70");
%>
<p>${num3 + num4 }</p> <!-- 120 -->
<%
pageContext.setAttribute("a", 30);
pageContext.setAttribute("a", 70);
%>
<p>${a + b }</p> <!-- 100 -->
<p>${ a + c }</p> <!-- 30 -->
<%
pageContext.setAttribute("a", 30);
pageContext.setAttribute("b", 70);
pageContext.setAttribute("e", "one");
%>
<p>${a + b }</p> <!-- 100 -->
<p>${ a + c }</p> <!-- 30 --> <!-- 산술연산시 null은 0으로 -->
<p>${c+ d }</p> <!-- 0 -->
<p>${d }</p> <!-- 출력없음 -->
<p>${a + e }</p> <!-- 예외발생 -->
11.38 EL 산술연산자 - 2
자바에서의 나눗셈연산에서 정수를 정수로 나누면 정수이지만
EL에서의 나눗셈 연산은 실수값을 리턴한다.
EL에서의 나머지 연산은 %로 할수도 있지만 이를 대신 mod라는 문법으로 작성할 수도 있다.
<%
pageContext.setAttribute("a", 12);
pageContext.setAttribute("b", 5);
%>
<p>${a+b }</p> <!-- 17 -->
<p>${a-b }</p> <!-- 7 -->
<p>${a * b}</p> <!-- 60 -->
<p>${a/b }</p> <!-- 2.4 -->
<p>${a %b }</p> <!-- 2 -->
<p>${a mod b }</p> <!-- 2 -->
11.39 EL 산술연산자 - 3
연산결과를 보고 post form을 만들어보기
<h1> 연산결과 </h1>
<p>${paramValues.nums[0]} + ${paramValues.nums[1]}
= ${paramValues.nums[0] + paramValues.nums[1]}</p>
<h1>6번 파일</h1>
<form action="07process.jsp">
수1 : <input type="text" name="nums" value="12"/> <br />
수2 : <input type="text" name="nums" value="5"/> <br />
<input type="submit" value="전송" />
</form>
11.40 empty
empty연산자는 검사할 객체가 빈 객체인지를 검사하기 위해 사용한다.
빈 스트링, 빈 컬렉션, null, 빈 배열 ture값을 리턴한다.
obejct배열은 true 기본타입배열은 false이다.
<h1>empty</h1>
<%
pageContext.setAttribute("a", "hello");
pageContext.setAttribute("b", "");
pageContext.setAttribute("c", 100);
pageContext.setAttribute("d", 0);
pageContext.setAttribute("e", List.of());
pageContext.setAttribute("f", Map.of());
pageContext.setAttribute("h", new String[]{});
pageContext.setAttribute("i", new int[]{});
%>
<p>${empty a }</p> <!-- false -->
<p>${empty b }</p> <!-- true 빈 스트링-->
<p>${empty c }</p> <!-- false -->
<p>${empty d }</p> <!-- false -->
<p>${empty e }</p> <!-- true 빈 컬렉션(리스트)-->
<p>${empty f }</p> <!-- true 빈 컬렉션(맵)-->
<p>${empty g }</p> <!-- true null-->
<p>${empty h }</p> <!-- true 빈 배열-->
<p>${empty i }</p> <!-- false -->
11.39 EL 논리연산자
and, && / or,|| / not, !
키워드로 작성해도되고 각 연산자로 작성해도된다.
자바의 논리연산자와 같은 역할을 한다.
<h1>논리연산 (and or not)</h1>
<h1>and</h1>
<p>${true && true}</p> <!-- true -->
<p>${true && false}</p> <!-- false -->
<p>${false && true}</p> <!-- false -->
<p>${false && false}</p> <!-- false -->
<h1>or</h1>
<p>${true || true}</p> <!-- true -->
<p>${true || false}</p> <!-- true -->
<p>${false || true}</p> <!-- true -->
<p>${false || false}</p> <!-- false -->
<h1>not</h1>
<p>${!false}</p> <!-- true -->
<p>${!true}</p> <!-- false -->
not연산자는 비어있지 않은가와 같이 empty와 자주 같이 사용된다.
<%
pageContext.setAttribute("a", "");
pageContext.setAttribute("b", List.of());
pageContext.setAttribute("c", Map.of());
pageContext.setAttribute("d", null);
pageContext.setAttribute("e", "hello");
pageContext.setAttribute("f", List.of("hi"));
pageContext.setAttribute("g", Map.of("a", "b"));
%>
<p>${! empty a }</p> <!-- false -->
<p>${! empty b}</p> <!-- flase -->
<p>${! empty c }</p> <!-- false -->
<p>${! empty d }</p> <!-- false -->
<p>${! empty e }</p> <!-- true -->
<p>${! empty f }</p> <!-- true -->
<p>${! empty g }</p> <!-- true -->
11.40 EL 비교 연산자
==(eq), !=(ne), <(lt), >(gt), <=(le), >=(ge)가 있다.
<%
pageContext.setAttribute("a", 5);
pageContext.setAttribute("b", 3);
%>
<p>${a==b }</p> <!-- false -->
<p>${a != b }</p> <!-- true -->
<p>${a < b }</p> <!-- false -->
<p>${a > b }</p> <!-- true -->
<p>${a <= b }</p> <!-- false -->
<p>${a >= b }</p> <!-- true -->
<br />
<p>${a eq b }</p> <!-- false -->
<p>${a ne b }</p> <!-- true -->
<p>${a lt b }</p> <!-- false -->
<p>${a gt b }</p> <!-- true -->
<p>${a le b }</p> <!-- false -->
<p>${a ge b }</p> <!-- true -->
11.41 EL 비교 연산자 - 2
문자끼리 비교는 코드값을 비교한다.
숫자와 다른 타입끼리 비교할때는 숫자로 변환한 후 비교한다.
숫자로 변환할 수 없는 문자열와 숫자를 비교하면 exception이 발생한다.
<%
pageContext.setAttribute("a", 5);
pageContext.setAttribute("b", 11);
pageContext.setAttribute("c", "5");
pageContext.setAttribute("d", "11");
pageContext.setAttribute("f", "eleven");
%>
<p>${a lt b}</p> <!-- true -->
<p>${c lt d}</p> <!-- false 문자코드비교 -->
<p>${a lt d}</p> <!-- true 수와 다른 타입 비교시 수로 변경 -->
<p>${b lt c}</p> <!-- false 수와 다른 타입 비교시 수로 변경-->
<%-- <p>${a lt f }</p> exception --%>
11.42 EL 조건연산(삼항연산)
자바의 삼항연산과 같다. 연산결과가 true면 앞의 것 false면 뒤의 것이 출력된다.
<h1>조건 연산(삼항연산)</h1>
<%
pageContext.setAttribute("a", 3);
pageContext.setAttribute("b", 5);
%>
<p>${a lt b ? "작다" : "크다" }</p> <!-- 작다 -->
11.43 삼항연산 연습
numA가 크면 '첫번째 수가 큽니다'출력
numB가 크면 '두번째 수가 큽니다'출력
파라미터가 넘어오면 문자열이기 때문에 int값으로 파싱해줘야한다.
문자열과 숫자를 산술연산하면 숫자가 되는 성질을 이용할수도 있다.
<h1>16번</h1>
<form action="17process.jsp">
수1 : <input type="text" name="numA" value="12" /> <br />
수2 : <input type="text" name="numB" value="5" /> <br />
<input type="submit" value="전송" />
</form>
<%
request.setAttribute("numA", Integer.parseInt(request.getParameter("numA")));
request.setAttribute("numB", Integer.parseInt(request.getParameter("numB")));
%>
<p>${numA > numB ? '첫 번째 수가 큽니다' : '두 번째 수가 큽니다'}</p>
<p>${(param.numA + 0) > (param.numB + 0) ? '첫 번째 수가 큽니다' : '두 번째 수가 큽니다'}</p>
11.44 EL 자바코드
자주일어나지는 않지만 급할때 사용할 수 있다.
EL을 배운 이유가 JSP에서 자바코드를 없애기 위해서 배우고 있다.
스크립트 릿, 표현식, 정의를 안쓰고자 EL을 사용한다.
그런데 가끔 가다 자바코드를 사용하고 싶은 경우가 있다.
EL에서 자바코드를 사용할 수 있다. 하지만 왠만해선 사용하지 말자.
EL에서 표기하는데 한계가 있을때 직접 만들어서 사용할 수도 있다.
11.44.1 static 메소드
<h1>스태틱 메소드 사용</h1>
<p><%= Math.random() %></p>
<p>${Math.random()}</p>
내가 작성한 메소드를 사용할 수도 있다.
<h1>직접 만든 static 메소드 호출</h1>
<p>${MyUtil.method1()}</p>
11.44.2 instance메소드
자바코드 처럼 사용하면되는데 attribute명을 변수명처럼 사용해야한다.
<h1>instance메소드</h1>
<%
List<String> list = List.of("jsp", "java", "spring");
pageContext.setAttribute("mylist", list);
%>
<p><%=list.get(0) %></p>
<p>${mylist.get(0)}</p>
2023.04.04 후기
EL에 들어가는 모든 변수명은 attribute명에서 찾는 것을 생각해야한다.
param에서 찾는 등의 객체에서 찾는 방법들을 잊지 말아야한다.
그냥 파라미터를 가져와서 출력할수는 없고 attribute를 알아내서 property를 가져오는 방식으로 출력해야함을 잊지말아야한다.