ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • EL, JSTL 프레임워크 -0624
    웹프로그래밍 2022. 6. 24. 19:29
    728x90

    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&lt;String, Object&gt;)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" )}

    https://tiles.apache.org/

     

    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 

    https://fullcalendar.io/demos

    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
Designed by Tistory.