이안의 평일코딩

JSP 5일차 - JSTL / 망고플레이트 본문

Back-end/JSP

JSP 5일차 - JSTL / 망고플레이트

이안92 2020. 10. 7. 09:50
반응형

2020.10.07(수)

 

JSTL => Java Standard Tag Library : XML형식

1. 지원하는 태그와 속성만 사용이 가능

2. 오버라이딩 => 사용자 정의 태그라이브러리

3. JSP => View(화면출력 용도) => if, for, 다중 if

 

=> 1. core

        <c:set var="" value=""> : 변수 설정

                         키           값 ==> request.setAttribute(var에 지정된 키, value에 있는 값);

        제어문

        <c:if test="조건문">결과값</c:if>

             if(test에 지정된 조건문) =====> 단점 else가 없다(단일 조건문만 사용이 가능)

        <c:forEach var="i" begin="1" end="10" step="1">

             for(int i=1(begin); i<=10(end); i++(step))

                       = end는 포함 end="10" ==> i<=10

                       = step => 음수는 사용할 수 없다 (양수만) ==> 일반 for문 사용

        <c:forEach var="vo" items="배열,ArrayList">

              for(MovieVO vo:list) ==> for-each(향상된 for) ==> list가 두개일때 처리

 

        <c:choose> switch,다중 if

             <c:when test="조건문">결과</c:when>

             <c:when test="조건문">결과</c:when>

             <c:when test="조건문">결과</c:when>

             <c:when test="조건문">결과</c:when>

             <c:otherwise>해당되는 조건이 없는 경우에 처리</c:otherwise> default, else

        </c:choose>

 

        <c:forTokens var="" value="id|sex|name|pwd" delims="|">

          var: 자를 문자,  value값 : 분해 대상,  delims : 구분문자

 

        URL(화면 이동)

          <c:redirect url="이동할 주소">

               => response.sendRedirect(url에 설정된 주소)

          <c:out value=""/> => <%=%> 출력할때 주로 사용

 

=> 2. fmt : 변환

           = 날짜 변환

                <fmt:formatDate value="변경될 날짜 데이터" pattern="">

                     년도 : yyyy

                     월 : M, MM ==> M (1,2,3,..10,11,12), MM (01,02~10,11,12)

                     일 : dd

                     시간 : hh

                     분 : mm

                     초 : ss

                                         ==> SimpleDateFormat(pattern에 지정된 형식)

            = 숫자 변환

                 <fmt:formatNumber value="변경할 숫자" pattern="00,000"/>

                     오라클 : 9 , 자바 : 0

                 예)$<fmt:formatNumber value="90000" pattern="00,000"/> => 90,000

                        <fmt:~> ==> out.println()

=> 3. function(fn) : String메소드 호출 ====> 333page

         length(), substring(), split(), trim(), toUpperCase()

         toLowerCase(), replace(), indexOf(), startsWith(), endsWith()

        ======================== JavaScript

        ${fn:length("abcdefg")}

        ${fn:substring(문자열,1,5)}

 

exam1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%-- 변수설정, 제어문, URL : core --%>
<%-- 태그(XML)을 이용해서 자바 라이브러리를 만든다 : taglib --%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%-- 날짜 변경, 숫자 변경 : format --%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%-- String클래스의 메소드를 사용할 수 있게 만든 라이브러리 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<fmt:formatNumber value="90000" pattern="00,000"/><br>
	<c:out value="Hello JSP"/> <!-- Javascript : Jquery ($)=> ${} -->
	<%--
		Javascript ==> JSTL 기능 => 그래프 제작
	 --%>
</body>
</html>

exam2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	List<String> list=new ArrayList<String>();
	list.add("홍길동"); //0 list.get(0) => varStatus
	list.add("심청이"); //1
	list.add("박문수"); //2
	List<Integer> list2=new ArrayList<Integer>();
	list2.add(30); //0
	list2.add(25); //1
	list2.add(33); //2
%>
<c:set var="names" value="<%=list %>"/>
<c:set var="ages" value="<%=list2 %>"/>
<%--
	홍길동(30)
	심청이(25)
	박문수(33)
 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:forEach var="name" items="${names }" varStatus="s">
	<%-- varStatus => index번호 --%>
		${s.index }:${name }(${ages[s.index] })<br>
	</c:forEach>
</body>
</html>

 

망고플레이트

 

Java Resources/src

Config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
   "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="db.properties"/>
  <typeAliases>
    <typeAlias type="com.sist.dao.RecipeVO" alias="RecipeVO"/>
    <typeAlias type="com.sist.dao.ChefVO" alias="ChefVO"/>
  </typeAliases>
  <environments default="development">
    <environment id="development">
       <transactionManager type="JDBC"/>
       <dataSource type="POOLED">
           <property name="driver" value="${driver}"/>
           <property name="url" value="${url}"/>
           <property name="username" value="${username}"/>
           <property name="password" value="${password}"/>
       </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="com/sist/dao/recipe-mapper.xml"/>
  </mappers>
</configuration>

db.properties

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@211.238.142.000:1521:XE
username=hr
password=happy

 

Java Resources/src/com.sist.dao

ChefVO.java

package com.sist.dao;
/*
 *      POSTER    NOT NULL VARCHAR2(260) 
		CHEF      NOT NULL VARCHAR2(100) 
		MEM_CONT1          VARCHAR2(20)  
		MEM_CONT3          VARCHAR2(20)  
		MEM_CONT7          VARCHAR2(20)  
		MEM_CONT2          VARCHAR2(20) 
		
		SELECT poster as image,chef,....  image
		
		class ChefVO
		{
		   private String image;
		}
 */
public class ChefVO {
    private String poster;
    private String chef;
    private String mem_cont1;
    private String mem_cont2;
    private String mem_cont3;
    private String mem_cont7;
    private int recipeCount;
    
	public int getRecipeCount() {
		return recipeCount;
	}
	public void setRecipeCount(int recipeCount) {
		this.recipeCount = recipeCount;
	}
	public String getPoster() {
		return poster;
	}
	public void setPoster(String poster) {
		this.poster = poster;
	}
	public String getChef() {
		return chef;
	}
	public void setChef(String chef) {
		this.chef = chef;
	}
	public String getMem_cont1() {
		return mem_cont1;
	}
	public void setMem_cont1(String mem_cont1) {
		this.mem_cont1 = mem_cont1;
	}
	public String getMem_cont2() {
		return mem_cont2;
	}
	public void setMem_cont2(String mem_cont2) {
		this.mem_cont2 = mem_cont2;
	}
	public String getMem_cont3() {
		return mem_cont3;
	}
	public void setMem_cont3(String mem_cont3) {
		this.mem_cont3 = mem_cont3;
	}
	public String getMem_cont7() {
		return mem_cont7;
	}
	public void setMem_cont7(String mem_cont7) {
		this.mem_cont7 = mem_cont7;
	}
	
}

RecipeVO.java

package com.sist.dao;
/*
 *  NO     NOT NULL NUMBER         
	TITLE  NOT NULL VARCHAR2(1000) 
	POSTER NOT NULL VARCHAR2(200)  
	CHEF   NOT NULL VARCHAR2(100)  
	LINK   NOT NULL VARCHAR2(200) 
 */
public class RecipeVO {
    private int no;
    private String title;
    private String poster;
    private String chef;
    private String link;
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getPoster() {
		return poster;
	}
	public void setPoster(String poster) {
		this.poster = poster;
	}
	public String getChef() {
		return chef;
	}
	public void setChef(String chef) {
		this.chef = chef;
	}
	public String getLink() {
		return link;
	}
	public void setLink(String link) {
		this.link = link;
	}
   
}

 

RecipeDAO.java

package com.sist.dao;
import java.io.*;
import java.util.*;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class RecipeDAO {
	// XML을 파싱
	private static SqlSessionFactory ssf;
	static {
		try {
			// XML을 읽기 시작
			Reader reader=Resources.getResourceAsReader("Config.xml");
			ssf=new SqlSessionFactoryBuilder().build(reader);
		}catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	// 기능 처리 ==> jstl + el => 망고플레이트 => 지도
	// 1. 레시피 목록
	//<select id="recipeListData" resultType="RecipeVO" parameterType="hashmap">
	public static List<RecipeVO> recipeListData(Map map){
		List<RecipeVO> list=new ArrayList<RecipeVO>();
		SqlSession session=null;
		try {
			// 연결
			session=ssf.openSession();
			// 데이터 처리
			list=session.selectList("recipeListData",map);
		}catch(Exception ex) {
			ex.printStackTrace();
		}finally {
			if(session!=null)
				session.close();
		}
		return list;
	}
	// 총페이지 구하기
	// <select id="recipeTotalPage" resultType="int">
	public static int recipeTotalPage() {
		int total=0;
		SqlSession session=null;
		try {
			session=ssf.openSession();
			total=session.selectOne("recipeTotalPage");
		}catch(Exception ex) {
			ex.printStackTrace();
		}finally{
			if(session!=null)
				   session.close();
		   }
		   return total;
	   }
	   // 2. chef 목록
	//<select id="chefListData" resultType="ChefVO" parameterType="hashmap">
	   public static List<ChefVO> chefListData(Map map){
		   List<ChefVO> list=new ArrayList<ChefVO>();
		   SqlSession session=null;
		   try{
			   // 연결
			   session=ssf.openSession();
			   // 데이터 처리
			   list=session.selectList("chefListData",map);
		   }catch(Exception ex){
			   ex.printStackTrace();
		   }
		   finally{
			   if(session!=null)
				   session.close();
		   }
		   return list;
	   }
	   // 총페이지 구하기 
	   //<select id="chefTotalPage" resultType="int">
	   public static int chefTotalPage(){
		   int total=0;
		   SqlSession session=null;
		   try{
			   // 연결
			   session=ssf.openSession();
			   total=session.selectOne("chefTotalPage");
		   }catch(Exception ex){
			   ex.printStackTrace();
		   }
		   finally{
			   if(session!=null)
				   session.close();
		   }
		   return total;
	   }
	// 3. chef => 레시피
	   //<select id="chefRecipeData" resultType="RecipeVO" parameterType="string">
	   public static List<RecipeVO> chefRecipeData(String chef){
			List<RecipeVO> list=new ArrayList<RecipeVO>();
			SqlSession session=null;
			try {
				// 연결
				session=ssf.openSession();
				// 데이터 처리
				list=session.selectList("chefRecipeData",chef);
			}catch(Exception ex) {
				ex.printStackTrace();
			}finally {
				if(session!=null)
					session.close();
			}
			return list;
		}
	// <select id="chefRecipeCount" resultType="ChefVO">
	   public static List<ChefVO> chefRecipeCount(){
		   List<ChefVO> list=new ArrayList<ChefVO>();
		   SqlSession session=null;
		   try{
			   // 연결
			   session=ssf.openSession();
			   // 데이터 처리
			   list=session.selectList("chefRecipeCount");
			   for(ChefVO vo:list) {
				   String s=vo.getMem_cont1().replace(",", "");
				   vo.setRecipeCount(Integer.parseInt(s));
			   }
		   }catch(Exception ex){
			   ex.printStackTrace();
		   }
		   finally{
			   if(session!=null)
				   session.close();
		   }
		   return list;
	   }
	// 4. 검색
}

 

recipe-mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sist.dao.recipe-mapper">
  <!-- 레시피 페이지를 나눠서 처리 : 인라인뷰 -->
  <select id="recipeListData" resultType="RecipeVO" parameterType="hashmap">
    SELECT no,title,chef,poster,num
    FROM (SELECT no,title,chef,poster,rownum as num 
    FROM (SELECT no,title,chef,poster 
    FROM recipe ORDER BY no ASC))
    WHERE num BETWEEN #{start} AND #{end}
  </select>
  <select id="recipeTotalPage" resultType="int">
    SELECT CEIL(COUNT(*)/20.0) FROM recipe
  </select>
  <!-- 검색 -->
  <!-- chef목록 출력 -->
  <select id="chefListData" resultType="ChefVO" parameterType="hashmap">
    SELECT chef,poster,mem_cont1,mem_cont2,mem_cont3,mem_cont7,num
    FROM (SELECT chef,poster,mem_cont1,mem_cont2,mem_cont3,mem_cont7,rownum as num 
    FROM (SELECT chef,poster,mem_cont1,mem_cont2,mem_cont3,mem_cont7 
    FROM chef))
    WHERE num BETWEEN #{start} AND #{end}
  </select>
  <!-- chef 총페이지 -->
  <select id="chefTotalPage" resultType="int">
   SELECT CEIL(COUNT(*)/50.0) FROM chef
  </select>
  
  <!-- chef => 레시피찾기 -->
  <select id="chefRecipeData" resultType="RecipeVO" parameterType="string">
  	SELECT no,title,poster,chef,rownum 
  	FROM recipe 
  	WHERE chef=#{chef} AND rownum&lt;=32
  </select>
  
  <select id="chefRecipeCount" resultType="ChefVO">
  	SELECT chef,mem_cont1,rownum 
  	FROM chef 
  	WHERE rownum&lt;=10
  </select>
</mapper>

 

Java Resources/src/com.sist.model

RecipeModel.java

package com.sist.model;
import com.sist.dao.*;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
public class RecipeModel {
	public void recipeListData(HttpServletRequest request) {
		// request => 사용자의 요청 정보, 필요한 데이터를 첨부해서 사용 (setAttribute())
		                                                  // ==> JSP로 전송
		// 사용자가 요청한 페이지를 받는다
		String page=request.getParameter("page");
		if(page==null)
			page="1";
		// 데이터 읽기
		int curpage=Integer.parseInt(page); // 현재 보고 있는 페이지
		Map map=new HashMap();
		int rowSize=20;
		int start=(rowSize*curpage)-(rowSize-1);
		int end=rowSize*curpage;
		
		// map에 묶어서 전송 ==> myBatis가 읽어서 처리
		map.put("start",start);
		map.put("end",end);
		List<RecipeVO> list=RecipeDAO.recipeListData(map);
		for(RecipeVO vo:list) {
			String str=vo.getTitle();
			if(str.length()>20) {
				str=str.substring(0,20);
				str+="...";
			}
			vo.setTitle(str);
		}
		// 총페이지
		int totalpage=RecipeDAO.recipeTotalPage();
		
		// JSP로 받은 결과값을 전송
		request.setAttribute("list", list);
		request.setAttribute("curpage", curpage);
		request.setAttribute("totalpage", totalpage);
	}
	public void chefListData(HttpServletRequest request) {
		// 사용자 요청정보 받기 => page
		String page=request.getParameter("page");
		if(page==null)
			page="1";
		// 현재 페이지
		int curpage=Integer.parseInt(page);
		// 현재 페이지 출력할 데이터 읽기
		Map map = new HashMap();
		int rowSize=50;
		int start=(rowSize*curpage)-(rowSize-1);
		int end=rowSize*curpage;
		
		map.put("start", start);
		map.put("end", end);
		List<ChefVO> list=RecipeDAO.chefListData(map); // 시작위치, 마지막위치
		// 총페이지
		
		int totalpage=RecipeDAO.chefTotalPage();
		// curpage, totalpage, lisxwt => JSP
		
		request.setAttribute("list", list);
		request.setAttribute("curpage", curpage); //현재 페이지
		request.setAttribute("totalpage", totalpage); //총페이지
		
		List<ChefVO> cList=RecipeDAO.chefRecipeCount();
		request.setAttribute("cList", cList);
	}
	// chef => 레시피 목록 출력
	public void chefRecipeData(HttpServletRequest request) {
		// 사용자 요청한 => chef명을 읽어 온다
		String chef_name = request.getParameter("chef_name");
		List<RecipeVO> list=RecipeDAO.chefRecipeData(chef_name);
		// JSP로 전송 => list에 있는 내용만 출력
		request.setAttribute("list", list);
	}
}

 

WebContent/recipe/

recipe.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.sist.model.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- RecipeModel을 메모리 할당 --%>
<jsp:useBean id="model" class="com.sist.model.RecipeModel"/>
<%
	model.recipeListData(request); // 처리후에 결과값을 넘겨 받는다
	/*
		${} ==> request.getAttribute(), session.getAttribute()
	     === 일반 변수는 들어갈 수 없고 request, session만 가능하다.
	*/
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
.row {
   margin: 0px auto; /*가운데 정렬*/
   /*width:1024px;*/
}
h1 {
     text-align: center;
}
</style>
</head>
<body>
<div class="container-fluid">
 <div class="row">
  <h1>10000개의 레시피</h1>
   <c:forEach var="vo" items="${list }">
    <div class="col-md-3">
     <div class="thumbnail">
        <img src="${vo.poster }" alt="Lights" style="width:100%">
        <div class="caption">
          <p>${vo.title }</p>
          <p>${vo.chef }</p>
        </div>
    </div>
  </div>
  </c:forEach>
 </div>
 <div class="row">
  <div class="text-right">
   <a href="recipe.jsp?page=${curpage>1?curpage-1:curpage }" class="btn btn-sm btn-info">이전</a>
   	${curpage } page / ${totalpage } pages
   <a href="recipe.jsp?page=${curpage<totalpage?curpage+1:curpage }" class="btn btn-sm btn-success">다음</a>
  </div>
 </div>
</div>
</body>
</html>

 

chef.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.sist.model.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<jsp:useBean id="model" class="com.sist.model.RecipeModel"/>
<%
    model.chefListData(request);
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
.row {
   margin: 0px auto; /*가운데 정렬*/
   width:900px;
}
h1 {
     text-align: center;
}
</style>
	<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load("current", {packages:["corechart"]});
      google.charts.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['쉐프명', '레시피'],
          <c:forEach var="vo" items="${cList}">
          ['<c:out value="${vo.chef}"/>',     <c:out value="${vo.recipeCount}"/>],
          </c:forEach>
        ]);

        var options = {
          title: '셰프 순위',
          is3D: true,
        };

        var chart = new google.visualization.PieChart(document.getElementById('piechart_3d'));
        chart.draw(data, options);
      }
    </script>
</head>
<body>
	<div class="container">
	 <div class="row">
	  <div id="piechart_3d" style="width: 900px; height: 500px;"></div>
	 </div>
		<div class="row">
			<h1>Chef 목록</h1>
			<%-- 목록 출력 --%>
			<table class="table">
			 <tr>
			  <td>
			   <c:forEach var="vo" items="${list }">
			    <table class="table table-striped">
			     <tr>
			      <td width=35% rowspan="2" class="text-center">
			      	<img src="${vo.poster }" class="img-circle" width=60 height=60>
			      </td>
			      <td colspan="4" style="font-size:13pt; color:#FC6"><b> 
			     	<a href="chef_detail.jsp?chef_name=${vo.chef }">${vo.chef }</a>
			     	</b></td>
			     </tr>
			     <tr>
			      <td class="text-center">${vo.mem_cont1 }</td>
			      <td class="text-center">${vo.mem_cont3 }</td>
			      <td class="text-center">${vo.mem_cont7 }</td>
			      <td class="text-center">${vo.mem_cont2 }</td>
			     </tr>
			    </table>
			  </td>
			 </tr>
			</table>
			</c:forEach>
		</div>
		<div class="row">
		 <div class="text-center">
		  <a href="chef.jsp?page=${curpage>1?curpage-1:curpage }" class="btn btn-sm btn-primary">이전</a>
		  	${curpage } page / ${totalpage } pages
		  <a href="chef.jsp?page=${curpage<totalpage?curpage+1:curpage }" class="btn btn-sm btn-danger">다음</a>
		 </div>
		</div>
	</div>
</body>
</html>

 

chef_detail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.sist.model.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<jsp:useBean id="model" class="com.sist.model.RecipeModel"/>
<%
	model.chefRecipeData(request);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
.row {
   margin: 0px auto; /*가운데 정렬*/
}
h1 {
     text-align: center;
}
</style>
</head>
</head>
<body>
	<div class="container-fluid">
		<div class="row">
			<h1>${param.chef_name }님의 레시피 목록</h1>
			<c:forEach var="vo" items="${list }">
			    <div class="col-md-3">
			     <div class="thumbnail">
			        <img src="${vo.poster }" alt="Lights" style="width:100%">
			        <div class="caption">
			          <p>${fn:length(vo.title)>20?fn:substring(vo.title,0,20)+="...":vo.title }</p>
			          <p>${vo.chef }</p>
			           <%--
		               ${fn:메소드() fn:메소드}
		           		--%>
			        </div>
			    </div>
			  </div>
			</c:forEach>
		</div>
	</div>
</body>
</html>
반응형
Comments