이전글 (관리자 기능)
https://amongthestar.tistory.com/149
이번에 포스팅할 내용은 회원 비회원 상관없이 볼 수 있는 소개화면과 강의목록화면, 관련 기능구현이다.
시작페이지에서 두번째 탭은 "와이저"라 명명했다. 이 사이트에 대해 간략하게 소개하는 페이지이다.
about.jsp
(소개 페이지. 내용은 캠블리에서 복사 붙여넣기 했다.)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="/include/header.jsp" %>
<style>
h2{
color:#484848;
font-size: 1.4em;
}
</style>
<!-- Image Showcases -->
<section class="showcase">
<div class="container-fluid p-0">
<div class="row no-gutters">
<div class="col-lg-6 order-lg-2 text-white showcase-img" style="background-image: url('/Tutoring/img/about1.jpg'); background-position: center center"></div>
<div class="col-lg-6 order-lg-1 my-auto showcase-text">
<h2>복습으로 학습 효과 2배!</h2>
<p class="lead mb-0"><b>수업 동영상</b> 모든 수업은 영상파일로 저장 되며, 튜터 피드백과 함께 효과적으로 복습할 수 있습니다.</p>
</div>
</div>
<div class="row no-gutters">
<div class="col-lg-6 text-white showcase-img" style="background-image: url('/Tutoring/img/about2.jpg');"></div>
<div class="col-lg-6 my-auto showcase-text">
<h2>영어회화 두려움 떨쳐내기</h2>
<p class="lead mb-0"><b>번역기</b> 영어로 생각나지 않을 땐 채팅창에 한국어로! 자동 번역 기능이 있어 걱정 없어요</p>
</div>
</div>
<div class="row no-gutters">
<div class="col-lg-6 order-lg-2 text-white showcase-img" style="background-image: url('/Tutoring/img/about3.jpg'); background-position: center center""></div>
<div class="col-lg-6 order-lg-1 my-auto showcase-text">
<h2>내 일정에 딱 맞는 수업</h2>
<p class="lead mb-0"><b>예약</b> 마음에 드는 튜터와 내가 원하는 시간에 미리 예약해 만들어 나가는 유연한 학습 스케쥴</p>
</div>
</div>
</div>
</section>
<%@ include file="/include/footer.jsp" %>
특별하게 서블릿으로 이동하여 구현해야할 기능은 없다.
시작페이지에서 세번째 탭에 해당하는 "과정"이다. 강의목록을 카드형식으로 볼 수 있다.
jsp가 먼저 실행되는 것이 아니라 링크를 통해 서블릿으로 이동하면 다시 카드형식의 jsp로 내보낸다.
WClassCourseList.java
(강의목록을 보여주는 서블릿으로 DB에 있는 강의를 ArrayList에 담아 courseList.jsp로 이동하여 뿌린다. 서블릿의 경로는 "/Tutoring/class/courseList"이다. )
package com.wclass.action;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wmember.model.WClassDAO;
import com.wmember.model.WClassDTO;
/**
* Servlet implementation class WClassCourseAction
*/
@WebServlet("/class/courseList")
public class WClassCourseList extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public WClassCourseList() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
WClassDAO dao=WClassDAO.getInstance();
ArrayList<WClassDTO> arr= dao.classList();
request.setAttribute("dto", arr);
RequestDispatcher rd=request.getRequestDispatcher("courseList.jsp");
rd.forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- WClassDAO.java의 classList메소드를 수행하는데, 앞선 관리자의 강의목록 페이지와 다르게 인자값이 없다.
- 이용자가 강의 목록을 검색을 하여 뽑거나 강의를 수정하지 않고 현재 존재하는 강의만 보기 때문이다. 다만 테이블 형식으로 출력할 것인지, 카드 형식으로 출력할 것인지 jsp의 양식에 따라 다르다.
- 강의목록을 들고 courseList.jsp로 다시 이동한다.
<WClassDAO.java의 classList메소드>
//과정 메뉴 클릭시 전체보기
public ArrayList<WClassDTO> classList() {
Connection con=null;
Statement st=null;
ResultSet rs=null;
ArrayList<WClassDTO>arr=new ArrayList<WClassDTO>();
try {
con=getConnection();
String sql="select * from wclass";
st=con.createStatement();
rs=st.executeQuery(sql);
while(rs.next()) {
WClassDTO dto=new WClassDTO();
dto.setClassnum(rs.getInt("classnum"));
dto.setClassname(rs.getString("classname"));
dto.setStu_num(rs.getInt("stu_num"));
dto.setStu_regdate(rs.getString("stu_regdate"));
dto.setTopic(rs.getString("topic"));
dto.setContent(rs.getString("content"));
dto.setClevel(rs.getString("clevel"));
dto.setUploadFile((rs.getString("uploadfile")));
arr.add(dto);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnection(con, st, rs);
}
return arr;
}
courseList.jsp
(WClassCourseList.java에서 넘어온 값들을 카드형식으로 뿌린다.)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="/include/header.jsp" %>
<style>
html, body, div, span, applet, object, iframes,
p, blockquote, pre, abbr, acronym, address, big, quotes, code, del,
dfn, em, img, ins, kbd, q, s, samp, small, strike, sub, sup, tt, var, u,
i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table,
caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas,
details, embed, figure, figcaption, footer, header, hgroup, menu, nav,
output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
do: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure, footer, header, hgroup,
menu, nav, section {
display: block;
}
blockquote, q {
quotes: none;
}
blockquote : before, blockquote : after, q : before, q : after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
a{
text-decoration: none;
color: black;
}
a:hover{
text-decoration: none;
color: black;
}
.card:hover{
background-color: #eee;
}
.card {
height: 400px;
width: 350px;
border-radius: 15px;
display: inline-block;
margin-top: 30px;
margin-bottom: 30px;
position: relative;
box-shadow: 0 6px 0px 0 rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.card-header {
-webkit-transition: 0.5s; /*사파리 & 크롬*/
-moz-transition: 0.5s; /*파이어폭스*/
-ms-transition: 0.5s; /*인터넷 익스플로러*/
-o-transition: 0.5s; /*오페라*/
transition: 0.5s;
width: 100%;
height: 230px;
border-radius: 15px 15px 0 0;
background-color: gray;
background-size: 100% 230px;
background-repeat: no-repeat;
}
.card-header-is_closed{
background-color: #EF5A31 ;
color: #FFF ;
font-weight: bold ;
text-align: center ;
float: right;
margin: 15px 15px 0 0;
border-radius: 50%;
font-weight: bold;
padding: 10px 10px;
line-height: 20px;
}
.card-body-header{
line-height: 25px;
margin: 10px 20px 0px 20px;
}
.card:hover .card-body-description {
opacity: 1;
-webkit-transition: .5s ease-in-out;
-moz-transition: .5s ease-in-out;
-ms-transition: .5s ease-in-out;
-o-transition: .5s ease-in-out;
transition : .5s ease-in-out;
overflow: scroll;
text-decoration: none;
}
.card-columns{
overflow: auto;
flex-wrap: nowrap;
}
</style>
<body>
<br/>
<div class="container">
<h3>과정 둘러보기</h3>
<hr>
<p style="font-size:1.25em;">유창한 영어의 기본 요소</p>
<p style="font-size:0.9em;">유창한 영어로 대화하며 자신감을 키워보세요. 간단한 대화부터 복잡한 시사 문제에 대해 논리정연한 의견을 표현하는 것까지, 다양한 레벨의 과정을 통해 모두가 무언가를 배울 수 있습니다.</p>
<div class="card-columns" style="column-count:4;">
<c:forEach items="${dto}" var="dto">
<c:if test="${dto.clevel eq 'basic'}">
<a href="CourseDetail?num=${dto.classnum}">
<div class="card">
<div class="card-header" style="background-image: url('/Tutoring/upload/${dto.uploadFile}');">
</div>
<div class="card-body">
<div class="card-body-header" >
<h5>${dto.classname}</h5>
<p class = "card-body-nickname" style="font-size:0.9em;">${dto.topic}</p>
</div>
</div>
</div>
</a>
</c:if>
</c:forEach>
</div>
<br/><br/>
<p style="font-size:1.25em;">경력 개발</p>
<p style="font-size:0.9em;">해외 환경에서 비즈니스 관련 대화를 하려면 유창한 영어 실력만으로는 부족합니다. 언어와 비언어로 이루어진 다문화 커뮤니케이션은 경력 개발의 강력한 도구입니다.</p>
<div class="card-columns" style="column-count:4;">
<c:forEach items="${dto}" var="dto">
<c:if test="${dto.clevel eq 'career'}">
<a href="CourseDetail?num=${dto.classnum}">
<div class="card">
<div class="card-header" style="background-image: url('/Tutoring/upload/${dto.uploadFile}');">
</div>
<div class="card-body">
<div class="card-body-header" >
<h5>${dto.classname}</h5>
<p class = "card-body-nickname" style="font-size:0.9em;">${dto.topic}</p>
</div>
</div>
</div>
</a>
</c:if>
</c:forEach>
</div>
<br/><br/>
<p style="font-size:1.25em;">자신을 표현해보세요</p>
<p style="font-size:0.9em;">영어를 배우면 전 세계 사람들과 더 쉽게 교류할 수 있습니다. 요즘 화두가 되는 다양한 주제를 탐색하면서 특정 분야 어휘를 확장하고, 다른 문화와 관점에 대해 배워보세요!</p>
<div class="card-columns" style="column-count:4;">
<c:forEach items="${dto}" var="dto">
<c:if test="${dto.clevel eq 'expression'}">
<a href="CourseDetail?num=${dto.classnum}">
<div class="card">
<div class="card-header" style="background-image: url('/Tutoring/upload/${dto.uploadFile}');">
</div>
<div class="card-body">
<div class="card-body-header" >
<h5>${dto.classname}</h5>
<p class = "card-body-nickname" style="font-size:0.9em;">${dto.topic}</p>
</div>
</div>
</div>
</a>
</c:if>
</c:forEach>
</div>
<br/><br/>
<p style="font-size:1.25em;">시험 준비</p>
<p style="font-size:0.9em;">최신 시험 기출 문제를 연습해 다가오는 영어 말하기 시험에 대비하세요.</p>
<div class="card-columns" style="column-count:4;">
<c:forEach items="${dto}" var="dto">
<c:if test="${dto.clevel eq 'test'}">
<a href="CourseDetail?num=${dto.classnum}">
<div class="card">
<div class="card-header" style="background-image: url('/Tutoring/upload/${dto.uploadFile}');">
</div>
<div class="card-body">
<div class="card-body-header" >
<h5>${dto.classname}</h5>
<p class = "card-body-nickname" style="font-size:0.9em;">${dto.topic}</p>
</div>
</div>
</div>
</a>
</c:if>
</c:forEach>
</div>
<br/><br/>
</div>
</body>
</html>
<%@ include file="/include/footer.jsp" %>
강의분류에 따라 카드를 정렬시키기 위해 c:if 문에 조건을 써주었다.
강의 이미지들은 freepik.com에서 받았다. 카드를 클릭하면 강의 상세페이지로 이동한다.
WClassCourseDetail.java
(courseList.jsp에서 courseDetail로 강의번호를 달고 넘어간 서블릿. 경로는 "/Tutoring/class/CourseDetail"이다.)
package com.wclass.action;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.wmember.model.WClassDAO;
import com.wmember.model.WClassDTO;
/**
* Servlet implementation class WClassCourseDetail
*/
@WebServlet("/class/CourseDetail")
public class WClassCourseDetail extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public WClassCourseDetail() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
WClassDAO dao=WClassDAO.getInstance();
int num=Integer.parseInt(request.getParameter("num"));
WClassDTO dto=dao.classView(num);
request.setAttribute("dto", dto);
RequestDispatcher rd=request.getRequestDispatcher("courseDetail.jsp");
rd.forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- a링크로 넘어갔기 때문에 doGet 내에서 처리된다.
- 파라미터 값으로 받아온 num을 들고 WClassDAO의 classView메소드를 수행한다.
- 그리고 courseDetail.jsp로 이동한다.
<WClassDAO의 classView메소드>
관리자 페이지에서 강의목록을 누르고, 제목을 누르면 떴던 classView 메소드와 동일하다. (다만 값을 뿌려줄때의 양식이 다르기에 jsp가 다른것이고, jsp로 넘어가는 서블릿도 분리한 것이다. 전자는 ClassDetail.jsp와 WClassDetailAction.java이고 지금은 courseDetail.jap와 WClassCourseDetail.java이다.)
//강의 상세보기
public WClassDTO classView (int classnum) {
Connection con=null;
Statement st=null;
ResultSet rs=null;
WClassDTO dto=null;
try {
con=getConnection();
st=con.createStatement();
String sql="select * from wclass where classnum="+classnum;
rs=st.executeQuery(sql);
if(rs.next()) {
dto=new WClassDTO();
dto.setClassnum(rs.getInt("classnum"));
dto.setClassname(rs.getString("classname"));
dto.setClevel(rs.getString("clevel"));
dto.setContent(rs.getString("content"));
dto.setStu_num(rs.getInt("stu_num"));
dto.setStu_regdate(rs.getString("stu_regdate"));
dto.setTopic(rs.getString("topic"));
dto.setUploadFile((rs.getString("uploadfile")));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnection(con, st, rs);
}
return dto;
}
courseDetail.jsp
강의소개영역, 강의별 수강후기 게시판 영역, 게시글 검색 영역, 글쓰기폼 영역으로 이루어져있다.
수강후기와 관련된 기능들은 다음 포스팅에서 소개하고, 지금은 강의소개 영역만 보겠다.
WClassCourseDetail.java에서 dto이름으로 저장한 dto객체를 뿌린다.
<!-- 강의 소개 -->
<div><a href="/Tutoring/class/courseList"><b>〈</b> 모든 과정</a></div>
<div class="card">
<form action="/Tutoring/class/cartInsert" method="post" id="frm">
<!-- 등록하고자 하는 강의 번호 -->
<input type="hidden" id="classnum" name="classnum" value="${dto.classnum}">
<input type="hidden" id="classname" name="classname" value="${dto.classname}">
<input type="hidden" id="userid" name="userid" value="${sessionScope.userid}">
<!-- 카드 영역 -->
<div class="card-header" style="background-image: url('/Tutoring/upload/${dto.uploadFile}');">
</div>
<div class="card-body">
<div class="card-body-header" >
<h5>${dto.classname}</h5>
<p class = "card-body-nickname" style="font-size:0.9em;">${dto.topic}</p>
</div>
<div class="button">
<input type="button" class="btn btn-info" value="등록하기" id="subscribe" style="width: 100%;">
</div>
</div>
<!-- 카드 영역 끝 -->
<br/>
</form>
</div>
<br/>
<div class="content">
<p style="font-size: 1.25em;">개요</p><br/>
<p>왜 이런 과정을 수강해야 하나요?</p>
<br/>
<span style="color: gray;">${dto.content}</span>
</div>
<!-- 강의 소개 끝 -->
https://github.com/kkj0712/JspProject_Tutoring
'Learning > JSP' 카테고리의 다른 글
JSP 개인프로젝트-영어 학습 사이트 만들기 (수강후기 상세보기 및 수정 삭제, 댓글 입력 및 삭제) (0) | 2020.08.18 |
---|---|
JSP 개인프로젝트-영어 학습 사이트 만들기 (수강후기 게시판 전체보기, 게시글 입력) (0) | 2020.08.18 |
JSP 개인프로젝트-영어 학습 사이트 만들기 (관리자 기능) (0) | 2020.08.18 |
JSP 개인프로젝트-영어 학습 사이트 만들기 (로그인, 회원가입) (0) | 2020.08.18 |
파일 전송 (0) | 2020.08.06 |