🚩오늘의 할일.
1. 어느 스코프에 저장을 하든 뷰에서 저장되어있는 데이터 꺼낼 때 한가지 방식으로 꺼낼 수 있도록 통일해보자.
2. EL jsp spec을 사용해보자. 표현 언어 : 데이터 출력용 언어 - 제어문 없다.(if, for, while...) + JSTL과 함께 사용한다.
DB에서 코드조각을 만든 이유 : 스키마 구조를 이용하여 property 잡아보기
복습
PL에서 사용하는 맵퍼를 Data Mapper라고 하며 또는 sql mapper라고도 하고 ORM(object relation mapper)라고도 한다. 또한 여기서 사용하는 프레임웍을 퍼시스턴트 프레임웤이라고 한다.
어제 사용한 프레임웤 : Lombok
앞으로 사용할 프레임웍 :
myBatis , H/V , EL+JSTL+Tiles , 플로우컨트롤패턴과 커멘드패턴이 있는 Spring , 보안 Spring Security
, 양단에서 사용하게 하는 S.M , 배치잡하려는 스케쥴링Q콰츠
딕셔너리 뷰를 잘 활용해서 유아이를 구성해보자.
코드조각 짜보기!
💊지금한거는?
1. 오라클 활용해보기
2. CRUD를 통해 반복되는 코드 알아보
▶사용한 파일 : MeberVO 와 친구들
디버깅 사용하기
1. 첫 시작에 브레이크 포인트, 뷰를 찾으니까 뷰에서 백그라운드 코드에 브레이크 포인트
2. restart in debug
https://repo1.maven.org/maven2/jstl/jstl/1.2/
Index of /maven2/jstl/jstl/1.2/
repo1.maven.org
${} : EL 표현식 ,
request하지 않아도 그냥 표현됨. : 장점.
그런데 왕창 꺼내옴. 반복문 못돌림
JSTL써보자.
library
로딩,,,, <%@taglib uri="http://java.sun.com/jsp/jstl/core" %>
커스텀태그 이제 사용가능
prefix="c" c태그라고 부른다. 이제 c:으로 사용한다.
<tbody>
<c:if test="${not empty memList }">
</c:if>
<c:if test="${empty memList }">
<tr>
<td colspan="8">회원이 없음.</td>
</tr>
</c:if>
</tbody>
코드 가독성이 올라간다 스크립트 가 들어가지 않아도 되서/.!
foreach의 var 는 임시속성 : 변수가 아니라 scope안에 있는 어트리부트명, 4개중 뭘까? page! 페이지 않에 있으니까
그걸 다시 el로 접근하자.
<td>${member.memId }<td> 겟터이다. ->나중에 모두 자바코드로 바뀌는데 그때 member.getMemID로 바뀐다.
<c:url value=""></c:url> 클라이언트 사이드 절대경로 만들어준다.
스코프의 속성을 쉽게 꺼내오기 위해 EL표현방식
스코프가 없다면? EL도 필요가 없다 model1방식에서는 안쓴다.
🚩오후수업
EL 어떻게 써먹을지
단독으로 쓸수 없는 EL, 어떤 연산자들이 있는지....
▶elDesc.jsp
EL(Expression Language, 표현 언어)
: Scope를 통해 공유되는 속성값을 조회할 목적으로 사용되는 스크립트 형태의 언어. ${attributeName }
조회하는 목적이기에 null이 발생하면 ""화이트 스페이스로 바꿔버린다.
<%=Objects.toString(request.getAttribute("attributeName"), "") %>
${attributeName }
같은 결과!
1. 속성데이터에 대한 접근 방법
<%
pageContext.setAttribute("attr", "페이지속성");
request.setAttribute("attr", "요청속성");
%>
${attr } ==> "페이지속성"출력 ==> 가장 좁은 영역을 건드리게 된다. ==> 같은 이름이 있으면 매우 불안하다.
==> 그래서 5. 기본객체가 있다. 5번을 보자.
2. EL 연산자
자바의 연산자와 비슷하다.
1) 산술연산자 : +-*/%
- 자바에서는? + 가 컨캣연산자도 하지만 여기서는 그 역할 없다.
- ${3+2 }, ${"3"+2 }, ${"3"+"2" }, ${"a"+3 } ==> 555에
- ${3/2 } ==> 타입이 없으니까 연산이 수행될때 결정되고 1.5출력 실수연산을 한다.
- ${attrNum2+2 } ==> null + 2 ==> 0 + 2
- pageContext.setAttribute("attrNum2-2", "3"); ${attrNum2-2 } ==> ${pageScope['attrNum2-2'] }
2) 논리연산자
- : &&, ||, !, ==> html 템플릿 리터럴때문에 연산자 키워드로 더 많이 사용 ==> and, or, not
- ${true and true }, ${attrBool and true } ==> attrBool false로 간주했
3) 비교연산자
- : > gt, < lt, >= ge, <= le, == eq, != ne
- ${3 lt 4 }, ${3 ge 4 }, ${3 eq 4 }, ${3 ne 4 } ==> true false false true
- ${pageScope.attr eq requestScope.attr } 둘다 객체로 들어오면 eq가 내부적으로 equels 메서드로 변환된다. String은 객체, // 평소에는 그냥 equal 연산
4) 단항연산자
- ++ (=+), --(=-) ==> 할당연산자. EL은 조회의 목적이 있기 때문에 아직까지는 할당연산이 불가능 그래서 단항 연산자도 지원하지 않는다.
- empty : EL에 지원되는 유일한 단항연산자
- : empty <% pageContext.setAttribute("sample", ""); %> 또는 값으로 null
- ${empty sessionScope.attr }, ${empty sample } : 길이 체크 true 그런데 " " 하면 false
- <%pageContext.setAttribute("array", new String[]{}); %>
${empty array } ===> length 프로퍼티와 size, length 메서드 알아서 체크
1. 값이 있는가
2. 어떤 형태인가
3. 형태에 맞춰 길이비교
5) 삼항연산자
- : 조건식? 참표현 : 거짓표현
- ${empty array? "빈배열" : "채워진배열" }, ${not empty list? "채워진리스트" : "빈리스트" }
3. 속성 객체의 구성멤버 접근 방법
<%
MemberVO member = MemberVO.builder()
.memName("이름")
.build();
%>
${member } ==> member 는 속성도 아니고 지역변수 이다. 사용하려면? scope에 저장하여 속성이 되어야한다.
pageContext.setAttribute("aMem", member); ==>${aMem } toString 형태로 나온다.
이름을 출력하려면? ${aMem.getMemName() } ==>'이름' 겟터로 적용 그런데 많이 안사용해 3버전부터 ==>${aMem.memName } 이렇게 사용 ==> 이것도 겟터 쓴거임. ==> 메소드 호출하는 코드임
${aMem['memTest'] } 이것도 가능.
4. 속성 컬렉션의 요소에 대한 접근 방법
<%
String[] array = new String[]{"value1", "value2"};
List<String> list = Arrays.asList(array);
Set<String> set = new HashSet(list);
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
pageContext.setAttribute("attrArray", array);
pageContext.setAttribute("attrList", list);
pageContext.setAttribute("attrSet", set);
pageContext.setAttribute("attrMap", map);
%>
${attrArray[4] }, <%=array[4] %>
값을 처리하는게 목적이라서 왠만해서는 예외를 던지지 않는다.
${attrList[4] }, ${attrList.get(4) } ==> 화이트스페이스 / 에러 ==> 출력이 목적이라면 EL에서는 메서드를 잘 사용하지 않는다.
${attrSet }
${attrMap['key2'] } , ${attrMap.key2 }
map.put("key-3", "value3");
${attrMap.key-3 }, ${attrMap['key-3'] } ==> -3 / value3 ==> 연산먼저!!!!
5. EL 기본 객체
: 영역객체 : pageScope, requestScope, sessionScope, applicationScope
${requestScope.attr } ==> 닷노테이션으로 맵의 키에 접근하여 ==> "요청속성" 출력
스크립트 언어는 연산배열구조도 가능 ==>${requestScope['attr'] }
그런데,
session.setAttribute("a ttr", "세션 속성"); 이런 속성을 등록하여 ${a ttr }로 부르면 500에러. 기본형이 맞지 않기때문에 ==>${sessionScope['a ttr'] } 이렇게 연산배열로 표기하면 성공.
즉, 닷노테이션보다 연산배열을 더 사용해라
스크립트언어는 연산배열 구조를 잘 사용하면 리터럴로도 사용할 수 있다.
정적타입언어는 데이터의 타입이 정해져있어서 결과가 정수야 연산의 중심이 데이터야.
동적타입언어는 타입이 존재하지 않아. 데이터가 사용될때 타입이 결정돼. 연산의 중심이 데이터가 아니라 연산자이다.
2)요청파라미터객체 : param(Map<String, String>), paramValues(Map<String, String[]>)
<%=request.getParameter("name1") %>, ${param.name1 }, ${param['name1'] }
<%=request.getParameterValues("name1") %>, ${paramValues.name1[0] }, ${paramValues['name1'][0] }
1, 1, 1
[Ljava.lang.String;@2798a62a, 1, 1
3)요청 헤더 객체 : header(Map<String, String>), headerValues(Map<String, String[]>)
<%=request.getHeader("user-agent") %>, ${header['user-agent'] }
4) 쿠키 객체 : cookie(Map<String, Cookie>)
<%
Cookie[] cookies = request.getCookies();
for( Cookie tmp : cookies){
if("JSESSIONID".equals( tmp.getName()) ){
out.println(tmp.getValue());
}
}
%>
${cookie.JSESSIONID.value }, ${cookie['JSESSIONID']['value'] }
5) 컨텍스트 파라미터 객체 : initParam(Map<String, String>)
${initParam.imageFolder }
서블릿 컨텍스트에 겟 이닛파람으로 얻어야하는 객체인데 EL은 간단하게 가져옴.
6) pageContext
${pageContext.request.contextPath }
CORE TAG의 종류 알아보기
<pre>
: 커스텀 태그의 모음 라이브러리
<%-- <prefix:tagname attribute.../> --%>
1. Core 태그 종류
1) EL 변수(속성) 지원 : set, remove
<%-- <c:set var="sample" value="샘플" scope="session" /> --%>
${sample }
<c:remove var="sample" scope="session"/>
일반적인 변수가 아니라 속성이기 때문에 remove를 쓸 수 있었다.
지울때 어느 스코프인지 꼭 설정해줘라 왜냐면 4개 다 돌면서 속성네임 찾아서 다 지워버리니까 위험!!!!
2) 조건문 : if, choose~when~otherwise
<c:if test="${not empty sample }">
${sample }==> 있다
</c:if>
<c:if test="${empty sample }">
없다.
</c:if>
<c:choose>
<c:when test="${not empty sample }">
${sample }==> 있다
</c:when>
<c:otherwise>
없다.
</c:otherwise>
</c:choose>
step 이 1이면 생략이 가능하며 음수는 불가능함.
토큰 : 문장의 구성요소 중 최소한의 의미를 부여받을 수 있는 것을 말한다.
아버지가방에들어가신다
아버지 가방에 들어가신다
아버지가 방에 들어가신다
토큰에 따라 의미가 달라짐 토큰 3개 토큰에따라 반복 forTockens
out은 일반적인 소스를 그대로 이스케이프 시켜서 가지고 온다. 꺽쇠 하나도 없이 < 시켜버림...
escapeXml 이스케이프 하지 말아
<%
String message = (String)session.getAttribute("message");
session.removeAttribute("message"); // flash attribute
if(StringUtils.isNotBlank(message)){
%>
<script type="text/javascript">
alert("<%=message%>");
// Swal.fire({
// icon: 'error',
// title: 'Oops...',
<%-- text: '<%=message%>' --%>
// })
</script>
<%
}
%>
== > el로 만들어보리기
<c:if test="${not empty message }">
<script type="text/javascript">
alert("${message}");
</script>
<c:remove var="message" scope="session"/>
</c:if>
내일은
CL 에서 19개 수작업으로 검증해보고 H/V로 해보고..
'내가 보려고 정리하는 > Spring' 카테고리의 다른 글
웹 : 0324 (0) | 2023.03.24 |
---|---|
웹 : MAVEN : 0323(2) (2) | 2023.03.23 |
웹 : Performance Check : 0321(2) (0) | 2023.03.21 |
웹 : 0321 (0) | 2023.03.21 |
웹 : 3Tier로의 확장, DB연결하기 : 0320 (0) | 2023.03.20 |