-
EL, JSTL 프레임워크 -0624웹프로그래밍 2022. 6. 24. 19:29728x90
EL ,JSTㅣ, TILES :프레임워크
타일즈 프레임워크 : 리스너, 필터 개념 알아야함

가입할 수 있는 양식제공 , 뷰 리절브 양도 하고 있어

순서 알아두기

EL 축약형 만들어 모두가 컨텍스트 필요해 그럼 application미리 넣어놨다면 쉽게 꺼낼 수 있고
절대경로 만드는데 더 쉬워짐
=> 값을 출력할 수 있지만 제어할 수 없어
JSP 스펙에서 서버사이드 이벤트 처리 방법
1. target 선별 : context(web application)
2.이벤트 종류: request, session, servletContext
lifecycle : 생성, 소멸
scope : add, remove, replace
3. 이벤트 헨들러 : Listener 의 구현체
4.이벤트 헨들러를 target 대해 listening 할 수 있도록 부착함 : web.xml -> listener<pre> 1. target 선별 : context(web application) 2.이벤트 종류 3. 이벤트 헨들러 : 발생한 이벤트참조함 4.이벤트 헨들러를 target 대해 listening 할 수 있도록 부착함 <button id="sampleBtn">샘플버튼</button> <!-- 버튼을 클릭했을 때 , alert메세지를 띄우자 --> <script type="text/javascript"> // 1.target 선별 let sampleBtn =document.getElementById('sampleBtn'); // 2.이벤트 종류, 3. 이벤트 헨들러, 4.이벤트 헨들러를 target 대해 listening 할 수 있도록 부착함 let eventHandler =function(event){ alert(event.target.innerHTML); } sampleBtn.onclick =eventHandler; </script>//새로운 요청이 발생하면 (request,lifecycle : 생성), 클라이언트의 ip를 콘솔에 출력



새로운 요청이 발생하면 (request)이므로 이거 선택

우리가 평소 사용하던것과 다름 http없어 그래서 변환을해줘야함

Local: 자기자신 Remote : 클라이언트
시간얼마나 걸렸는지 계산하려고하니 지금 계산할 수 없어
서블릿에서 운영되는 싱글톤으로 여기 객체는 하나의 유저가 사용하는것이아니라 여러사람이 제어하는것임
전역변수로 만들어서는 안된다.

3번요청된다면 start에는 마지막 3번째의 시간만 들어가있을것이다 그럼 1,2번 요청은 사라짐
package kr.or.ddit.listener; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServletRequest; @WebListener public class CustomRequestLifecycleListener implements ServletRequestListener { public static final String STARATTR =" CustomRequestLifecycleListener.start"; public void requestInitialized(ServletRequestEvent sre) { ServletRequest requset =sre.getServletRequest(); HttpServletRequest req =(HttpServletRequest)requset; System.out.printf("%s의 요청 발생\n", req.getRemoteAddr()); long start =System.currentTimeMillis(); req.setAttribute(STARATTR, new Long(start)); // 오토박싱 기본생성자 래퍼.. 대문자 L로 들어감 기본형으로들어감 } public void requestDestroyed(ServletRequestEvent sre) { ServletRequest requset =sre.getServletRequest(); HttpServletRequest req =(HttpServletRequest)requset; long end =System.currentTimeMillis(); long start =((Long)req.getAttribute(STARATTR)).longValue(); //다시 기본형으로 언박싱 System.out.printf("소요시간 : %d\n",(end-start)); } }request라는 scope에 넣자
long start =((Long)req.getAttribute(STARATTR)).longValue(); //다시 기본형으로 언박싱
-> 신경안쓴 이유는 오토언박싱 때문에
리스너는 잠복근무같은 요청이 들어오면 동작을 하고 요청하고 응답하는 시간 을 잡는것
엔터 딱 누르면 그때부터 요청들어온것을 확인하고 응답하기까지의 시간을 체크함



package kr.or.ddit.listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class ContextLoaderListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { ServletContext application =sce.getServletContext(); application.setAttribute("cPath", application.getContextPath()); System.out.printf("%s 로딩완료\n", application.getContextPath()); } public void contextDestroyed(ServletContextEvent sce) { ServletContext application =sce.getServletContext(); System.out.printf("%s 언로드\n", application.getContextPath()); } }=> 실행할때 얘가 이미 cPath를 set해주고 있으므로 browsing.jsp에서 <%set..%>해줄필요 없다.



<방문자 수 출력하기 예제>

위에 리스너없어서직접등록하기


package kr.or.ddit.listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class ContextLoaderListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { ServletContext application =sce.getServletContext(); application.setAttribute("cPath", application.getContextPath()); application.setAttribute("userCount", 0); 추가!!!!!!!!!! System.out.printf("%s 로딩완료\n", application.getContextPath()); } public void contextDestroyed(ServletContextEvent sce) { ServletContext application =sce.getServletContext(); System.out.printf("%s 언로드\n", application.getContextPath()); } }
package kr.or.ddit.listener; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionIdListener; import javax.servlet.http.HttpSessionListener; public class CustomSessionListener implements HttpSessionListener{ @Override public void sessionCreated(HttpSessionEvent se) { ServletContext application =se.getSession().getServletContext(); int userCount =(int)application.getAttribute("userCount"); application.setAttribute("userCount", ++userCount); } @Override public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub } }index.jsp추가
현재 누적 방문자수 : <%=application.getAttribute("userCount") %><현재 로그인 된 사람 수 구하는 예제>
현재 방문자수로 바꾸기
반드시 인증받은 유저에 대해서만 카운팅 세션이만들어졌을때가 아닌
usmember들어갔다 누군가가 새로 로그인했다. 그때 카운팅 시키면 인증받은 유저 카운팅 할 수 있다.
로그아웃은 usmember가 사라졌을때

=> 인증받은 유저 체킹 가능해짐
EDD방식 사용중임 (리스너 하나로도 처리가가능, 이벤트를 발생시켜서 처리하는방법,스프링에서 주로 이용)
1.서블릿 컨텍스트리스너 : 비어있는 컬랙션
2. 세션 어트리뷰트 리스너
표현언어(Expression Language): Model2 구조에서 활용
: 값을 출력하기 위한 기능만을 갖고 있는 언어. 제어문의 형태가 없음. , \${속성명} ,스크립트 형태 언어
속성을 쓸 필요없을경우 EL은 사용되지 않는다.
영어와 숫자만 가능
<%
String sample ="샘플";
%>
<%=sample %>, ${sample=>샘플 하나만 나옴
EL : 4개의 스코프중에 들어가있는 속성을 사용하는것 ,jsp기본객체와 다름
<% String sample ="샘플"; pageContext.setAttribute("sample", sample); %> <%=sample %>, ${sample } </pre>
1. EL 연산자
1)산술연산자
1)산술연산자 : +-/*% ${1+1}, ${"1"+1 }
=> 스크립트언어의 특징 변수타입 준적 없잖아 데이터타입이 런타임에 결정 사용된는 시점에 결정됨
피연산자 타입이 결정될때는 연산을할때야 +는 연산기능만 있어 그래서 문자1을 숫자1로 파싱을 해버림
EL 피연산자가 아니라 은연산자의 중심
+는 컨켓연산을 하지않는다. 타입결정은 연산을 수행할때이다!!!!
${1+1}, ${"1"+1 },${"a"+1}
${1+1}, ${"1"+1 },\${"a"+1},${a+1 }앞에있는 a는 속성명으로 간주 그런속성 없네 속성 없으니까 null 이네 근데 이 null을 0으로 바꿔서 계산함

<% String sample ="1000"; pageContext.setAttribute("sample", sample); %> <%=sample %>, ${sample } 1. EL 연산자 1)산술연산자 : +-/*% ${1+1}, ${"1"+1 },\${"a"+1},${a+1 },${sample+1 }
2) 논리연산자
2)논리연산자: &&(and), ||(or),!(not) ${true and true }, ${"true"and true }
=> 강제로 문자열을 논리값으로 바꿈
2)논리연산자: &&(and), ||(or),!(not) ${true and true }, ${"true"and true },${a and true }
a는 값이 아니라 판단 속성이라판단했는데 속성이 없네 null이네 null을 논리값으로바꾸려했기에 false가 됨
3)단항 연산자 : empty
El: 꺼내오는게 목적 그래서 할당 연산자 존재 x 근데 지금버전은 할당연산자 존재하여 증감연산자 (++,--)사용가능
근데 우리나라 지원안하므로 empty만 사용
3)단항 연산자 : empty ${empty sample }
sample은 안비워져있으니까 false
<% String sample ="1000"; pageContext.setAttribute("sample", sample); pageContext.setAttribute("blank", " "); %> <%=sample %>, ${sample } 1. EL 연산자 1)산술연산자 : +-/*% ${1+1}, ${"1"+1 },\${"a"+1},${a+1 },${sample+1 } 2)논리연산자: &&(and), ||(or),!(not) ${true and true }, ${"true"and true },${a and true } 3)단항 연산자 : empty ${empty sample }, ${empty a }, ${empty blank}
=>(문자열 길이)데이터 길이를 파악하고 있음 " " 빈칸일거같지만 길이를 파악해서 fasle찍어줌 만약 ""이거라면 true
<% pageContext.setAttribute("list", Arrays.asList("v1","v2")); %> 3)단항 연산자 : empty ${empty sample }, ${empty a }, ${empty blank} ,${empty list }컬렉션 길이 를 파악하고 잇음

-pageContext.setAttribute("list", Arrays.asList()); 하면 true나옴 속성 존재하지만 null값이니 ....
-${not empty sample } !대신 not쓰는것이 좋긴함
1. 속성의 존재 여부
2. null여부 판단 -> 없구나 하고 끝내 근데 null이 아니면 String(length), Collection(size)
4) 삼항 연산자 :
4) 삼항 연산자: 조건식? 참:거짓 ${not empty test? "있다":"없다" }not이 붙어있어서 비어있지않으면 ? 근데 test없자나 그래서 true가 나왔어야 하는데 not이 잇어서 없다나옴

2. 객체 접근 방법MemberVO member =new MemberVO(); 이렇게 선언만해놓고
${member }

=> null강제로 화이트스페이스로 출력함
효율성찾는다면 작은 영역부터 뒤진다
page<requset이므로 page에서 꺼내옴
그럼영원히 request가져올 수 없자나 특정 스코프 참조는 ${requestScope.member } 이렇게
지금EL 2.2 EL은 메소드 호출못했었음 옛날버전이라면 ? 자바빈 규약은 거꿀로 접근 ${requsetScope.member.memName } 이렇게 getter을 접근했음
<% MemberVO member =new MemberVO(); pageContext.setAttribute("member", member); MemberVO member2 = new MemberVO(); member2.setMemName("신규"); request.setAttribute("member", member2); %> 2. 객체 접근 방법 ${requestScope.member.getMemName() }, ${requestScope.member.memName }, ${requestScope.member.getMemTest()}, ${requestScope.member.memTest} ${requestScope.member["memName"]}
3. 집합 객체 접근 방법값을 출력하는게 목적 제어하는게 아니라 그래서 어지간한 에러는 화이트 스페이스로 바꾼다.
1)array, 2) list
<% String[] array =new String[]{"value1","value2"}; List<String> list = Arrays.asList(array); Set<String> set = new HashSet<>(list); //이 3가지 파생구조 가능 //map은 파생구조x Map<String, Object> map = new LinkedHashMap<>(); map.put("key1","value1"); map.put("key2","value2"); pageContext.setAttribute("sampleArray", array); pageContext.setAttribute("sampleList", list); pageContext.setAttribute("sampleSet", set); pageContext.setAttribute("sampleMap", map); %> 1. array : <%--<%=array[2] %>--%>, ${sampleArray[2]} 2. list : <%=list.get(1) %>, ${sampleList.get(1) }
2. list : <%=list.get(1) %>, ${sampleList.get(1) }, ${sampleList[1] }
1. array : <%--<%=array[2] %>--%>, ${sampleArray[2]} 2. list : <%-- <%=list.get(2) %> --%>, <%-- ${sampleList.get(2) } --%>, ${sampleList[2] }
=> 예외 발생안함 그래서 3번 쓰는것이 좋아!!!
3)set
3. set: <%=set %>, ${sampleSet }set: 순서가 없어 인덱스 존재 x
표현식을 통해서 하나를 접근하는 방법은 없어
4)map
4. map :<%=map.get("key2") %>, ${sampleMap.get("key2") }, ${sampleMap.key2}, ${sampleMap["key2"]}[ ]:연산구조배열

4. map :<%=map.get("key-2") %>, ${sampleMap.get("key-2") }, ${sampleMap.key-2}, ${sampleMap["key-2"]}
-연산자로 인식해버림
즉 4번이 제일안전
key 2 이렇게 하면
만약 공백이면 토큰이 짤려버려서 3번은 또 에러남
4. EL 기본객체1) Scope객체 : (Map<String, Object>)pageScope, requestScope, sessionScope, applicationScope
${pageScope.pageAttr } -> ${pageScope["pageAttr"] } ${sessionScope.sessionAttr } -> ${sessionScope["sessionAttr"] } ${requestAttr } -> ${requestScope.requestAttr } -> ${requestScope["requestAttr"] }
2. Parameter객체(Map) : param(Map<String, String>), paramValues(Map<String, String[]>)<%=request.getParameter("paramName") %>, <%=request.getParameterValues("paramName") %> ${param.paramName }, ${paramValues.paramName }
3 .Header객체(Map) : header(Map<String, String>), headerValues(Map<String, String[]>)<%=request.getHeader("accept") %> ${header.accept } -> ${header['accept'] }
user-agent <%=request.getHeader("user-agent") %> ${header.user-agent } -> ${header['user-agent'] }
되도록 [] 사용하도록
4. Cookie객체(Map) :cookie클라이언트쪽에서 꺼내야함 : 나에게 필요한 쿠키 찾으려면 <% Cookie[] cookies =request.getCookies(); Cookie finded =null; if(cookies!=null){ for(Cookie tmp:cookies){ if("JSESSIONID".equals(tmp.getName())){ //쿠키 찾았다! finded =tmp; break; } } } out.print("JSESSIONID :"+finded.getValue()); %>
EL---> ${cookie.JSESSIONID.value }
연산배열로 바꿔보자~
EL---> ${cookie.JSESSIONID.value } -> ${cookie['JSESSIONID']['value'] }
5. pageContext객체<%-- ${pageContext.request.getContextPath() } --%> ${pageContext.request.contextPath }, ${cPath } ${pageContext.session.id}<%=session.getId() %>

EL 단점: 위에 <%%>안에 내용 없앨 수 없음
그래서 나온게 jstl



1.1 버전의 jsp 를 사용해야함 sql, xml거의 안씀

코어 태그
c:if : if문 역할
EL은 꺼내오기만하니까 같이 사용하면 역할 수행
<% String message =(String)session.getAttribute("message"); if(StringUtils.isNoneBlank(message)){ %> <%-- ${message} --> JSTL --%> <script> alert("${message}"); </script> <% session.removeAttribute("message"); } %>이것을 대체할 수 있다.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <c:if test="${not empty message }"> <script> alert("${message}"); </script> <c:remove var="message" scope="session"/> </c:if>번외 : War : 배포하기전단계임 -> maven없어짐


태그라이브러리 디피니션

커스텀태그 식별자, 이거없으면 커스텀 태그 못씀

if사용할 수 있었던 것임
만약에 url 하고 컨트롤 스페이스 안되면 c.tld있나 확인
JSTL(Jsp Standard Tag Library) : EL과 함께 사용, 모든데이터는 속성, 변수는 없음
:커스텀 태그들 중 널리 쓰이는 것들을 모아놓은 라이브러리.taglib 로 사용할 커스텀 태그의 라이브러리 파일을 로딩.
<c:if test="${empty sample }"> "sample속성 없음." </c:if> <c:if test="${not empty sample }"> "sample 속성 있음." </c:if> <c:choose> <c:when test="${empty sample }"> "sample속성 없음." </c:when> <c:otherwise> "sample 속성 있음." </c:otherwise> </c:choose> <c:forEach begin="1" step="1" end="10" var="i"> ${i } </c:forEach>i는 pageScope영역에 저장되어있음

<% pageContext.setAttribute("array", new String[]{"value1","value2"}); %> <c:forEach items="${array}" var="element"> ${element} </c:forEach>
<c:if test="${empty sample }"> "sample속성 없음." </c:if> <c:if test="${not empty sample }"> "sample 속성 있음." </c:if> <c:choose> <c:when test="${empty sample }"> "sample속성 없음." </c:when> <c:otherwise> "sample 속성 있음." </c:otherwise> </c:choose> <c:forEach begin="1" step="1" end="10" var="i"> ${i } </c:forEach> <% pageContext.setAttribute("array", new String[]{"value1","value2"}); %> <c:set var="array" value='<%=new String[]{"value1","value2"} %>' scope="page"/> <c:forEach items="${array}" var="element"> ${element} </c:forEach> <c:remove var="array" scope="page"/> <c:if test="${not empty array }"> 배열있음 </c:if> <c:if test="${empty array }"> 배열없음 </c:if>
기타: url(url rewriting ), import, out
<c:url value="/02/first.jsp" var="newURL"></c:url> ${newURL} <a href="/02/first.jsp">first.jsp</a>${cPath} 안해줘도 된다.

기타: url(url rewriting ), import, out <c:url value="/02/first.jsp" var="newURL"> <c:param name="name1" value="value1"/> <c:param name="name2" value="value2"/> </c:url> ${newURL} <a href="${newURL}">first.jsp</a>
=> url(url rewriting ) : 클라이언트사이드, 쿼리스트링, 세션파라미터 경우에 따라 붙여준다.
<c:import url="https://www.naver.com"></c:import><import>

<c:import url="https://www.naver.com" var="naver"></c:import> ${naver }=> var를 쓰게되면 네이버는 안나오는데 일단 저장을 해놓은것이고 다시 출력하려면 EL사용해야함
네이버 pageScope에 저장
<out>
<c:import url="https://www.naver.com" var="naver"></c:import> <c:out value="${naver }"></c:out>
<c:import url="https://www.naver.com" var="naver"></c:import> <c:out value="${naver}" escapeXml="false"></c:out>=> escapeXml="false" : 소스 보기 하느냐 안하느냐에 따라 달라짐 true하면 코드 나옴 ..!!!!

< EL태그로 바꿔보기 >

- jdbcDesc. jsp 바꾸기전
<%@page import="kr.or.ddit.vo.MemberVO"%> <%@page import="java.util.List"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <table class="table table-bordered"> <thead> <tr> <th>회원아이디</th> <th>회원명</th> <th>휴대폰</th> <th>거주지역</th> <th>이메일</th> <th>마일리지</th> </tr> </thead> <tbody> <% List<MemberVO> memberList = (List) request.getAttribute("memberList"); if(memberList.size() > 0) { for(MemberVO member : memberList){ %> <tr> <td><%=member.getMemId() %></td> <td><%=member.getMemName() %></td> <td><%=member.getMemHp() %></td> <td><%=member.getMemAdd1() %></td> <td><%=member.getMemMail() %></td> <td><%=member.getMemMileage() %></td> </tr> <% } } else { %> <tr> <td colspan="6">회원이 아직 없음.</td> </tr> <% } %> </tbody> </table>바꾼후
<%@page import="kr.or.ddit.vo.MemberVO"%> <%@page import="java.util.List"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <h4>회원목록 조회</h4> <table class="table table-bordered"> <thead> <tr> <th>회원아이디</th> <th>회원명</th> <th>휴대폰</th> <th>거주지역</th> <th>이메일</th> <th>마일리지</th> </tr> </thead> <tbody> <c:choose> <c:when test="${not empty memberList}"> <c:forEach items="${memberList}" var="member"> <tr> <td>${member.memId }</td> <td>${member['memName'] }</td> <td>${member.memHp}</td> <td>${member.memAdd1 }></td> <td>${member.memMail }</td> <td>${member.memMileage }</td> </tr> </c:forEach> </c:when> <c:otherwise> <tr> <td colspan="6">아직 회원이 없음</td> </tr> </c:otherwise> </c:choose> </tbody> </table>
employeeList.jsp
El은 page에서 찾고 requset에서 찾고... 없으면 점점 영역을 넓혀 찾아간다.
바꾸기전
<% List<DataBasePropertyVO> dataList =(List)request.getAttribute("dataList"); for(DataBasePropertyVO tmp : dataList){ %> <tr> <td><%=tmp.getPropertyName()%></td> <td><%=tmp.getPropertyValue()%></td> <td><%=tmp.getDescription()%></td> </tr> <% } %><%@page import="kr.or.ddit.db.ConnectionFactory"%> <%@page import="java.util.List"%> <%@page import="java.util.ArrayList"%> <%@page import="kr.or.ddit.vo.DataBasePropertyVO"%> <%@page import="java.sql.SQLException"%> <%@page import="java.sql.ResultSet"%> <%@page import="java.sql.Statement"%> <%@page import="java.sql.Connection"%> <%@page import="java.sql.DriverManager"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>11/jdbcDesc.jsp</title> </head> <body> <h4>JavaDataBaseConnectivity - JDBC Driver</h4> <pre> JDBC 단계 1. 벤더가 제공하는 드라이버를 빌드패스에 추가(pom.xml) 2. 드라이버 로딩 3. Connection 수립 4. Query 객체 생성 Statement : 기본 쿼리 객체로 모든 쿼리 객체의 상위. PreparedStatement(선컴파일된 쿼리 객체) : 쿼리 객체 생성시 미리 고정된 쿼리문에 의해 컴파일된 쿼리 객체가 생성. CallableStatement : procedure/function 등 일련의 명령 집합객체를 실행할때. 5. Query 실행 ResultSet executeQuery : SELECT (rowcount) int executeUpdate : INSERT/UPDATE/DELETE 6. 자원 해제(close) </pre> <table> <c:forEach items="${dataList}" var="tmp"> <tr> <td>${ tmp.propertyName}</td> <td>${tmp.propertyValue}</td> <td>${tmp.description}</td> </tr> </c:forEach> </table> </body> </html>
memberForm.jsp
=> null문자를 전혀 고려하지 않고도 사용하기 편하다
memberList.jsp
browsing.jsp
2. fmt : parsing, formatting

fmt : 국제화 코드 , Locale(언어,지역정보 포함)
formatNumber,formatDate : 숫자를 문자로 ,날짜를 문자로 (포멧)
parseDate : 문자를 날짜로 파싱)
2. fmt : parsing, formatting <c:set var="today" value="<%=new Date() %>"/> <fmt:formatDate value="${today}"/>
2. fmt : parsing, formatting <c:set var="today" value="<%=new Date() %>"/> <fmt:formatDate value="${today}" dateStyle="long" timeStyle="long" type="both"/>
2. fmt : parsing, formatting <c:set var="today" value="<%=new Date() %>"/> <fmt:formatDate value="${today}" dateStyle="long" timeStyle="long" type="both" var="todayStr"/> before parsing -> ${todayStr } <fmt:parseDate value ="${todayStr}" dateStyle="long" timeStyle="long" type="both" var="today2"/> after parsing -> ${today2} ,${today2.time}type="both" => time이랑 date이랑 같이 보내주겠다 .

memberList.jsp도 수정해보기
<td> <fmt:formatNumber value="${member.memMileage }" type="currency"/> </td>
<td> <fmt:setLocale value="<%=Locale.US %>"/> <fmt:formatNumber value="${member.memMileage }" type="currency"/> </td>
3. functions

${fn:replace("abc","b","B") }, ${"abc".replace("b","B" )}
Apache Tiles - Home
<!-- /* * $Id: index.xml 1813843 2017-10-31 02:56:12Z mck $ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding cop
tiles.apache.org











=>근데 여기서 "" 이거 꼭 빼주기


1. 거푸집만들기
ex) 구멍 4개 뚫었네 jsp 하나 타일조각 의미하는 4개 총 5개
템플릿은 : 어트리뷰트 페이지 하나를 데피니션
1.커스텀태그 쓸 수 있도록 로딩


=> 바디에 들어갈 수 있는것들
https://tiles.apache.org/framework/tutorial/basic/pages.html


body역할 
변경
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd" > <tiles-definitions> <definition name="parent" template="/WEB-INF/views/template_tiles.jsp"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="preScript" value="/includee/preScript.jsp" /> <put-attribute name="leftMenu" value="/includee/leftMenu.jsp" /> <put-attribute name="postScript" value="/includee/postScript.jsp" /> </definition> <definition name="sample/*" extends="parent"> <put-attribute name="body" value="/WEB-INF/views/sample/{1}.jsp" /> </definition> <definition name="member/*" extends="parent"> <put-attribute name="body" value="/WEB-INF/views/member/{1}.jsp" /> </definition> <definition name="employee/*" extends="parent"> <put-attribute name="body" value="/WEB-INF/views/employee/{1}.jsp" /> </definition> <definition name="server/browsing" extends="parent"> <put-attribute name="body" value="/WEB-INF/views/server/browsing.jsp" /> </definition> <definition name="11/jdbcDesc" extends="parent"> <put-attribute name="body" value="/WEB-INF/views/11/jdbcDesc.jsp" /> </definition> </tiles-definitions>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd" > <tiles-definitions> <definition name="sample/*" template="/WEB-INF/views/template_tiles.jsp"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="preScript" value="/includee/preScript.jsp" /> <put-attribute name="leftMenu" value="/includee/leftMenu.jsp" /> <put-attribute name="body" value="/WEB-INF/views/sample/{1}.jsp" /> <put-attribute name="postScript" value="/includee/postScript.jsp" /> </definition> <definition/> <definition name="member/*" template="/WEB-INF/views/template_tiles.jsp"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="preScript" value="/includee/preScript.jsp" /> <put-attribute name="leftMenu" value="/includee/leftMenu.jsp" /> <put-attribute name="body" value="/WEB-INF/views/member/{1}.jsp" /> <put-attribute name="postScript" value="/includee/postScript.jsp" /> </definition> <definition/> </tiles-definitions>근데 더 쉽게 바꿀 수 있어
MemberListServlet
그리드 빼기
DelegatingViewResolver resolver =new DelegatingViewResolver(); String viewName ="/WEB-INF/views/member/memberList.jsp"+GridTemplateViewResolver.GRIDSUFFIX; resolver.viewResolve(viewName,req,resp); DelegatingViewResolver resolver =new DelegatingViewResolver(); String viewName ="/member/memberList.tiles"; resolver.viewResolve(viewName,req,resp);MVC
GridTemplateView 삭제
Dele 수정
template.jsp지우기
지금 발생하는 에러 없애서 파일즈 띄울것
공유폴더 : DB10제txt
employees hiredate 컬럼네임인게 있엉 이플러그인 이용해서 이날 입사한 사람들 뿌려주기 +fancytree 쓰던 어뎁터 패턴 쓰기
AA : 환경셋팅
TA어떤기술 사용할거냐 찾는 사람 TA : 호기심많아 (주로)
테스트 시나리오 작성하고 관리
BA: 요구사항정의서 ,조율 경험이 있는 사람
DA : DB설계
UA : userInterface : 화면단 잘 만드는 디자인 감각 css만들어봄 경험
728x90'웹프로그래밍' 카테고리의 다른 글
번외 ) grid적용하는 예제 이해하기 (0) 2022.06.27 tiles를 적용한 후 에러잡기 (0) 2022.06.25 회원등록, DB -22.06.23 (0) 2022.06.23 로그인처리, 템플릿맛보기-0622 (0) 2022.06.22 JDBC-22.06.21 (0) 2022.06.22