식별자 규칙

 

대소문자 구분

문자 또는 언더바로 시작

맨 처음을 제외하고 숫자 포함 가능

특수문자 사용불가

한글을 변수명으로 사용 가능

띄어쓰기 불가

숫자만 사용 불가

파이썬 명령어를 변수명으로 사용 불가

 

 


 

변수

#변수

iq=190 #메모리에 숫자 190은 바이너리(2진수)로 저장됨

print(iq)



#여러개의 변수를 초기화

a,b,c=1,2,3

print(a)

print(b)

print(c)

print("-------")



#예제1

놀이기구="자이로드롭"

print(놀이기구)

나이21살=1,2,3,4

print(나이21살)

이름="박써니"

print(이름)

_myName="홍길동"

print(_myName)

print("-------")



#예제2

x=10

print(x)

print("-------")



#예제3

x,y,z=1,2,3

print(x)

print(y)

print(z)

print("-------")



#예제4

x,y,z=1,1.1,"str"

print(type(x))

print(type(y))

print(type(z))

print("-------")



 


 

 

문자형 데이터 str

#문자형 데이터 str
#쌍따옴표, 한따옴표
print(type('문자열'))
var1='한따옴표'
var2="쌍따옴표"
print("문자열은 "+var1+var2)
print("문자열은 ",var1,var2)

 


 

따옴표 3개

#따옴표 3개씩 쓸때 ''' """
var3='''
따옴표 3개는
문장 모두를
처리하는 문자열
-----
'''
print(var3)

 

 


 

문자열 (+)연산

#문자열 (+)연산
성='홍'
이름="길동"
Name=성+' '+이름
print(Name)

 

 


 

타입 변환 str(), int(), float()

#타입 변환 str(), int(), float()
num=input("숫자하나 입력: ")
print(num+10) #입력받을때 문자로 인식

 

 

 

#타입 변환 str(), int(), float()
num=input("숫자하나 입력: ")
print(int(num)+10)

 

 

 


 

이스케이프 시퀀스

#이스케이프 시퀀스
날씨 = "It\'s \"kind of\" sunny"
print(날씨)

 

 

 


#예제
날씨2="\tIt's \"kind of\" sunny \n Have a nice Day!"
print(날씨2)


#예제2
string1='''
다스베이더가 말했다.
"내가 니 애비다!"
그 말을 들은 루크는 \'깜짝\' 놀랐다.
'''
print(string1)

'Learning > Python' 카테고리의 다른 글

for 반복문  (0) 2020.08.25
if문과 while 반복문  (0) 2020.08.24
bool, 논리연산자  (0) 2020.08.24
문자열 f-string 포맷, 인덱스, 슬라이싱  (0) 2020.08.24
파이썬 실행, 데이터 타입, 숫자 연산자  (0) 2020.08.24

https://www.python.org/

 

Welcome to Python.org

The official home of the Python Programming Language

www.python.org

 

파이썬 설치 후 터미널, 코드 에디터 (비주얼 스튜디오 코드, 서브라임), IDE 통합개발환경(파이참, 스파이더), 쥬피터 노트북(데이터 분석용)를 이용하여 사용

 

+

온라인에서 프로그램 설치없이 어디서든지 작업할 수 있는 클라우드 개발환경을 사용해본다.

https://repl.it/

 

The collaborative browser based IDE

Repl.it is a simple yet powerful online IDE, Editor, Compiler, Interpreter, and REPL. Code, compile, run, and host in 50+ programming languages: Clojure, Haskell, Kotlin, QBasic, Forth, LOLCODE, BrainF, Emoticon, Bloop, Unlambda, JavaScript, CoffeeScript,

repl.it

 

 

 

 

출력

print('헬로우 월드!')

 

입력

input ("이름 입력:")

 

(자바스크립트 처럼 변수 앞에 var 안써도 됨)

 

 

예제) 이름을 입력받아 출력하기

name=input("당신의 이름은?:")

print("안녕하세요 "+name+"님")

 


 

 


파이썬 표준 라이브러리 참고

https://docs.python.org/ko/3/library/index.html

 

파이썬 표준 라이브러리 — Python 3.8.5 문서

파이썬 표준 라이브러리 파이썬 언어 레퍼런스 는 파이썬 언어의 정확한 문법과 의미를 설명하고 있지만, 이 라이브러리 레퍼런스 설명서는 파이썬과 함께 배포되는 표준 라이브러리를 설명합�

docs.python.org

 

 

repl.it 의 단축키

한줄 복사 붙여넣기: Ctrl+c, Ctrl+v 또는 Shift+Alt+화살표 위아래 단축키

한줄 삭제: Shift+Del

여러줄 한꺼번에 편집: Ctrl+Alt+화살표 단축키

실행: Ctrl+Enter

코드한줄 이동: Alt+화살표 위아래 단축키

 

 

기본 데이터 타입

#기본 데이터 타입

int #정수

float #실수

bool #불린(참,거짓)

str #문자

list #

tuple #

set #

dict #



#none: null과 비슷

None



#숫자(int float): 정수, 실수

#type(): 자료형 리턴

print(type(2+4))

print(type(2-4))

print(type(2*4))

print(type(2/4)) #int->float로 자동 형변환

print("------")



print(2+4)

print(2-4)

print(2*4)

print(2/4)

print("------")



print(type(0.000001))

print(type(5.000001))

print(type(0))

print(type(0.0))

print("------")



print(type(9.9+1.1)) #float->int로는 자동 형변환이 안됨

 


 

제곱과 나누기

#제곱과 나누기

#거듭제곱 **

print(2**2)

print(2**3)

print(2**4)

print("------")



#나누기 몫 //

print(10/4)

print(10//4)

print("------")



#나누기 나머지 %

print(10%3)



#Math 수학 함수

#반올림

print(round(3.123456))

#절대값 abs

print(abs(-2))

 


숫자 계산식 우선순위

# 숫자 계산식 우선순위

print((3-2)*2**3/4) #1*8/4=2

print((20-3)+2**2) #17+4



#()

#**

#*/

#+-

 

이진수 변환 bin()

#이진수 변환 bin()

print(bin(5))

print(int('0b101',2))


 

'Learning > Python' 카테고리의 다른 글

for 반복문  (0) 2020.08.25
if문과 while 반복문  (0) 2020.08.24
bool, 논리연산자  (0) 2020.08.24
문자열 f-string 포맷, 인덱스, 슬라이싱  (0) 2020.08.24
변수, 문자열str, 이스케이프 시퀀스  (0) 2020.08.24

New Dynamic Web Project로 Jsoup_test 생성

com.jsoup.test 패키지에 Test01.java 클래스 생성

 

 

https://mvnrepository.com/artifact/org.jsoup/jsoup/1.11.3

 

Maven Repository: org.jsoup » jsoup » 1.11.3

jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods. jsoup implements the WHATWG HTML5 specification, and parses HTML to the s

mvnrepository.com

에서 jsoup-1.11.3.jar 다운받아서 WEB-INF 내 lib 폴더에 붙여넣기

 

다음 사이트에서 영화 검색, 검색창 주소 복사해서 Jsou.connnet 함수 인자로 넣기


 

Test01.java

package com.jsoup.test;

import java.io.IOException;

import java.util.ArrayList;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.select.Elements;

public class Test01 {

    public static void main(String[] args) {

        try {

            Document doc=Jsoup.connect("https://search.daum.net/search?w=tot&DA=YZR&t__nil_searchbox=btn&sug=&sugo=&sq=&o=&q=%EC%98%81%ED%99%94").get();

//          System.out.println(doc);

            

            Elements movie_list=doc.select("ol.movie_list li");

//          System.out.println(movie_list);

            System.out.println("====제목====");

            Elements titleContainer=movie_list.select("div.info_tit a");

//          System.out.println(titleContainer);

//          for(int i=0;i<titleContainer.size();i++) {

//              System.out.println(titleContainer.get(i).text());

//          }

//          

//          System.out.println("====평점====");

            Elements scoreContainer=movie_list.select("em.rate");

//          for(int i=0;i<scoreContainer.size();i++) {

//              System.out.println(scoreContainer.get(i).text());

//          }

            

            ArrayList<Movie> arr=new ArrayList<Movie>();

            for(int i=0;i<scoreContainer.size();i++) {

                Movie movie=new Movie();

                String title=titleContainer.get(i).text();

                String rate=scoreContainer.get(i).text();

                movie.setTitle(title);

                movie.setRate(rate);

                arr.add(movie);

            }

            for(Movie movie:arr) {

                System.out.println("제목:"+movie.getTitle());

                System.out.println("평점: "+movie.getRate());

                System.out.println();

            }

            

        } catch (IOException e) {

            e.printStackTrace();

        }

        

    }

}

Movie.java

 

package com.jsoup.test;

public class Movie {

    private String title;

    private String rate;

    

    public String getTitle() {

        return title == null ? "" : title.trim();

    }

    public void setTitle(String title) {

        this.title = title;

    }

    public String getRate() {

        return rate == null ? "" : rate.trim();

    }

    public void setRate(String rate) {

        this.rate = rate;

    }

}

 


손흥민의 프로필 출력하기

 

Son.java

 

package com.jsoup.test;

import java.io.IOException;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.select.Elements;

public class Son {

    public static void main(String[] args) {

        try {

            Document doc=Jsoup.connect("https://search.daum.net/search?w=tot&DA=YZR&t__nil_searchbox=btn&sug=&sugo=&sq=&o=&q=%EC%86%90%ED%9D%A5%EB%AF%BC").get();

            Elements container=doc.select("div.type_thumb_s160 dl");

            Elements title=doc.select("div.type_thumb_s160 dl dt");

            Elements data=doc.select("div.type_thumb_s160 dl dd");

            System.out.println("손흥민에 대한 정보");

            for(int i=0;i<container.size();i++) {

                String titleText=title.get(i).text();

                String dataText=data.get(i).text();

                System.out.println(titleText+":"+dataText);

            }

        

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

 

 


 

최근 로또 5회차의 당첨번호 출력하기

 

Lottery2.java

package com.jsoup.test;

import java.io.IOException;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.nodes.Element;

import org.jsoup.select.Elements;

public class Lottery2 {

    public static void main(String[] args) {

        Document doc;

        try {

            doc=Jsoup.connect("https://m.dhlottery.co.kr/common.do?method=main").get();

            Elements lottoNo=doc.select("#lottoDrwNo"); //회차

            Elements lottoDrwNo=doc.select("div.prizeresult"); //로또번호

        

            for(int i=0;i<lottoNo.size();i++) {

                System.out.println(lottoNo.get(i).text()+" 당첨번호"); //회차

                //회차에 해당하는 로또 번호

                System.out.println(lottoDrwNo.get(i).select("span").text());

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}



 

환율 출력하기

 

Exchage.java

 

package com.jsoup.test;

import java.io.IOException;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.nodes.Element;

import org.jsoup.select.Elements;

public class Exchage {

    public static void main(String[] args) {

        Document doc;

        try {

            doc=Jsoup.connect("https://search.naver.com/search.naver?sm=top_hty&fbm=1&ie=utf8&query=%ED%99%98%EC%9C%A8").get();

            Elements table=doc.select("table.rate_table_info");

            Elements tr=table.select("tbody tr");

            for(int i=0;i<tr.size();i++) {

                String country=tr.get(i).select("th a").text();

                String ratio=tr.get(i).select("td").first().text();

                System.out.println(country+"=>"+ratio);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}


 

<상세보기>

상세보기는 num이 파라미터 값이다. 그리고 돌아오는 값은 DTO이다.

따라서 ObjectMapper.xml 에서 parameterType, resultType 둘다 써줘야한다.

 

addrList.jsp에서 다음과 같이 제목을 클릭하면 상세보기로 넘어가도록 함

<td><a href="viewAction.amy?num=${arr.num}">${arr.name}</a></td>

 


ViewAction.java

 

package org.addrMy.action;

import java.io.IOException;

import java.util.List;

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 org.addrMy.config.MybatisManager;

import org.addrMy.model.AddressVO;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

/**

 * Servlet implementation class ViewAction

 */

@WebServlet("/address_my/viewAction.amy")

public class ViewAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public ViewAction() {

        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");

        int num=Integer.parseInt(request.getParameter("num"));

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

        AddressVO vo=sqlSession.selectOne("viewData",num);

        request.setAttribute("address", vo);

        RequestDispatcher rd=request.getRequestDispatcher("arrView.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);

    }

}


addrView.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<form action="updateAction.amy" method="post" name="frm">

<input type="hidden" name="num" value="${address.num}">

<table>

    <tr>

        <td colspan="2">주소록 수정하기</td>

    </tr>

    <tr>

        <td>이름</td>

        <td><input type="text" name="name" value="${address.name}"></td>

    </tr>

    <tr>

        <td>우편번호 </td>

        <td><input type="text" name="zipcode" size=10 value="${address.zipcode}">

        <input type="button" name="search" value="검색" onclick="zipfinder()"></td>

    <tr>

        <td>주소

        <td><input type="text" name="addr" size=30 value="${address.addr}"></td>

    </tr>

    <tr>

        <td>전화번호</td>

        <td><input type="text" name="tel" value="${address.tel}"></td>

    </tr>

    <tr>

        <td colspan="2">

        <input type="submit" value="수정" onclick="location.href='updateAction.amy?num=${address.num}'">

        <input type="button" value="삭제" onclick="location.href='deleteAction.amy?num=${address.num}'"> <!-- del()이라는 함수를 부른다. -->

        <input type="reset" value="취소">

        </td>

    </tr>

</table>

</form>

</body>

</html>

 


 

<수정하기>

상세보기 후 수정 버튼을 눌러서 수정되도록.

받아오는 값들을 다 써주고 Address vo 객체에 담는다. vo 객체를 들고 업데이트를 시켜야한다. 그 후 전체보기로 넘어간다.

 

UpdateAction.java

 

package org.addrMy.action;

import java.io.IOException;

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 org.addrMy.config.MybatisManager;

import org.addrMy.model.AddressVO;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

/**

 * Servlet implementation class UpdateAction

 */

@WebServlet("/address_my/updateAction.amy")

public class UpdateAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public UpdateAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        

        

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        AddressVO vo=new AddressVO();

        vo.setAddr(request.getParameter("addr"));

        vo.setName(request.getParameter("name"));

        vo.setNum(Integer.parseInt(request.getParameter("num")));

        vo.setTel(request.getParameter("tel"));

        vo.setZipcode(request.getParameter("zipcode"));

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

        sqlSession.update("updateData",vo);

        sqlSession.commit();

        response.sendRedirect("listAction.amy");

    }

}

 

<삭제하기>

 

DeleteAction.java

 

package org.addrMy.action;

import java.io.IOException;

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 org.addrMy.config.MybatisManager;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

/**

 * Servlet implementation class DeleteAction

 */

@WebServlet("/address_my/deleteAction.amy")

public class DeleteAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public DeleteAction() {

        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");

        int num=Integer.parseInt(request.getParameter("num"));

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

        sqlSession.delete("deleteData", num);

        sqlSession.commit();

        response.sendRedirect("listAction.amy");

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(request, response);

    }

}

 


 

ObjectMapper.xml 주의점

 

<경로지정 혹은 형 지정>

ObjectMapper.xml 에 resulttype을 쓸때 경로가 아니므로 . 을 쓴다.

resultType="org/addrMy/model/AddressVO" 가 아닌

resultType="org.addrMy.model.AddressVO" 이다.

 

=>이름이 너무 기므로 별칭으로 대신 써주고 싶다면 Configuration.xml을 수정해야함

<typeAliases>, <typeAlias type="타입이름" alias="별칭">

 

ObjectMapper.xml에 다음과 같이 쓸 수 있다.

resultType="별칭"

 

<like 연산자 쓸때 주의점>

sql문에 like가 들어갈때  #{변수}는 홑따옴표를 포함하고 있기 때문에

'%#{dong}%' 이렇게 쓰면 안되고  '%'||#{dong}||'%' 이렇게 써야함.

 


 

<우편번호>

이번엔 API를 쓰지 않고 전국 주소 엑셀을 SQL에서 임포트하여 우편번호 DB를 만들었다.

ZipcodeVO.java

 

package org.addrMy.model;

public class ZipcodeVO {

    private String zipcode;

    private String sido;

    private String gugun;

    private String dong;

    private String bunji;

    private int seq;

    

    public String getZipcode() {

        return zipcode == null ? "" : zipcode.trim();

    }

    public void setZipcode(String zipcode) {

        this.zipcode = zipcode;

    }

    public String getSido() {

        return sido == null ? "" : sido.trim();

    }

    public void setSido(String sido) {

        this.sido = sido;

    }

    public String getGugun() {

        return gugun == null ? "" : gugun.trim();

    }

    public void setGugun(String gugun) {

        this.gugun = gugun;

    }

    public String getDong() {

        return dong == null ? "" : dong.trim();

    }

    public void setDong(String dong) {

        this.dong = dong;

    }

    public String getBunji() {

        return bunji == null ? "" : bunji.trim();

    }

    public void setBunji(String bunji) {

        this.bunji = bunji;

    }

    public int getSeq() {

        return seq;

    }

    public void setSeq(int seq) {

        this.seq = seq;

    }

}

zipCheck.jsp에서 비동기함수 $.post를 사용해서 ZipAction.java액션으로 갔다. Mybatis를 수행후 결과값이 List에 담겨있다. 그 값을 가지고 어디로 출력할 것인가? zipCheck.jsp에 다시 돌아온다. 비동기함수는 자신에게 돌아오는 함수이다. 

그런데 ZipAction.java에서 dispatcher를 사용하면 다른 페이지로 이동한다.

따라서 JSON 방법을 사용해서 값을 가지고, 데이터를 기다리고 있는 jsp에 가야한다.

예전에는 json simple jar를 이용하여 JSON object, array를 만들었는데.. 이번엔 gson-2.8.5.jar를 maven repository에서 다운받아 사용한다. 

https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.5

 

Maven Repository: com.google.code.gson » gson » 2.8.5

com.google.code.gson gson 2.8.5 // https://mvnrepository.com/artifact/com.google.code.gson/gson compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5' // https://mvnrepository.com/artifact/com.google.code.gson/gson libraryDependencies += "co

mvnrepository.com

 

ZipAction.java

 

package org.addrMy.action;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.HashMap;

import java.util.List;

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 org.addrMy.config.MybatisManager;

import org.addrMy.model.ZipcodeVO;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import com.google.gson.Gson;

/**

 * Servlet implementation class ZipAction

 */

@WebServlet("/address_my/zipAction.amy")

public class ZipAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public ZipAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        RequestDispatcher rd=request.getRequestDispatcher("zipCheck.jsp");

        rd.forward(request, response);

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        String dong=request.getParameter("dong");

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

        List<ZipcodeVO> zarr=sqlSession.selectList("zipData", dong);

        

        HashMap<String, Object> hm=new HashMap<String, Object>();

        hm.put("zarr",zarr);

        //java->json형태로 값 출력

        Gson gson=new Gson();

        String obj=gson.toJson(hm); //자바 오브젝을 json으로 만들어준다.

        response.setContentType("text/html;charset=utf-8");

        PrintWriter out=response.getWriter();

        out.println(obj.toString());

    }

}

zipCheck.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<script>

$(document).ready(function(){

    $("#send").click(function(){

        if($("#dong").val()==""){

            alert("동이름 입력");

            return false;

        }

        $.post("zipAction.amy",

              {"dong":$("#dong").val()},

              function(data){

                var res=JSON.parse(data); //JSON으로 부른게 아니기 때문에 파싱 필요

                var htmlStr="<table>";

                $.each(res.zarr,function(key,val){

                    var bunji=val.bunji==null?"":val.bunji;

                    var gugun=val.gugun==null?"":val.gugun;

                    htmlStr+="<tr>";

                    htmlStr+="<td>"+val.zipcode+"</td>";

                    htmlStr+="<td>"+val.sido+"</td>";

                    htmlStr+="<td>"+gugun+"</td>";

                    htmlStr+="<td>"+val.dong+"</td>";

                    htmlStr+="<td>"+bunji+"</td>";

                    htmlStr+="</tr>";

                });//each

                htmlStr+="</table>";

                $("#area").html(htmlStr);

             }//콜백함수

        )//post

    })//send

    

    $("#area").on("click","tr",function(){

        var address=$("td:eq(1)", this).text()+" "+

                    $("td:eq(2)", this).text()+" "+

                    $("td:eq(3)", this).text()+" "+

                    $("td:eq(4)", this).text();

        $(opener.document).find("#zipcode").val($("td:eq(0)",this).text());

        $(opener.document).find("#addr").val(address);

        self.close();

    })//area

})//document

</script>

</head>

<body>

<table>

    <tr>

        <td> 동이름입력: <input type="text" name="dong" id="dong">

        <input type="button" value="검색" id="send">

        </td>

    </tr>

    <tr>

        <td>*주소를 클릭하면 주소록에 자동 입력 됩니다</td>

    </tr>

</table>

<div id="area"></div>

</body>

</html>

 

 


 

<검색>

field값과 word값을 받아와서 selectList에 같이 들고 가야하는데 selectList는 Stirng 두개를 달고 가지 못한다. 따라서 해쉬맵에 field와 word를 저장한다.

그리고 List로 돌아온 검색결과를 뿌리기 위해 해쉬맵을 하나 더 만들어서 저장하고 gson을 이용하여 JSON으로 형변환후 toString으로 다시 돌려준다.

 

 

addrList.jsp 에서 검색부분을 삽입

addrList.jsp

<div align="left">

    <form name="search" id="search">

        <select name="field" id="field">

            <option value="name">이름</option>

            <option value="tel">전화</option>

        </select>

        <input type="text" name="word" id="word">

        <input type="button" value="검색" id="btnSearch">

    </form>

</div>

검색 버튼을 누르면 검색 실행

$(document).ready(function(){

    $("#btnSearch").click(function(){

        $.getJSON("searchAction.amy",

                 {"field":$("#field").val(), "word":$("#word").val()},

                 function(data){

                         $("#count").html("개수:"+data.count);

                        var htmlStr="";

                    $.each(data.arr, function(key,val){

                        htmlStr+="<tr>";

                        htmlStr+="<td>순서</td>";

                        htmlStr+="<td>"+val.num+"</td>";

                        htmlStr+="<td>"+val.name+"</td>";

                        htmlStr+="<td>"+val.addr+"</td>";

                        htmlStr+="<td>"+val.tel+"</td>";

                        htmlStr+="<td onclick='javascript:fdelete("+val.num+")'>"+삭제+"</td>";

                        htmlStr+="</tr>";

                    });

                        $("table tbody").html(htmlStr);

                }

        ); //getJSON

    })//btnSearch

});//document

 


SearchAction.java

 

package org.addrMy.action;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.HashMap;

import java.util.List;

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 org.addrMy.config.MybatisManager;

import org.addrMy.model.AddressVO;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import com.google.gson.Gson;

/**

 * Servlet implementation class SearchAction

 */

@WebServlet("/address_my/searchAction.amy")

public class SearchAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public SearchAction() {

        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");

        String field=request.getParameter("field");

        String word=request.getParameter("word");

        HashMap<String, String> map=new HashMap<String, String>();

        map.put("field", field);

        map.put("word", word);

        

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

        List<AddressVO> arr=sqlSession.selectList("searchData", map);

        int count=sqlSession.selectOne("countSearchData",map);

        

        HashMap<String,Object> hm=new HashMap<>();

        hm.put("arr",arr);

        hm.put("count",count);

        Gson gson=new Gson();

        String obj=gson.toJson(hm);

        response.setContentType("text/html;charset=utf-8");

        PrintWriter out=response.getWriter();

        out.println(obj.toString());

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(request, response);

    }

}

 


 

ajax로 삭제하기

 

addrList.jsp의 결과 테이블 td값에 자바스크립트 함수 포함

<td onclick="fdelete(${arr.num})">삭제</td>

function fdelete(num){

    if(confirm("정말 삭제하시겠습니까?")){

        $.getJSON("deleteAjaxAction.amy",

                 {"num":num},

                 function(data){

                     $("#count").html("개수:"+data.count);

                        var htmlStr="";

                     $.each(data.arr, function(key,val){

                        htmlStr+="<tr>";

                        htmlStr+="<td>순서</td>";

                        htmlStr+="<td>"+val.num+"</td>";

                        htmlStr+="<td><a href='viewAction.amy?num="+val.num+"'>"+val.name+"</a></td>";

                        htmlStr+="<td>"+val.addr+"</td>";

                        htmlStr+="<td>"+val.tel+"</td>";

                        htmlStr+="<td onclick='fdelete("+val.num+")'>삭제</td>";

                        htmlStr+="</tr>";

                    });

                        $("table tbody").html(htmlStr);

                 }

        )//getJSON

    }

}//fdelete

위 사항들을 종합한 ObjectMApper.xml 의 sql문들

<?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="org.addrMy.config.ObjectMapper">

 <sql id="search">

    <where>

        <if test="word!=null and field=='name'">

            <!-- name like '%'||#{word}||'%' -->

            name like '%${word}%'

        </if>

        <if test="word!=null and field=='tel'">

            tel like '%'||#{word}||'%'

        </if>

    </where>

 </sql>

 

 <!-- insert -->

 <insert id="insertData" parameterType="org.addrMy.model.AddressVO">

    insert into address(num, name, zipcode, addr, tel)

    values(address_seq.nextval,#{name},#{zipcode},#{addr},#{tel})

 </insert>

 

 <!-- all select -->

 <select id="listData" resultType="org.addrMy.model.AddressVO">

    select * from address

 </select>

 

 <!-- count -->

 <select id="countData" resultType="Integer">

    select count(*) from address

 </select>

 

 <!-- view -->

 <select id="viewData" parameterType="Integer" resultType="org.addrMy.model.AddressVO">

    select * from address where num=#{num}

 </select>

 

 <!-- update -->

 <update id="updateData" parameterType="org.addrMy.model.AddressVO">

    update address set name=#{name}, zipcode=#{zipcode}, addr=#{addr}, tel=#{tel} where num=#{num}

 </update>

 

 <!-- delete -->

 <delete id="deleteData" parameterType="Integer">

    delete from address where num=#{num}

 </delete>

 

 <!-- zipcode select -->

 <select id="zipData" parameterType="String" resultType="zipvo">

    select * from zipcode where dong like '%'||#{dong}||'%'

 </select>

 

 <!-- search -->

 <select id="searchData" parameterType="java.util.Map" resultType="org.addrMy.model.AddressVO">

    select * from address

    <include refid="search"></include>

 </select>

 

 

 <!-- countSearchData -->

 <select id="countSearchData" resultType="Integer" parameterType="java.util.Map">

    select count(*) from address

    <include refid="search"></include>

 </select>

 </mapper>

 

 

  • DAO 대신 MyBatis 사용하기 (DB연결, sql문 처리)


  • New Dynamic Web Project로 0_AddressMybatis 생성

  • WebContent에 address_my 폴더 생성후 addressInsert.jsp 만들기

 

addressInsert.jsp 

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

<script src="../js/jquery-3.5.1.min.js"></script>

<script>

$(function(){

    $("#btn").on("click",function(){

        if($("#name").val()==""){

            alert("이름을 입력하세요");

            return false;

        }

        if($("#zipcode").val()==""){

            alert("우편번호을 입력하세요");

            return false;

        }

        if($("#addr").val()==""){

            alert("주소를 입력하세요");

            return false;

        }

        if($("#tel").val()==""){

            alert("전화번호를 입력하세요");

            return false;

        }

        frm.submit();

    });

})

function zipfinder(){

    window.open("zipAction.amy","","width=700 height=400");   

}

</script>

</head>

<body>

<a href="list.jsp">전체보기</a> <br>

<form action="insertAction.amy" method="post" name="frm" id="frm">

<table>

    <tr>

        <td colspan="2">주소록 등록하기</td>

    </tr>

    <tr>

        <td>이름</td>

        <td><input type="text" name="name" id="name" size=15></td>

    </tr>

    <tr>

        <td>우편번호 </td>

        <td><input type="text" name="zipcode" id="zipcode" size=10>

        <input type="button" name="search" value="검색" onclick="zipfinder()"></td>

    <tr>

        <td>주소

        <td colspan="2"><input type="text" name="addr" id="addr" size=30>

        </td>

    </tr>

    </tr>

        <td>전화번호</td>

        <td colspan="2"><input type="text" name="tel" id="tel" size=15></td>

    <tr>

        <td colspan="2">

        <input type="submit" value="등록">

        <input type="reset" value="취소"></td>

    </tr>

</table>

</form>

</body>

</html>

 

  • src에 org.addrMy.action 패키지 생성 후 InsertAction.java 서블릿 만들기.

  • 이 서블릿에 Mybatis를 연결할 것이다.

  • AddressVO 클래스의 vo객체를 생성하고 파라미터로 넘어온 값들을 저장할 것이다.

 


  • org.addrMy.model 패키지. AddressVO.java 생성

AddressVO.java 

package org.addrMy.model;

public class AddressVO {

    private int num;

    private String name;

    private String addr;

    private String tel;

    private String zipcode;

    

    public int getNum() {

        return num;

    }

    public void setNum(int num) {

        this.num = num;

    }

    public String getName() {

        return name == null ? "" : name.trim();

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getAddr() {

        return addr == null ? "" : addr.trim();

    }

    public void setAddr(String addr) {

        this.addr = addr;

    }

    public String getTel() {

        return tel == null ? "" : tel.trim();

    }

    public void setTel(String tel) {

        this.tel = tel;

    }

    public String getZipcode() {

        return zipcode == null ? "" : zipcode.trim();

    }

    public void setZipcode(String zipcode) {

        this.zipcode = zipcode;

    }

}

 

 


  • 이번에는 DAO를 만들지 않고 Mybatis를 이용하여 sql문을 처리한다.

  • org.addrMy.config 패키지를 생성하고 Configuration.xml 만들기 (New File)

 

 

 

Configuration.xml

(MyBatis-3-User-Guide_ko.pdf 에서 복사 붙여넣기)

https://kldp.net/fwko/release/3410-MyBatis-3-User-Guide_ko.pdf

 

<?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="org/addrMy/config/jdbc.properties"/>

  <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="org/addrMy/config/ObjectMapper.xml"/>

  </mappers>

 </configuration>


${변수} 는 어딘가에서 내보낸 값들이 저장된다. 어디서 내보낸 걸까?

같은 패키지 경로에 jdbc.properties를 New File로 생성한다.

 

jdbc.properties

driver = oracle.jdbc.driver.OracleDriver

url = jdbc:oracle:thin:@localhost:1521:xe

username = scott

password = 1234

 


 

https://mvnrepository.com/artifact/org.mybatis/mybatis/3.4.6

 

Maven Repository: org.mybatis » mybatis » 3.4.6

 

mvnrepository.com

에서 MyBatis.jar 파일을 다운받는다. 3.4.6버전이다. WEB-INF의 lib 폴더에 붙여넣는다.

 

 


 

org.addrMy.config 안에 MybatisManager.java 클래스를 생성한다.

 

MybatisManager.java

package org.addrMy.config;

import java.io.IOException;

import java.io.Reader;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisManager {

    public static SqlSessionFactory sqlMapper;

    static {

        String resource="org/addrMy/config/Configuration.xml";

        Reader reader;

        try {

            reader=Resources.getResourceAsReader(resource);

            sqlMapper=new SqlSessionFactoryBuilder().build(reader);

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    public static SqlSessionFactory getSqlMapper() {

        return sqlMapper;

    }

}

여기서 Resources는 ibatis라 적힌것을 임포트 해야한다.

 


 

InsertAction.java

package org.addrMy.action;

import java.io.IOException;

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 org.addrMy.config.MybatisManager;

import org.addrMy.model.AddressVO;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

/**

 * Servlet implementation class InsertAction

 */

@WebServlet("/address_my/insertAction.amy")

public class InsertAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public InsertAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        RequestDispatcher rd=request.getRequestDispatcher("addressInsert.jsp");

        rd.forward(request, response);

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        AddressVO vo=new AddressVO();

        vo.setName(request.getParameter("name"));

        vo.setAddr(request.getParameter("addr"));

        vo.setNum(Integer.parseInt(request.getParameter("num")));

        vo.setTel(request.getParameter("tel"));

        vo.setZipcode(request.getParameter("zipcode"));

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

sqlSession.insert("insertData", vo);

        sqlSession.commit();

response.sendRedirect("listAction.amy");

    }

}

 


 

org.addrMy.config 패키지 내에 ObjectMapper.xml 생성

Mybatis 가이드북에서 mapper.dtd 복사 붙여넣기

 

ObjectMapper.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="org.addrMy.config.ObjectMapper">

 

 <insert id="insertData" parameterType="org.addrMy.model.AddressVO">

  insert into address(num, name, zipcode, addr, tel)

  values(address_seq.nextval,#{name},#{zipcode},#{addr},#{tel})

 </insert>

 <!-- all select -->

 <select id="listData" resultType="org.addrMy.model.AddressVO">

    select * from address

 </select>

 

 <!-- count -->

 <select id="countData" resultType="Integer">

    select count(*) from address

 </select>

 </mapper>

 

ListAction.java

 

package org.addrMy.action;

import java.io.IOException;

import java.util.List;

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 org.addrMy.config.MybatisManager;

import org.addrMy.model.AddressVO;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import sun.rmi.server.Dispatcher;

/**

 * Servlet implementation class ListAction

 */

@WebServlet("/address_my/listAction.amy")

public class ListAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public ListAction() {

        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");

        SqlSessionFactory sqlMapper=MybatisManager.getSqlMapper();

        SqlSession sqlSession=sqlMapper.openSession(ExecutorType.REUSE);

        List<AddressVO> arr=sqlSession.selectList("listData");

        int count=(Integer)sqlSession.selectOne("countData");

        request.setAttribute("arr", arr);

        request.setAttribute("count", count);

        RequestDispatcher rd=request.getRequestDispatcher("addrList.jsp");

        rd.forward(request, response);

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(request, response);

    }

}

 

 

addrList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<table>

<div align="left">

    <a href="insertAction.amy">글쓰기 <a/>/ 개수 (${count}) </span>

</div>

    <thead>

        <tr>

            <td>번호</td>

            <td>이름</td>

            <td>주소</td>

            <td>전화번호</td>

        </tr>

    </thead>

    <tbody>

    <c:forEach items="${arr}" var="arr">

        <tr>

            <td>${arr.num}</td>

            <td><a href="detail.do?num=${arr.num}">${arr.name}</a></td>

            <td>${arr.addr}</td>

            <td>${arr.tel}</td>

        </tr>

    </c:forEach>

    </tbody>

</table>

    <select name="field" id="field">

    <option value="name">이름</option>

    <option value="tel">전화</option>

    </select>

    <input type="text" name="word" id="word">

    <input type="button" value="검색" id="searchBtn">

</body>

</html>

ListAction.java를 실행하면 목록이 보인다.

이전글

https://amongthestar.tistory.com/152?category=411827

 

JSP 개인프로젝트-영어 학습 사이트 만들기 (수강후기 상세보기 및 수정 삭제, 댓글 입력 및 삭제)

이전글 https://amongthestar.tistory.com/151?category=411827 JSP 개인프로젝트-영어 학습 사이트 만들기 (수강후기 게시판 전체보기, 게시글 입력) 이전글 https://amongthestar.tistory.com/150 JSP 개인프로..

amongthestar.tistory.com

 


이번에 포스팅할 내용은 강의 상세보기 화면에서 "등록하기" 버튼을 눌렀을때 생기는 장바구니 담기 기능에 대해서다.

장바구니는 DB도 따로 있으니 DTO도 따로 생성했다.

 

WCartDTO.java

package com.wmember.model;

public class WCartDTO {
	private int cartnum;
	private int classnum;
	private String classname;
	private String userid;
	
	public int getCartnum() {
		return cartnum;
	}
	public void setCartnum(int cartnum) {
		this.cartnum = cartnum;
	}
	public int getClassnum() {
		return classnum;
	}
	public void setClassnum(int classnum) {
		this.classnum = classnum;
	}
	public String getClassname() {
		return classname == null ? "" : classname.trim();
	}
	public void setClassname(String classname) {
		this.classname = classname;
	}
	public String getUserid() {
		return userid == null ? "" : userid.trim();
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
}

강의 상세보기 화면에서 "등록하기" 버튼을 눌렀을때의 로직은 $.ajax함수를 이용했다.

 

//등록하기 클릭
	$("#subscribe").click(function(){
		if(${sessionScope.userid==null}){
			alert("로그인 필요");
			location.href="/Tutoring/member/login";
		}else{
			if(confirm("장바구니에 추가하시겠습니까?")){
				//장바구니에 있는지 확인
				$.ajax({
					type : "post",
					url  : "/Tutoring/class/cartCheck",
					data : {"classnum":$("#classnum").val(), "userid":$("#userid").val()},
					success : function(value){
						if(value.trim()=="1"){
							alert("이미 장바구니에 있는 강의입니다.");
						}else{
							$.ajax({
								  type:    "post",
				                  url :    "/Tutoring/class/cartInsert",
				                  data:    {"classnum":$("#classnum").val(), "userid":$("#userid").val(), "classname":$("#classname").val()},
				                  success:function(d){
				                	   if(d.trim()=="1"){
					                	   alert("장바구니에 강의가 담겼습니다!");
					                	   if(confirm("장바구니로 이동하시겠습니까?")){
					                		   location.href="/Tutoring/member/cartList.jsp";
					                	   }
				                	   }
				                  },
				                  error: function(e){
				                       alert("error:"+e);
				                  }
							})//ajax	
						}
					},
					error: function(e){
						alert("error:"+e);
					}
				})//ajax
			}//if
		}//else
	})//subscribe

 

가장먼저 로그인을 하도록 유도하고, 로그인이 되어있다면 카드에 있는지 확인하는 cartCheck을 수행한다.

동일한 강의일 경우 장바구니에 1개만 추가될 수 있기 때문이다. 

 

cartCheck을 수행하고 나면 장바구니에 추가할 수 있다. 추가 후에는 다음과 같은 메시지들이 뜬다. 

 


WCartCheck.java

(장바구니에 있는 확인하는 서블릿. 경로는 "/Tutoring/class/cartCheck"이다.)

 

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 com.wmember.model.WCartDAO;
import com.wmember.model.WCartDTO;

/**
 * Servlet implementation class WCartCheck
 */
@WebServlet("/class/cartCheck")
public class WCartCheck extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WCartCheck() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 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 {
		request.setCharacterEncoding("utf-8");
        int classnum=Integer.parseInt(request.getParameter("classnum"));
        String userid=request.getParameter("userid");
        WCartDAO dao=WCartDAO.getInstance();
        int flag=dao.cartCheck(classnum, userid); //이미 userid에 classnum이 동일하게 있다면 flag=1;
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println(flag);
	}

}

 

파라미터 값으로 받아온 강의번호와 아이디를 인자로하여 WCartDAO.java에서 cartCheck 메소드를 수행한다. 반환값을 받아서 다시 ajax으로 이동한다.

 


<WCartDAO.java에서 cartCheck 메소드>

 

//디비셋팅
	private static WCartDAO instance=new WCartDAO();
	public static WCartDAO getInstance() {
		return instance;
	}
	private Connection getConnection() throws Exception{
		Context initCtx=new InitialContext();
		Context envCtx=(Context) initCtx.lookup("java:comp/env");
		DataSource ds=(DataSource) envCtx.lookup("jdbc/wiser"); //context.xml의 name을 jdbc/member로 바꾸기
		return ds.getConnection();
	}

//장바구니 체크
	public int cartCheck(int classnum, String userid) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		int flag=-1;
		try {
			con=getConnection();
			String sql="select classnum, classname from wcart where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			if(rs.next()) { //id 맞음
				if(rs.getInt("classnum")==classnum) { //비번 일치
					flag=1;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return flag;
	}
    
//닫기 closeConnection
	private void closeConnection(Connection con, PreparedStatement ps) {
		try {
			if(ps!=null) ps.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}
	private void closeConnection(Connection con, Statement st, ResultSet rs) {
		try {
			if(st!=null) st.close();
			if(con!=null) con.close();
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

 


cartCheck후 리턴된 flag 값이 1일 경우 장바구니에 있는 강의라는 메시지가 출력되고,

그게 아닐 경우 장바구니에 추가하는 cartInsert를 실행한다.

success : function(value){
	if(value.trim()=="1"){
		alert("이미 장바구니에 있는 강의입니다.");
	}else{
		$.ajax({
		type:    "post",
		url :    "/Tutoring/class/cartInsert",
		data:    {"classnum":$("#classnum").val(), "userid":$("#userid").val(), "classname":$("#classname").val()},
		success:function(d){
          if(d.trim()=="1"){
            alert("장바구니에 강의가 담겼습니다!");
            if(confirm("장바구니로 이동하시겠습니까?")){
            	location.href="/Tutoring/member/cartList.jsp";
          		}
			}
        },
        error: function(e){
            alert("error:"+e);
        }
		})//ajax	
	}
},

 


WCartInsert.java

(장바구니 추가 진행 서블릿. 경로는 "/Tutoring/class/cartInsert"이다.)

 

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 com.wmember.model.WCartDAO;
import com.wmember.model.WCartDTO;

/**
 * Servlet implementation class WCartInsert
 */
@WebServlet("/class/cartInsert")
public class WCartInsert extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WCartInsert() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        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 {
        request.setCharacterEncoding("utf-8");
        WCartDTO cart=new WCartDTO();
        cart.setClassname(request.getParameter("classname"));
        cart.setClassnum(Integer.parseInt(request.getParameter("classnum")));
        cart.setUserid(request.getParameter("userid"));
        WCartDAO dao=WCartDAO.getInstance();
        int flag=dao.cartInsert(cart);
        PrintWriter out = response.getWriter();
        out.println(flag);
    }
}

 

파라미터 값으로 받아온 강의이름, 강의번호, 아이디를 WCartDTO형의 cart객체에 담고 WCartDAO.java의 cartInsert메소드를 수행한다. 리턴값을 내보낸다.

 

 


<WCartDAO.java의 cartInsert메소드>

 

//장바구니 추가
	public int cartInsert(WCartDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		int flag=0;
		
		try {
			con=getConnection();
			String sql="INSERT INTO wcart(cartnum, classnum, userid, classname) VALUES(wcart_seq.nextval,?,?,?)";
			ps=con.prepareStatement(sql);
			ps.setInt(1, vo.getClassnum());
			ps.setString(2, vo.getUserid());
			ps.setString(3, vo.getClassname());
			flag=ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
		return flag;
	}

 

장바구니에 추가가 되었다면 int 형의 flag 값이 1이 된다.

 

 


flag 값이 1이라면 장바구니에 강의가 담겼습니다! 메시지가 출력된다. 그리고 장바구니로 이동하겠냐는 confirm창에서 확인을 누르면 cartList.jsp로 이동한다.

success:function(d){
      if(d.trim()=="1"){
        alert("장바구니에 강의가 담겼습니다!");
        if(confirm("장바구니로 이동하시겠습니까?")){
        location.href="/Tutoring/member/cartList.jsp";
      }
	}
},

cartList.jsp

장바구니 리스트를 getJSON을 통해 불러온다.

 

$(document).ready(function(){
	//장바구니 리스트를 불러옴
	$.getJSON("/Tutoring/member/cartList", 
				{userid:$("#userid").val()}, 
				function(d){
					var htmlStr="<table class='table table-hover table-bordered table-sm'>";
						htmlStr+="<thead><tr>";
		            	htmlStr+="<th style='width: 10%; text-align: center;'>강의 번호</th>";
		            	htmlStr+="<th style='text-align: center;'>강의명</th>";
		            	htmlStr+="<th style='width: 10%; text-align: center'>삭제</th>";
		            	htmlStr+="</tr></thead>";
		            	htmlStr+="<tbody>";
					$.each(d.carr, function(key, val){ 
		            	htmlStr+="<tr>";
	            		htmlStr+="<td>"+val.cartnum+"</td>";
	            		htmlStr+="<td>"+val.classname+"</td>";
	            		htmlStr+="<td style='text-align: center;'><a href='javascript:cartdel("+val.cartnum+")'><img src='/Tutoring/img/delete.png' style='height:20px; width:20px;'></a></td>";
						htmlStr+="</tr>";
					})
						htmlStr+="</tbody></table>";
						$(".back2").html(htmlStr);
				}
	)
})

 


WCartList.java

(장바구니 리스트 기능을 구현하는 서블릿. 경로는 "/Tutoring/member/cartList"이다.)

package com.wclass.action;

import java.io.IOException;
import java.io.PrintWriter;
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 javax.servlet.http.HttpSession;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import com.wmember.model.WCartDAO;
import com.wmember.model.WCartDTO;

/**
 * Servlet implementation class WCartList
 */
@WebServlet("/member/cartList")
public class WCartList extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WCartList() {
        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");
		String userid=request.getParameter("userid");
		WCartDAO dao=WCartDAO.getInstance();
		ArrayList<WCartDTO> arr= dao.cartList(userid);
		
		JSONObject mainObj=new JSONObject();
		JSONArray jarr=new JSONArray();
		
		for(WCartDTO cd:arr) {
			JSONObject obj=new JSONObject();
			obj.put("userid", cd.getUserid());
			obj.put("cartnum", cd.getCartnum());
			obj.put("classnum", cd.getClassnum());
			obj.put("classname", cd.getClassname());
			jarr.add(obj);
		}
		mainObj.put("carr", jarr);
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		out.println(mainObj.toString());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

 

WCartDAO의 cartList 메소드를 수행하고 arr 객체에 담는다. 그 arr 객체를 다시 JSONObject과 JSONArray로 처리하고 object 객체를 내보낸다.

 


<WCartDAO의 cartList 메소드>

 

//장바구니 전체보기
	public ArrayList<WCartDTO> cartList(String userid) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		ArrayList<WCartDTO>arr=new ArrayList<WCartDTO>();
		
		try {
			con=getConnection();
			String sql="select * from wcart where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			while(rs.next()) {
				WCartDTO dto=new WCartDTO();
				dto.setCartnum(rs.getInt("cartnum"));
				dto.setClassnum(rs.getInt("classnum"));
				dto.setUserid(rs.getString("userid"));
				dto.setClassname(rs.getString("classname"));
				arr.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return arr;
	}

 

cartList.jsp에서 불러온 장바구니 목록을 볼 수 있다.

 


장바구니에서 해당 강의를 삭제하는 것은 어떻게 구현할 수 있을까?

자신이 쓴 글이면 삭제할수 있도록 휴지통 아이콘이 나타난다. 그 아이콘에 자바스크립트 함수를 붙여넣는다.

 

htmlStr+="<td style='text-align: center;'><a href='javascript:cartdel("+val.cartnum+")'><img src='/Tutoring/img/delete.png' style='height:20px; width:20px;'></a></td>";

 

장바구니 삭제함수가 호출되면 getJSON을 이용하여 cartDelete 경로로 이동한다. 삭제되고 나서도 나머지 목록이 보여야하므로 $.each로 값을 출력한다.

//장바구니 삭제함수
function cartdel(cartnum){
	if(confirm("장바구니에서 삭제하시겠습니까?")){
		$.getJSON("/Tutoring/member/cartDelete", 
				{"cartnum":cartnum, userid:$("#userid").val()}, 
				function(d){
						var htmlStr="<table class='table table-hover table-bordered table-sm'>";
						htmlStr+="<thead><tr>";
		            	htmlStr+="<th style='width: 10%; text-align: center;'>강의 번호</th>";
		            	htmlStr+="<th style='text-align: center;'>강의명</th>";
		            	htmlStr+="<th style='width: 10%; text-align: center'>삭제</th>";
		            	htmlStr+="</tr></thead>";
		            	htmlStr+="<tbody>";
					$.each(d.carr, function(key, val){ 
		            	htmlStr+="<tr>";
	            		htmlStr+="<td>"+val.classnum+"</td>";
	            		htmlStr+="<td>"+val.classname+"</td>";
	            		htmlStr+="<td style='text-align: center;'><a href='javascript:cartdel("+val.cartnum+")'><img src='/Tutoring/img/delete.png' style='height:20px; width:20px;'></a></td>";
						htmlStr+="</tr>";
					})
						htmlStr+="</tbody></table>";
						$(".back2").html(htmlStr);
				}
		)
	}
}

 

 


WCartDelete.java

(장바구니 삭제를 진행하는 서블릿. 경로는 "/Tutoring/member/cartDelete"이다.)

 

package com.wclass.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

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 org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import com.wmember.model.WCartDAO;
import com.wmember.model.WCartDTO;

/**
 * Servlet implementation class WCartDelete
 */
@WebServlet("/member/cartDelete")
public class WCartDelete extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WCartDelete() {
        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");
		String userid=request.getParameter("userid");
		int cartnum=Integer.parseInt(request.getParameter("cartnum"));
		WCartDAO dao=WCartDAO.getInstance();
		dao.cartDel(cartnum);
		response.sendRedirect("/Tutoring/member/cartList?userid="+userid);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

 

삭제한 뒤에는 userid를 들고 장바구니 목록으로 다시 돌아간다.


<WCartDAO.java의 cartDel 메소드>

 

//장바구니에서 삭제
	public void cartDel(int cartnum) {
		Connection con=null;
		Statement st=null;
		try {
			con=getConnection();
			String sql="delete from wcart where cartnum='"+cartnum+"'";
			st=con.createStatement();
			st.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, null);
		}
	}

 


<아쉬운 점>

1. 장바구니 외에 따로 결제 기능을 구현하지 못했다. 다른 라이브러리를 배우는데로 업데이트할 예정이다. 다른 사이트들은 잘 모르겠지만.. 캠블리는 장바구니가 아니라 단위 기간별로 결제를 먼저 하는 것 같았는데 그 로직을 이해하지 못했기 때문이다. 

 

2. 또한 영어를 화상으로 튜터와 1:1로 배우는 특성을 살리지 못한 점. 꼭 동영상 수업이 아니더라도.. 그러려면 튜터 DB를 하나 생성해서 학생과 매치시켜야겠지. 그게 어떻게 가능할까?

 

3. 내 강의실을 만들고, 학습하고, 남은 강의일수를 확인하는 시스템을 넣지 못한 점. 결제가 안되기 때문에 장바구니에서 제목을 클릭하면 강의 상세 페이지로 이동만 시켰다. 

 

이로써 JSP 개인프로젝트 리뷰를 마치겠다.

 

https://github.com/kkj0712/JspProject_Tutoring

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

 

이전글

 

https://amongthestar.tistory.com/151?category=411827

 

JSP 개인프로젝트-영어 학습 사이트 만들기 (수강후기 게시판 전체보기, 게시글 입력)

이전글 https://amongthestar.tistory.com/150 JSP 개인프로젝트-영어 학습 사이트 만들기 (강의목록 전체보기, 상세보기) 이전글 (관리자 기능) https://amongthestar.tistory.com/149 JSP 개인프로젝트-영어 학..

amongthestar.tistory.com


지금까지 courseDetail.jsp 내에서 $.ajax을 통해 수강후기 전체글을 가져오고, 글쓰기 폼에서 후기등록 버튼을 눌렀을때 boardList로 이동하는 것까지 보았다.

 

오늘 포스팅할 내용은 수강후기 게시판에서 제목을 눌렀을 때 보이는 수강후기 글 상세보기 및 수정, 삭제와 그 밑에 달리는 댓글 입력하고 삭제하는 기능 구현이다.

 

 

제목을 누르면 boardDetail로 이동하여 다음과 같은 화면이 보인다. 댓글이 달려있다.

 


수강후기 전체 글의 껍데기인 listResult.jsp의 다음 코드에 의해 제목을 누르면 상세페이지로 이동한다.

<td><a href="/Tutoring/board/boardDetail?num=${board.num}">${board.subject}</a></td>

 


WBoardDetailAction.java

(수강후기 상세페이지 서블릿. 경로는 "/Tutoring/board/boardDetail"이다.)

package com.wboard.action;

import java.io.IOException;

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.WBoardDAO;
import com.wmember.model.WBoardDTO;


/**
 * Servlet implementation class BoardDetailAction
 */
@WebServlet("/board/boardDetail")
public class WBoardDetailAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WBoardDetailAction() {
        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");
		int num=Integer.parseInt(request.getParameter("num"));
		WBoardDAO dao=WBoardDAO.getInstance();
		WBoardDTO dto=dao.boardView(num);
		request.setAttribute("dto", dto);
		RequestDispatcher rd=request.getRequestDispatcher("detail.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

파라미터 값으로 넘어온 num을 인자로 하여 WBoardDAO의 boardView메소드를 수행하고, dto객체를 dto이름으로 담아서 detail.jsp로 이동한다.

 

 


<WBoardDAO의 boardView메소드>

//게시물 상세보기
	public WBoardDTO boardView (int num) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		WBoardDTO dto=null;
		try {
			con=getConnection();
			st=con.createStatement();
			st.execute("update wboard set readcount = readcount+1 where num ="+num);
			String sql = "SELECT * FROM wboard WHERE num="+num;
			rs=st.executeQuery(sql);
			if(rs.next()) {
				dto=new WBoardDTO();
				dto.setNum(rs.getInt("num"));
				dto.setContent(rs.getString("content"));
				dto.setReadcount(rs.getInt("readcount"));
				dto.setReg_date(rs.getString("reg_date"));
				dto.setSubject(rs.getString("subject"));
				dto.setUserid(rs.getString("userid"));
				dto.setClassnum(rs.getInt("classnum"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return dto;
	}

 

수강후기 글을 클릭할 때마다 조회수 (readcount)가 1씩 증가하도록 했다.


detail.jsp

수강후기 상세글 jsp이다. 

수강후기 상세보기와 댓글 입력, 댓글 목록 영역으로 이루어져있다.

 

<div class="container">
<!-- 액션처리를 위한 값들 -->
<input type="hidden" id="num" name="num" value="${dto.num}"> <!-- 수강후기 게시글 번호 -->
<input type="hidden" id="classnum" name="classnum" value="${dto.classnum}">
<c:set var="classnum" value="${dto.classnum}" />
<!-- 수강 후기 글보기-->
<div><a href="/Tutoring/class/CourseDetail?num=${dto.classnum}"><b>〈</b> 뒤로가기</a></div>
<br/>
	  <h5>수강후기</h5>
	  <br/>
	  <table class="table table-bordered table-sm">
	  <tr>
	 	<td style="width: 15%; background-color: #f8f9fa; text-align: center">글번호</td>
	 	<td style="width: 40%;">${dto.num}</td>
	 	<td style="width: 30%; background-color: #f8f9fa; text-align: center">조회수</td>
	 	<td style="width: 15%; text-align: right;">${dto.readcount}</td>
	  </tr>
	  <tr>
	 	<td style="background-color: #f8f9fa; text-align: center;">작성자</td>
	 	<td>${dto.userid}</td>
	 	<td style="background-color: #f8f9fa; text-align: center;">작성일</td>
	 	<td style="text-align: right">${dto.reg_date}</td>
	  </tr>
	  <tr>
	 	<td style="background-color: #f8f9fa; text-align: center">제목</td>
	 	<td colspan="3">${dto.subject}</td>
	  </tr>
	  <tr style="height: 150px">
	 	<td style="background-color: #f8f9fa; vertical-align: middle; text-align: center">글 내용</td>
	 	<td colspan="3">${dto.content}</td>
	  </tr>
	</table>
<!-- 수강후기 글보기 끝 -->
<!-- 수정, 삭제 버튼 보이기 -->
<c:set var="loginUserid" value="${sessionScope.userid}" />
<c:set var="userid" value="${dto.userid}" />
<c:if test="${loginUserid eq userid}">
		<div align="center" id="button">
			<input type="button" id="upBoard" name="upBoard" value="수정 " class="btn btn-info btn-sm" onclick="location.href='boardview?num=${dto.num}'"> 
			<input type="button" id="delBtn" name="delBtn" value="삭제" class="btn btn-danger btn-sm" onclick="javascript:fdelete(${dto.num}, ${dto.classnum})">
		</div> 
		<br/>
</c:if>
<!-- 수정, 삭제 버튼 보이기 끝-->
<!-- 댓글 리스트 영역 -->
	<div id="commentResult">
	</div>
<!-- 댓글 리스트 영역 끝-->
<!-- 댓글 달기 영역-->
	<div id="commentDiv" align="center">
		<textarea rows="2" cols="20" id="msg" name="msg" class="table table-bordered table-sm"></textarea>
<c:if test="${not empty sessionScope.userid}">
		<input type="button" id="commentBtn" name="commentBtn" value="댓글 " class="btn btn-info btn-sm">
</c:if>
	</div>
	<br/>
<!-- 댓글 달기 영역 끝 -->
</div>

자신이 쓴 글일 경우
다른이가 쓴 글일 경우

  • 현재 로그인한 userid와 글의 userid가 같으면 수정, 삭제 버튼이 보이도록 <c:set>과 <c:if>문으로 처리했다.
  • 댓글입력 버튼 또한 로그인을 하지 않으면 아예 보이지 않게 설정했다. 
  • 수강 후기 글을 클릭하자마자 댓글 리스트를 불러오도록 $.getJSON으로 처리했다.
$(document).ready(function(){
	//문서 열자마자 댓글 리스트를 불러옴
	$.getJSON("/Tutoring/board/commentList", 
				{num:$("#num").val()}, 
				function(d){
					var htmlStr="<table class='table table-striped'>";
					$.each(d.carr, function(key, val){ 
						htmlStr+="<tr>";
						htmlStr+="<th style='width:10%;'>"+val.userid+"</th>";
						htmlStr+="<td style='width:60%;'>"+val.msg+"</td>";
						htmlStr+="<td style='width:20%;'>"+val.reg_date+"</td>";
						
						if(val.userid == '${sessionScope.userid}'){
							htmlStr+="<td style='width:10%;'><a href='javascript:cdelete("+val.cnum+","+val.bnum+")'><img src='/Tutoring/img/delete.png' style='height:20px; width:20px;'></a></td>";
						}else{
							htmlStr+="<td></td>";
						}
						
						htmlStr+="</tr>";
					})
						htmlStr+="</table>";
						$("#commentResult").html(htmlStr);
				}
	)

 

commentList 서블릿에서 JSONObject과 JSONArray클래스를 이용하여 최종적으로 JSONObject 객체에 저장된 데이터를 $.each로 뿌린다. 


CommentDTO.java

package com.wmember.model;

public class CommentDTO {
	private int cnum;
	private String userid;
	private String msg;
	private String reg_date;
	private int bnum;
	public int getCnum() {
		return cnum;
	}
	public void setCnum(int cnum) {
		this.cnum = cnum;
	}
	public String getUserid() {
		return userid == null ? "" : userid.trim();
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getMsg() {
		return msg == null ? "" : msg.trim();
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
	public String getReg_date() {
		return reg_date == null ? "" : reg_date.trim();
	}
	public void setReg_date(String reg_date) {
		this.reg_date = reg_date;
	}
	public int getBnum() {
		return bnum;
	}
	public void setBnum(int bnum) {
		this.bnum = bnum;
	}
}

 


CommentListAction.java

(댓글 리스트 실행하는 서블릿. 경로는 "/Tutoring/board/commentList"이다.)

 

package com.wboard.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

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 org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import com.wmember.model.CommentDTO;
import com.wmember.model.WBoardDAO;


/**
 * Servlet implementation class CommentListAction
 */
@WebServlet("/board/commentList")
public class CommentListAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CommentListAction() {
        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");
		int bnum=Integer.parseInt(request.getParameter("num"));
		WBoardDAO dao=WBoardDAO.getInstance();
		ArrayList<CommentDTO> arr=dao.commentList(bnum);
		//arr를 json형태로 리턴
		JSONObject mainObj=new JSONObject();
		JSONArray jarr=new JSONArray();
		
		for(CommentDTO cd:arr) {
			JSONObject obj=new JSONObject();
			obj.put("bnum", cd.getBnum());
			obj.put("cnum", cd.getCnum());
			obj.put("msg", cd.getMsg());
			obj.put("userid", cd.getUserid());
			obj.put("reg_date", cd.getReg_date());
			jarr.add(obj);
		}
		mainObj.put("carr", jarr);
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		out.println(mainObj.toString());
	
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

  • 파라미터 값으로 받아온 수강후기 글번호(num)를 bnum 변수에 저장하고, 그것을 인자로 하여 WBoardDAO.java의 commentList메소드를 수행한다.
  • 불러온 곳으로 다시 값을 들고 가야하므로 JSONObject과 JSONArray클래스를 활용한다. 

 

<WBoardDAO.java의 commentList메소드>

 

//코멘트 리스트 commentList
	public ArrayList<CommentDTO> commentList(int bnum){
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		ArrayList<CommentDTO> arr=new ArrayList<CommentDTO>();
		try {
			con=getConnection();
			String sql="select * from wcomment_board where bnum="+bnum+ "order by cnum desc";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			while(rs.next()) {
				CommentDTO comment=new CommentDTO();
				comment.setBnum(rs.getInt("bnum"));
				comment.setCnum(rs.getInt("cnum"));
				comment.setMsg(rs.getString("msg"));
				comment.setReg_date(rs.getString("reg_date"));
				comment.setUserid(rs.getString("userid"));
				arr.add(comment);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return arr;
	}

 


이로써 게시글 상세보기 및 댓글 전체 목록 (comment list)를 출력할 수 있다.

 

 

자신이 쓴 게시글일 경우 삭제하고 싶으면 삭제 버튼을 누르면 된다.

 

<input type="button" id="delBtn" name="delBtn" value="삭제" class="btn btn-danger btn-sm" onclick="javascript:fdelete(${dto.num}, ${dto.classnum})">

삭제 버튼에 onclick을 달아 자바스크립트 함수를 호출했다.

confrim 창에서 확인을 누르면 삭제 메소드를 호출하는 서블릿으로 이동한다.

//게시글 삭제 함수
function fdelete(num, classnum){
	if(confirm("게시물을 삭제 하시겠습니까?")){
		location.href="delete?num=${dto.num}&classnum=${dto.classnum}";
	}
}

 


WBoardDeleteAction.java

(삭제 메소드를 호출하는 서블릿. 경로는 "/Tutoring/board/delete"이다.)

 

package com.wboard.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 com.wmember.model.WBoardDAO;

/**
 * Servlet implementation class BoardDeleteAction
 */
@WebServlet("/board/delete")
public class WBoardDeleteAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WBoardDeleteAction() {
        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");
		int num=Integer.parseInt(request.getParameter("num"));
		int classnum=Integer.parseInt(request.getParameter("classnum"));
		WBoardDAO dao=WBoardDAO.getInstance();
		dao.boardDel(num);
		response.sendRedirect("/Tutoring/class/CourseDetail?num="+classnum);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

게시글 삭제 후에는 강의번호를 달고 다시 강의 상세정보 페이지로 이동한다.


<WBoardDAO.java의 boardDel메소드>

 

//게시글 삭제
	public void boardDel(int num) {
		Connection con=null;
		Statement st=null;
		try {
			con=getConnection();
			st=con.createStatement();
			String sql="delete from WBoard where num="+num;
			st.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, null);
		}
	}

 


 

그렇다면 자신이 쓴 게시글을 어떻게 수정할 수 있을까? 앞서 글의 userid와 현재 로그인한 userid가 동일한 경우에만 수정버튼, 삭제버튼이 보이도록 했다.

 

<!-- 수정, 삭제 버튼 보이기 -->
<c:set var="loginUserid" value="${sessionScope.userid}" />
<c:set var="userid" value="${dto.userid}" />
<c:if test="${loginUserid eq userid}">
		<div align="center" id="button">
			<input type="button" id="upBoard" name="upBoard" value="수정 " class="btn btn-info btn-sm" onclick="location.href='boardview?num=${dto.num}'"> 
			<input type="button" id="delBtn" name="delBtn" value="삭제" class="btn btn-danger btn-sm" onclick="javascript:fdelete(${dto.num}, ${dto.classnum})">
		</div> 
		<br/>
</c:if>
<!-- 수정, 삭제 버튼 보이기 끝-->

 

수정 버튼을 누르면 onclick location에 의해 boardview로 num값을 달고 간다. num은 이 게시글의 번호이다. (WBoardDTO의 num)

 

지금은 게시글을 그냥 볼 수 있는 화면이고, 수정할 수 있도록 폼 양식이 살아있는 화면으로 바뀌어야한다.

 


WBoardViewAction.java

(게시글을 수정할 수 있는 화면으로 넘기는 서블릿. 경로는 "/Tutoring/board/boardview" 이다.)

 

package com.wboard.action;

import java.io.IOException;

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.WBoardDAO;
import com.wmember.model.WBoardDTO;

/**
 * Servlet implementation class WBoardViewAction
 */
@WebServlet("/board/boardview")
public class WBoardViewAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WBoardViewAction() {
        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");
		int num=Integer.parseInt(request.getParameter("num"));
		WBoardDAO dao=WBoardDAO.getInstance();
		WBoardDTO dto=dao.boardView(num);
		request.setAttribute("dto", dto);
		RequestDispatcher rd=request.getRequestDispatcher("updateForm.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

  • 파라미터 값으로 받아온 num을 인자로하여 WBoardDAO.java의 boardView 메소드를 수행한다.
  • dto객체를 dto이름에 담고 updateForm.jsp로 이동한다.

 

 


<WBoardDAO.java의 boardView 메소드>

  • 앞서 나온 메소드와 동일하다. 두 개의 서블릿에서 동일한 메소드를 거쳐 다른 출력화면으로 가는 것이다.
  • listResult.jsp(수강후기 전체 목록)의 제목 클릭->boardDetail(WBoardDetailAction.java)->WBoardDAO의 boardView 메소드->detail.jsp
  • detail.jsp의 수정버튼 클릭->boardView(WBoardViewAction.java)->WBoardDAO의 boardView 메소드->updateForm.jsp
//게시물 상세보기
	public WBoardDTO boardView (int num) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		WBoardDTO dto=null;
		
		try {
			con=getConnection();
			st=con.createStatement();
			st.execute("update wboard set readcount = readcount+1 where num ="+num);
			String sql = "SELECT * FROM wboard WHERE num="+num;
			rs=st.executeQuery(sql);
			if(rs.next()) {
				dto=new WBoardDTO();
				dto.setNum(rs.getInt("num"));
				dto.setContent(rs.getString("content"));
				dto.setReadcount(rs.getInt("readcount"));
				dto.setReg_date(rs.getString("reg_date"));
				dto.setSubject(rs.getString("subject"));
				dto.setUserid(rs.getString("userid"));
				dto.setClassnum(rs.getInt("classnum"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return dto;
	}

 


updateForm.jsp

수강후기글을 수정할 수 있는 화면

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/include/header.jsp" %>    
<script>
//취소 함수
function back(){
	if(confirm("나가겠습니까? 변경사항은 저장되지 않습니다.")){
		location.href="/Tutoring/board/boardDetail?num=${dto.num}";
	}
}
</script>
<form action="/Tutoring/board/boardUpdate" method="post" id="wFrm">
<div class="container">
			<br/><br/>
			  <!-- 수강후기 등록하고자 하는 강의 번호 -->
			  <input type="hidden" id="classnum" name="classnum" value="${dto.classnum}">
			  
			  <!-- 게시글 번호 -->
			  <input type="hidden" id="num" name="num" value="${dto.num}">
			  
			  <div class="input-group mb-3"><div class="input-group-prepend">
			  	  <span class="input-group-text">작성자</span></div>
			      <input type="text" class="form-control" id="userid" name="userid" readonly="readonly" value="${dto.userid}">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3"><div class="input-group-prepend">
			      <span class="input-group-text">제목</span></div>
			      <input type="text" class="form-control" id="subject" name="subject" value="${dto.subject}">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3"><div class="input-group-prepend">
			      <span class="input-group-text">내용</span></div>
			      <textarea rows="5" cols="20" class="form-control" id="content" name="content">${dto.content}</textarea>
			  </div>
			  
			  <div class="button" align="center">
			 	  <input type="reset" class="btn btn-gray" value="취소" onclick="javascript:back()">
			 	  <input type="submit" class="btn btn-primary" value="수정">
			  </div>
			  <br/>
			</form>
</div>
<%@ include file="/include/footer.jsp" %>

자신이 쓴 글의 수정버튼을 누르면 밑의 이미지처럼 updateForm.jsp 화면으로 이동한다.
updateForm.jsp 폼 양식 안에서 자신이 쓴 글을 수정할 수 있다. 

  • boardView 메소드를 거쳐 dto이름으로 저장된 dto 객체를 폼 양식 안에서 출력한다.
  • 수정버튼을 누르면 수정할 수 있는 서블릿으로 이동한다.

WBoardUpdateAction.java

(수정할 수 있는 구현체를 연결하는 서블릿. 경로는 "/Tutoring/board/boardUpdate"이다.)

 

 package com.wboard.action;

import java.io.IOException;

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.WBoardDAO;
import com.wmember.model.WBoardDTO;


/**
 * Servlet implementation class BoardUpdateAction
 */
@WebServlet("/board/boardUpdate")
public class WBoardUpdateAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WBoardUpdateAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("updateForm.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WBoardDTO board=new WBoardDTO();
		board.setNum(Integer.parseInt(request.getParameter("num")));
		board.setContent(request.getParameter("content"));
		board.setSubject(request.getParameter("subject"));
		board.setUserid(request.getParameter("userid"));

		int num=Integer.parseInt(request.getParameter("num"));
		WBoardDAO dao=WBoardDAO.getInstance();
		dao.boardUpdate(board);
		response.sendRedirect("/Tutoring/board/boardDetail?num="+num);
	}

}

 

  • 파라미터 값으로 받아온 게시글 번호, 내용, 제목, 아이디를 board객체에 저장한 후 이를 인자로 하여 WBoardDAO.java의 boardUpdate 메소드를 호출한다.
  • 게시글 수정 후에는 수강후기 상세보기 페이지로 다시 이동한다.

 


<WBoardDAO.java의 boardUpdate 메소드>

 

//게시물정보 수정
	public int boardUpdate(WBoardDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		int flag=0;
		try {
			con=getConnection();
			String sql="update WBoard set subject=?, content=?, reg_date=sysdate where num=?";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getSubject());
			ps.setString(2, vo.getContent());
			ps.setInt(3, vo.getNum());
			flag=ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
		return flag;
	}

 

 


지금까지의 진행과정:

1. 게시판 목록에서 제목을 클릭하여 게시글 상세보기

2. 댓글목록을 보기

3. 게시글 삭제하기

4. 게시글 수정버튼을 눌러서 수정할 수 있는 화면으로 이동 -> 수정하기

 

 

앞에서 댓글목록을 부르는 것은 했다.

 

그렇다면 댓글은 어떻게 입력할까?

수강후기글 상세보기 페이지인 detail.jsp에서 로그인되어 있을 경우에만 댓글 버튼이 보이도록 처리했다.

<!-- 댓글 달기 영역-->
	<div id="commentDiv" align="center">
		<textarea rows="2" cols="20" id="msg" name="msg" class="table table-bordered table-sm"></textarea>
<c:if test="${not empty sessionScope.userid}">
		<input type="button" id="commentBtn" name="commentBtn" value="댓글 " class="btn btn-info btn-sm">
</c:if>
	</div>
	<br/>
<!-- 댓글 달기 영역 끝 -->

 

자바스크립트 함수에서 댓글 버튼을 눌렀을 경우 ajax 함수를 통해 commentInsert 서블릿으로 이동한다.

//댓글 입력 버튼
	$("#commentBtn").on("click", function(){
		if($("#msg").val()==""){
			alert("댓글을 작성해주세요");
			$("#msg").focus();
			return false;
		}else{
			$.ajax({
				type: "get",
				url: "commentInsert",
				data: {"msg":$("#msg").val(), "num":$("#num").val()},
				success: function(d){
						var htmlStr="<table class='table table-striped'>";
						d=JSON.parse(d);
						$.each(d.carr, function(key, val){ 
							
							htmlStr+="<tr>";
							htmlStr+="<th>"+val.userid+"</th>";
							htmlStr+="<td>"+val.msg+"</td>";
							htmlStr+="<td>"+val.reg_date+"</td>";
							
							if(val.userid == '${sessionScope.userid}'){
								htmlStr+="<td style='width:10%;'><a href='a href='javascript:cdelete("+val.cnum+","+val.bnum+")'><img src='/Tutoring/img/delete.png' style='height:20px; width:20px;'></a></td>";
							}else{
								htmlStr+="<td></td>";
							}
							htmlStr+="</tr>";
						})
							htmlStr+="</table>";
							$("#commentResult").html(htmlStr);
				},
				error: function(e){
					alert("error:"+e);
				}
			})//ajax
		}
	})//commentBtn

 

commentInsert를 거쳐 돌아온 데이터는 JSON 형태로 파싱시켜 $.each로 값을 뿌린다.


WCommentInsertAction.java

(댓글 입력 처리 서블릿. 경로는 "/Tutoring/board/commentInsert"이다.)

 

package com.wboard.action;

import java.io.IOException;
import java.io.PrintWriter;

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.CommentDTO;
import com.wmember.model.WBoardDAO;


/**
 * Servlet implementation class CommentInsertAction
 */
@WebServlet("/board/commentInsert")
public class CommentInsertAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CommentInsertAction() {
        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");
		String msg=request.getParameter("msg");
		int bnum=Integer.parseInt(request.getParameter("num"));
		HttpSession session=request.getSession();
		String userid=(String)session.getAttribute("userid");

		CommentDTO comment=new CommentDTO();
		comment.setBnum(bnum);
		comment.setMsg(msg);
		comment.setUserid(userid);
		WBoardDAO dao=WBoardDAO.getInstance();
		dao.commentInsert(comment);
		//commentList ArrayList에 담아 json으로 리턴
		response.sendRedirect("commentList?num="+bnum);

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

댓글을 입력하고 나면 commentList 페이지로 게시글 번호를 달고 이동한다.

 

 


<WBoardDAO.java의 commentInsert 메소드>

 

//코멘트 추가 commentInsert
	public void commentInsert(CommentDTO comment) {
		Connection con=null;
		PreparedStatement ps=null;
		
		try {
			con=getConnection();
			String sql="insert into wcomment_board(cnum, userid, msg, reg_date, bnum) "
					+ "values(wcomment_board_seq.nextval,?,?,sysdate,?)";
			ps=con.prepareStatement(sql);
			ps.setString(1, comment.getUserid());
			ps.setString(2, comment.getMsg());
			ps.setInt(3, comment.getBnum());
			ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
	}

댓글도 게시글과 마찬가지로 자신이 쓴 댓글이면 삭제 아이콘이 나타난다.

댓글 삭제또한 자바스크립트 함수 링크를 달아서 처리한다.

 

//댓글 삭제 함수
function cdelete(cnum, bnum){
	if(confirm("댓글을 삭제 하시겠습니까?")){
		$.getJSON("/Tutoring/board/cdelete", 
				{"cnum":cnum,"bnum":bnum}, 
				function(d){
					var htmlStr="<table class='table table-striped'>";
					$.each(d.carr, function(key, val){ 
						htmlStr+="<tr>";
						htmlStr+="<th style='width:10%;'>"+val.userid+"</th>";
						htmlStr+="<td style='width:60%;'>"+val.msg+"</td>";
						htmlStr+="<td style='width:20%;'>"+val.reg_date+"</td>";
						
						if(val.userid == '${sessionScope.userid}'){
							htmlStr+="<td style='width:10%;'><a href='javascript:cdelete("+val.cnum+","+val.bnum+")'><img src='/Tutoring/img/delete.png' style='height:20px; width:20px;'></a></td>";
						}else{
							htmlStr+="<td></td>";
						}
						
						htmlStr+="</tr>";
					})
						htmlStr+="</table>";
						$("#commentResult").html(htmlStr);
				}
	)
	}
}

 


CommentDeleteAction.java

(댓글 삭제 처리 서블릿. 경로는 "/Tutoring/board/cdelete"이다.)

 

package com.wboard.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 com.wmember.model.WBoardDAO;

/**
 * Servlet implementation class BoardDeleteAction
 */
@WebServlet("/board/cdelete")
public class CommentDeleteAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CommentDeleteAction() {
        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");
		int cnum=Integer.parseInt(request.getParameter("cnum"));
		int bnum=Integer.parseInt(request.getParameter("bnum"));
		WBoardDAO dao=WBoardDAO.getInstance();
		dao.commentDel(cnum);
		response.sendRedirect("/Tutoring/board/commentList?num="+bnum);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

삭제후에는 게시글번호를 달고 다시 commentList로 이동한다.

 


<WBoardDAO.java의 commentDel 메소드>

 

//댓글 삭제
	public void commentDel(int cnum) {
		Connection con=null;
		Statement st=null;
		try {
			con=getConnection();
			st=con.createStatement();
			String sql="delete from WComment_Board where cnum="+cnum;
			st.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, null);
		}
	}

 


https://github.com/kkj0712/JspProject_Tutoring

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

이전글

https://amongthestar.tistory.com/150

 

JSP 개인프로젝트-영어 학습 사이트 만들기 (강의목록 전체보기, 상세보기)

이전글 (관리자 기능) https://amongthestar.tistory.com/149 JSP 개인프로젝트-영어 학습 사이트 만들기 (관리자 기능) 이전글 (로그인, 회원가입) https://amongthestar.tistory.com/148 JSP 개인프로젝트-영어..

amongthestar.tistory.com


이번에 포스팅할 내용은 수강후기 게시판 전체보기와 게시글 입력이다.

게시글 상세보기 및 수정 삭제, 댓글 입력 삭제는 다음 포스팅에 게시할 예정이다.

 

지금까지 로직 진행은 다음과 같다.

1. 메인 화면에서 세번째 탭에 해당하는 "과정"을 클릭하면 과정 전체목록이 카드 형식으로 보인다.

WClassCourseList.java -> courseList.jsp 로 이동

2. 카드 하나를 클릭하면 해당하는 과정의 상세내용을 볼 수 있다.

WClassCourseDetail.java -> courseDetail.jsp 로 이동

3. 과정의 상세내용 하단에 수강후기 게시판을 볼 수 있다.

 


수강후기 DB관련 DTO (WBoardDTO.java)

package com.wmember.model;

public class WBoardDTO {
	private int num;
	private String userid;
	private String subject;
	private String content;
	private String reg_date;
	private int readcount;
	private int classnum;
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getUserid() {
		return userid == null ? "" : userid.trim();
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getSubject() {
		return subject == null ? "" : subject.trim();
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getContent() {
		return content == null ? "" : content.trim();
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getReg_date() {
		return reg_date == null ? "" : reg_date.trim();
	}
	public void setReg_date(String reg_date) {
		this.reg_date = reg_date;
	}
	public int getReadcount() {
		return readcount;
	}
	public void setReadcount(int readcount) {
		this.readcount = readcount;
	}
	public int getClassnum() {
		return classnum;
	}
	public void setClassnum(int classnum) {
		this.classnum = classnum;
	}
}

 


courseDetail.jsp

 

게시판 영역이다. 검색영역, 글쓰기 버튼, 수강후기 게시판영역으로 이루어져있다.

<!-- 게시판 -->
	<div class="board">
		<br/>
		
		<!-- 검색 시작-->
		<div align="right" id="searchDiv">
		<form name="search" id="search">
			<select name="field" id="field">
				<option value="userid">작성자</option>
				<option value="subject">제목</option>
			</select>
			<input type="text" name="word" id="word">
			<input type="button" value="찾기" id="btnSearch" class="btn btn-outline-secondary btn-sm">
			<a href="#coll"  id="writeBtn" class="btn btn-outline-dark btn-sm" data-toggle="collapse">글쓰기</a>
		</form>
		</div>
		<!-- 검색 끝-->
		
		<!-- 수강후기 게시판 -->
		<div id="result" align="center"></div>
		
		<!-- 글쓰기 폼 영역 -->
		  <div id="coll" class="collapse">
		   <form action="/Tutoring/board/boardinsert" method="post" id="wFrm">
			<br/><br/>
			  <!-- 수강후기 등록하고자 하는 강의 번호 -->
			  <input type="hidden" id="classnum" name="classnum" value="${dto.classnum}">
			  
			  <div class="input-group mb-3"><div class="input-group-prepend">
			      <span class="input-group-text">강의명</span></div>
			      <input type="text" class="form-control" id="classname" name="classname" readonly="readonly" value="${dto.classname}">
			  	  <div class="input-group-prepend"><span class="input-group-text">작성자</span></div>
			      <input type="text" class="form-control" id="userid" name="userid" readonly="readonly" value="${sessionScope.userid}">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3"><div class="input-group-prepend">
			      <span class="input-group-text">제목</span></div>
			      <input type="text" class="form-control" id="subject" name="subject">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3"><div class="input-group-prepend">
			      <span class="input-group-text">내용</span></div>
			      <textarea rows="5" cols="20" class="form-control" id="content" name="content"></textarea>
			  </div>
			  
			  <div class="button">
			 	  <input type="reset" class="btn btn-gray" value="취소">
			 	  <input type="button" class="btn btn-primary" id="send" value="후기등록">
			  </div>
			</form>
		  </div>
		  <!-- 글쓰기 폼 영역  끝-->
	</div>
<!-- 게시판 끝-->

 

수강후기 게시판 영역은 div태그만 있고 내용이 없다. 테이블 태그는 보이지 않는다. 어떻게 구현할까?

페이지가 로드되자 마자 수강후기 리스트를 불러오도록 자바스크립트 함수를 기입한다.

<script>
$(document).ready(function(){
	getData(1, "", "", ${dto.classnum}); //페이지 로드 시 수강후기 리스트 보기
//전체보기 함수
function getData(pageNum, field, word, classnum){
	$.get("/Tutoring/board/boardlist", 
			{"pageNum":pageNum, "field":field, "word":word, "classnum":classnum},
			function(d){
			$("#result").html(d);
	})
}//getData
//검색버튼 클릭
	$("#btnSearch").on("click", function(){
		getData(1, $("#field").val(), $("#word").val(), $("#classnum").val());
	})//btnSearch
  • $.get 함수로 "/Tutoring/board/boardlist"로 이동하고 들고온 값을 result div영역에 뿌린다.

 


WBoardListAction.java

(수강후기 게시판 전체 목록을 가져오는 서블릿. 경로는  "/Tutoring/board/boardlist"이다.)

package com.wboard.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.PageUtil;
import com.wmember.model.WBoardDAO;
import com.wmember.model.WBoardDTO;


/**
 * Servlet implementation class WBoardListAction
 */
@WebServlet("/board/boardlist")
public class WBoardListAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WBoardListAction() {
        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");
		WBoardDAO dao=WBoardDAO.getInstance();
		
		String pageNum=request.getParameter("pageNum")==null? "1":request.getParameter("pageNum");
		int currentPage=Integer.parseInt(pageNum);
		int pageSize=5;
		int startRow=(currentPage-1)*pageSize+1;
		int endRow=currentPage*pageSize;
				
		int count=0;
		String field=request.getParameter("field")==null?"":request.getParameter("field");
		String word=request.getParameter("word")==null?"":request.getParameter("word");
		
		//어떤 강의인지 강의 번호를 가져오기
		String classNumber=request.getParameter("classnum");
		int classnum=Integer.parseInt(classNumber);
		
		//수강후기 개수 출력
		count=dao.getCount(field, word,classnum);
		
		//총페이지 수
		int totPage=(count/pageSize)+(count%pageSize==0?0:1);
		int pageBlock=3;
		int startPage=((currentPage-1)/pageBlock)*pageBlock+1;
		int endPage=startPage+pageBlock-1;
		if(endPage>totPage) endPage=totPage;
		
		PageUtil pu=new PageUtil();
		pu.setCurrentPage(currentPage);
		pu.setEndPage(endPage);
		pu.setPageBlock(pageBlock);
		pu.setStartPage(startPage);
		pu.setTotPage(totPage);
		pu.setField(field);
		pu.setWord(word);
		pu.setClassnum(classnum);
		
		ArrayList<WBoardDTO> arr=null;
		if(word.equals("")) {
			arr=dao.boardList(startRow, endRow, classnum);
		}else {
			arr=dao.boardList(field, word, startRow, endRow, classnum);
		}
		
		int rowNo=count-((currentPage-1)*pageSize); //매 페이지의 시작번호
		
		request.setAttribute("rowNo", rowNo);
		request.setAttribute("pu", pu);
		request.setAttribute("board", arr);
		request.setAttribute("count", count);
		
		RequestDispatcher rd=request.getRequestDispatcher("listResult.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);
	}

}

 

관리자 페이지에서 강의목록을 내보냈던 것과 마찬가지로 페이징, 전체 게시글 수, 게시글 목록을 request 객체를 이용해 listResult.jsp로 내보낸다. 

 

 


 

PageUtil.java 내용은 앞서 관리자 기능에 대해 소개한 포스팅에 나와있다.

 


<WBoard.java의 boardList 메소드>(검색이 아닐때)

 

//검색 아닌 전체보기
	public ArrayList<WBoardDTO> boardList(int startRow, int endRow, int classnum) {
		Connection con=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		ArrayList<WBoardDTO>arr=new ArrayList<WBoardDTO>();
		
		try {
			con=getConnection();
			StringBuilder sb=new StringBuilder();
			sb.append(" select * from");
			sb.append(" (select aa.*, rownum rn from");
			sb.append(" (select * from WBoard where classnum="+classnum);
			sb.append(" order by num desc) aa");
			sb.append(" where rownum<=?) where rn>=?");
			ps=con.prepareStatement(sb.toString());
			ps.setInt(1, endRow);
			ps.setInt(2, startRow);
			rs=ps.executeQuery();
			while(rs.next()) {
				WBoardDTO dto=new WBoardDTO();
				dto.setNum(rs.getInt("num"));
				dto.setContent(rs.getString("content"));
				dto.setReadcount(rs.getInt("readcount"));
				dto.setReg_date(rs.getString("reg_date"));
				dto.setSubject(rs.getString("subject"));
				dto.setUserid(rs.getString("userid"));
				dto.setClassnum(rs.getInt("classnum"));
				arr.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps, rs);
		}
		return arr;
	}

 

더보기

이때 SQL문이 헷갈려서 고생을 했다.. (좀 막혔던 부분들을 생각해보면 다 전체목록 보기에 관한 기능 구현에 관해서다..)

지금까지 전체 목록을 볼때는 검색한 결과인지 아닌지만 가르면 됐는데, 지금의 수강후기 게시판은 "특정 강의에 대한" 수강후기라는 단서가 붙는다.

 

그래서 처음엔 바깥에 select를 한번 더 감싸고 where classnum=강의번호; 라고 조건절을 줬고 그 select문 안에서 rn을 미리 부여해놓고 5에서 10사이, 10에서 15사이 이런식으로 골라냈었다. 당연히 1페이지에는 2개, 2페이지에는 5개 이렇게 오류가 날 수 밖에 없었다. (사실 오류가 아니고 당연한 결과다.) 

 

하지만 강의 페이지별로 수강후기 DB가 따로 있는게 아니고 전체 수강후기 DB에서 강의번호 별로 골라낸다.

 

따라서 바깥 select를 지우고, rownum where 절이 아닌 select * from wboard 뒤에 where classnum이라는 조건절을 추가해야한다. 즉 미리 classnum을 골라내고 rn을 계산해야하는 것이다.


<WBoard.java의 boardList 메소드>(검색일때)

 

//검색 전체보기
	public ArrayList<WBoardDTO> boardList(String field, String word, int startRow, int endRow, int classnum) {
		Connection con=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		ArrayList<WBoardDTO>arr=new ArrayList<WBoardDTO>();
		
		try {
			con=getConnection();
			StringBuilder sb=new StringBuilder();
			sb.append(" select * from");
			sb.append(" (select aa.*, rownum rn from");
			sb.append(" (select * from WBoard where classnum="+classnum);
			sb.append(" and upper ("+field+") like upper ('%"+word+"%')");
			sb.append(" order by num desc) aa");
			sb.append(" where rownum<=?) where rn>=?");
			ps=con.prepareStatement(sb.toString());
			ps.setInt(1, endRow);
			ps.setInt(2, startRow);
			rs=ps.executeQuery();
			while(rs.next()) {
				WBoardDTO dto=new WBoardDTO();
				dto.setNum(rs.getInt("num"));
				dto.setContent(rs.getString("content"));
				dto.setReadcount(rs.getInt("readcount"));
				dto.setReg_date(rs.getString("reg_date"));
				dto.setSubject(rs.getString("subject"));
				dto.setUserid(rs.getString("userid"));
				dto.setClassnum(rs.getInt("classnum"));
				arr.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps, rs);
		}
		return arr;
	}

 


<WBoard.java의 getCount 메소드>

 

//게시물수 출력
	public int getCount(String field, String word, int classnum) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		int count=0;
		String sql="";
		
		try {
			con=getConnection();
			st=con.createStatement();
			if(word.equals("")) {
				sql="select count(*) from WBoard where classnum="+classnum;
			}else {
				sql="select count(*) from WBoard where upper ("+field+") like upper ('%"+word+"%') and classnum="+classnum;
			}
			rs=st.executeQuery(sql);
			if(rs.next()) {
				count=rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return count;
	}

listResult.jsp

WBoardListAction.java에서 내보내진 값을 board란 이름에 담아서 뿌린다. 페이징 영역도 포함하고 있다.

그런데 courseDetail.jsp->WBoardListAction.java->listResult.jsp로 이동된 것이므로 $.get의 콜백함수에 의해 이 값들이 courseDetail.jap의 result div에 뿌려지게 된다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<body>
<h5 style="text-align: left"><span id="cntSpan">수강후기(${count}</span>)</h5>
<table class="table table-hover table-bordered table-sm">
	<thead>
		<tr>
			<th style="width: 8%">글번호</th>
			<th style="width: 13%">작성자</th>
			<th>제목</th>
			<th style="width: 8%">작성일</th>
			<th style="width: 7%">조회수</th>
		</tr>
	</thead>
	<tbody>
		<c:forEach items="${board}" var="board" varStatus="st">
		<tr>
			<td>${rowNo-st.index}</td>
			<td>${board.userid}</td>
			<td><a href="/Tutoring/board/boardDetail?num=${board.num}">${board.subject}</a></td>
			<td>${board.reg_date}</td>
			<td>${board.readcount}</td>
		</tr>
		</c:forEach>
	</tbody>
</table>
<div align="center">
	<c:if test="${pu.startPage>pu.pageBlock}"> <!-- 이전 -->
		<a href="javascript:getData(${pu.startPage-pu.pageBlock},'${pu.field}','${pu.word}', ${pu.classnum})">[이전]</a>
	</c:if>
	<c:forEach begin="${pu.startPage}" end="${pu.endPage}" var="i"><!-- 페이지 출력 -->
		<c:if test="${i==pu.currentPage}"> <!-- 현재 페이지 -->
			<c:out value="${i}"/>
		</c:if>
		<c:if test="${i!=pu.currentPage}"> <!-- 현재 페이지 아닌 경우 링크 부여-->
			<a href="javascript:getData(${i},'${pu.field}','${pu.word}', ${pu.classnum})">${i}</a>
		</c:if>
	</c:forEach>
	<c:if test="${pu.endPage<pu.totPage}"> <!-- 다음-->
		<a href="javascript:getData(${pu.endPage+1},'${pu.field}','${pu.word}', ${pu.classnum})">[다음]</a>
	</c:if>
</div>
</body>
</html>

 


다음은 수강후기 글쓰기에 대한 내용이다.

지금까지는 로그인 없이 볼 수 있는 내용들이었지만 수강후기를 쓰려고 하면 로그인을 해야한다.

글쓰기 버튼을 누르면 숨어있던 글쓰기 폼이 나타난다. 부트스트랩의 collapse 클래스를 이용했다.

courseDetail.jsp 내에 글쓰기 폼이 있으므로 후기등록 버튼을 눌렀을때 실행되는 자바스크립트 함수도 이곳에 적어준다.

 

 

courseDetail.jsp 내의 글쓰기 폼 영역

 

//후기등록 버튼 클릭
	$("#send").click(function(){ //후기등록 버튼 클릭
         if(${sessionScope.userid==null}){
              alert("로그인 필요");
              location.href="/Tutoring/member/login";
         }else{
	       	 	var classnum=$("#classnum").val();
				var userid=$("#userid").val();
				var content=$("#content").val();
				var subject=$("#subject").val();
				var postString="classnum="+classnum+"&userid="+userid+"&content="+content+"&subject="+subject;
	            $.ajax({
	                  type:    "post",
	                  url :    "/Tutoring/board/boardinsert",
	                  data:    postString,
	                  success:function(d){
	                	   alert("후기가 등록되었습니다!");
	                	   $("#result").html(d);
	                       document.getElementById("wFrm").reset();
	                  },
	                  beforeSend: showRequest, //빈칸 확인
	                  error: function(e){
	                       alert("error:"+e);
	                  }
	            })//ajax
         }
     })//send
}); //document ready
//빈칸확인 함수
function showRequest(){
	if($("#subject").val()==""){
		alert("제목을 입력하세요");
		$("#subject").focus();
		return false;
	}
	if($("#content").val()==""){
		alert("내용을 입력하세요");
		$("#content").focus();
		return false;
	}
	return true;
}

 

로그인을 하지 않았을 경우 alert창을 띄우고 login화면으로 넘어간다.

로그인을 한 경우 $.ajax을 이용하여 비동기방식으로 수강후기가 입력되며, 새로고침을 하지 않아도 수강후기 화면이 업데이트 된다. 

 


WBoardInsertAction.java

($.ajax를 통해 넘어온 수강후기 입력 서블릿. 경로는 "/Tutoring/board/boardinsert"이다.)

 

package com.wboard.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 com.wmember.model.WBoardDAO;
import com.wmember.model.WBoardDTO;


/**
 * Servlet implementation class BoardInsertAction
 */
@WebServlet("/board/boardinsert")
public class WBoardInsertAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WBoardInsertAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		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 {
		request.setCharacterEncoding("utf-8");
		WBoardDTO board=new WBoardDTO();
		board.setClassnum(Integer.parseInt(request.getParameter("classnum")));
		board.setUserid(request.getParameter("userid"));
		board.setSubject(request.getParameter("subject"));
		board.setContent(request.getParameter("content"));
		WBoardDAO dao=WBoardDAO.getInstance();
		
		int classNumber=Integer.parseInt(request.getParameter("classnum"));
		int flag=0;
		flag=dao.boardInsert(board);

		if(flag==1){
			response.sendRedirect("/Tutoring/class/CourseDetail?num="+classNumber);
		}
	}
}

 

WBoardDAO.java의 boardInsert메소드를 수행하여 수강후기가 입력되었으면 return된 flag 값을 받아오고 1일 경우 다시 CourseDetail로 넘어간다. 수강후기가 해당되는 강의 상세보기로 넘어가므로 num값을 미리 받아와야한다.

 

 


<WBoardDAO.java의 boardInsert메소드>

 

//디비셋팅
	private static WBoardDAO instance=new WBoardDAO();
	public static WBoardDAO getInstance() {
		return instance;
	}
	private Connection getConnection() throws Exception{
		Context initCtx=new InitialContext();
		Context envCtx=(Context) initCtx.lookup("java:comp/env");
		DataSource ds=(DataSource) envCtx.lookup("jdbc/wiser");
		return ds.getConnection();
	}
	
	//게시물등록
	public int boardInsert(WBoardDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		int flag=0;
		
		try {
			con=getConnection();
			String sql="INSERT INTO WBoard(num, userid, subject, content, reg_date, "
					+ "readcount, classnum)"
					+ "VALUES(WBoard_seq.nextval,?,?,?,sysdate,0,?)";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getUserid());
			ps.setString(2, vo.getSubject());
			ps.setString(3, vo.getContent());
			ps.setInt(4, vo.getClassnum());
			flag=ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
		return flag;
	}
    
    //닫기 closeConnection
	private void closeConnection(Connection con, PreparedStatement ps) {
		try {
			if(ps!=null) ps.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}
	private void closeConnection(Connection con, Statement st, ResultSet rs) {
		try {
			if(st!=null) st.close();
			if(con!=null) con.close();
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

 

courseDetail의 $.ajax으로 다시 돌아가면 result영역에 수강후기 게시판이 업데이트되어 나타난다. 


게시글 상세보기 및 수정 삭제, 댓글과 관련된 포스팅은 다음에 하겠다.

 

https://github.com/kkj0712/JspProject_Tutoring

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

이전글 (관리자 기능)

https://amongthestar.tistory.com/149

 

JSP 개인프로젝트-영어 학습 사이트 만들기 (관리자 기능)

이전글 (로그인, 회원가입) https://amongthestar.tistory.com/148 JSP 개인프로젝트-영어 학습 사이트 만들기 (로그인, 회원가입) 학원에서 일주일간 JSP로 개인프로젝트를 했다. 주제는 영어 학습 사이트. ��

amongthestar.tistory.com


이번에 포스팅할 내용은 회원 비회원 상관없이 볼 수 있는 소개화면과 강의목록화면, 관련 기능구현이다.

시작페이지에서 두번째 탭은 "와이저"라 명명했다. 이 사이트에 대해 간략하게 소개하는 페이지이다.

 

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

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

이전글 (로그인, 회원가입)

https://amongthestar.tistory.com/148

 

JSP 개인프로젝트-영어 학습 사이트 만들기 (로그인, 회원가입)

학원에서 일주일간 JSP로 개인프로젝트를 했다. 주제는 영어 학습 사이트. 벤치마킹?할 사이트는 캠블리로 선정했다. 강의 구매와 튜터 매칭 시스템, 캘린더에서 날짜를 골라서 수업을 듣는 기능

amongthestar.tistory.com

 


회원가입시 admin 컬럼의 값을 무조건 0으로 주고 DB에서 관리자를 선정하여 admin 값을 1로 고친다.

이번 포스팅은 관리자가 로그인했을 경우 어떤 기능들을 수행할 수 있는지에 대한 내용이다.

 

관리자로 로그인을 하면 먼저 관리자 페이지로 이동한다.

 


<login.jsp 중 ajax 부분>

 

$.ajax({
		type : "post",
		url  : "login",
		data : {"userid":$("#userid").val(), "pwd":$("#pwd").val()},
		success : function(value){
			switch(value.trim()){
			case "0" : alert("로그인 성공"); location.href="/Tutoring/index.jsp"; break;
			case "1" : alert("관리자 로그인"); location.href="/Tutoring/member/Adminview"; break;
			case "2" : alert("비밀번호 오류"); break;
			case "-1": alert("회원이 아닙니다"); location.href="/Tutoring/member/insert"; break;
			default: alert(value.trim());
			}
		},
		error: function(e){
			alert("error:"+e);
		}
	})

 


WMemberAdminViewAction.java

(관리자 화면으로 이동하는 서블릿으로 "/Tutoring/member/AdminView" 경로에 해당한다.)

 

package com.wmember.action;

import java.io.IOException;

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.WMemberDAO;
import com.wmember.model.WMemberDTO;

/**
 * Servlet implementation class WMemberAdminViewAction
 */
@WebServlet("/member/Adminview")
public class WMemberAdminViewAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberAdminViewAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session=request.getSession();
		String userid=(String)session.getAttribute("userid");
		WMemberDAO dao=WMemberDAO.getInstance();
		WMemberDTO dto=dao.memberView(userid);
		request.setAttribute("member", dto);
		
		RequestDispatcher rd=request.getRequestDispatcher("Adminview.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

 

  • a href로 이동하였으므로 doGet 내에서 처리되며 doPost에는 내용이 없다.
  • 로그인으로 인해 생긴 seesion userid값으로 WMemberDAO.java의 memberVIew 메소드를 실행한다.
  • WMemberDTO형의 dto 객체에 member라는 이름으로 담고 AdminView.jsp로 이동한다. 자신의 회원정보를 수정할 수 있는 화면이다.

<WMemberDAO.java의 memberView 메소드)>

 

//회원 상세보기
	public WMemberDTO memberView(String userid) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		WMemberDTO dto=null;
		try {
			con=getConnection();
			String sql="select * from wmember where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			if(rs.next()) {
				dto=new WMemberDTO();
				dto.setNum(rs.getInt("num"));
				dto.setEmail(rs.getString("email"));
				dto.setName(rs.getString("name"));
				dto.setPwd(rs.getString("pwd"));
				dto.setUserid(rs.getString("userid"));
				dto.setAddress(rs.getString("address"));
				dto.setPostcode(rs.getInt("postcode"));
				dto.setDetailAddress(rs.getString("detailaddress"));
				dto.setExtraAddress(rs.getString("extraaddress"));
				dto.setAdmin(rs.getInt("admin"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return dto;
	}

 

 


AdminView.jsp

회원가입할때 폼 양식과 똑같다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
a{
	text-decoration: none;
}
a:hover{
	text-decoration: none;
}
.back2{
	margin-top: 20px;
	background-color: #f8f9fa;
	border-radius: 20px;
}
#frm{
	margin: 0 auto;
	width: 50%;
}
.button{
	text-align: center;
	margin: 0 auto;
	padding: 20px;
}
.sidebar{
	float: left;
	width: 200px;
	height:200px;
	margin-top: 60px;
	margin-left: 60px;
}
.sidebar ul{
	list-style: none;
}
.sidebar ul a{
	line-height: 2em;
}
</style>

<aside class="sidebar">
	<ul id="menu">
        <li><h5><a href="/Tutoring/class/ClassInsert.jsp"> 강의입력</a></h5></li>
        <li><h5><a href="/Tutoring/class/ClassList.jsp"> 강의목록</a></h5></li>
        <li><h5><a href="/Tutoring/member/Adminview"> 계정설정</a></h5></li>
	</ul>
</aside>

<div class="container" id="userInfo">
<br/>
<h5>계정설정</h5>
<div class="back2">
<form action="Adminupdate" method="post" id="frm">
  <br/><br/>
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">아이디</span>
    </div>
      <input type="text" class="form-control" name="userid" id="userid" value="${member.userid}" readonly="readonly">
  </div>
  <br/>
   
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">이름</span>
    </div>
    <input type="text" class="form-control" id="name" value="${member.name}" name="name">
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">비밀번호</span>
    </div>
    <input type="password" class="form-control" id="pwd" value="${member.pwd}" name="pwd">
  	<input type="password" class="form-control" placeholder="비밀번호 확인" id="pwd_check" name="pwd_check">
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">이메일</span>
    </div>
    <input type="text" class="form-control" id="email" value="${member.email}" name="email">
  </div>
  <br/>
    
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">우편번호</span>
    </div>
      <input type="text" id="sample6_postcode" name="sample6_postcode" value="${member.postcode}" readonly="readonly" class="form-control">
    <div class="col align-self-end" >
      <input type="button" onclick="sample6_execDaumPostcode()" value="우편번호" class="btn btn-secondary"><br>
   	</div>
  </div>
  <br/>  

  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">주소</span>
    </div>
    <input type="text" id="sample6_address" name="sample6_address" value="${member.address}" placeholder="주소" class="form-control"><br>
  </div>

  <div class="input-group mb-3">
	<input type="text" id="sample6_detailAddress" name="sample6_detailAddress" value="${member.detailAddress}" placeholder="상세주소" class="form-control">
	<input type="text" id="sample6_extraAddress" name="sample6_extraAddress" value="${member.extraAddress}" placeholder="참고항목" class="form-control">
  </div>
  <div class="button">
  	<button  id="send"  class="btn btn-info">저장</button>
	<input type="button" class="btn btn-danger" value="회원탈퇴" onclick="delCheck('${member.userid}')">
  </div>
</form>
</div>

</div>
<br/><br/>
<%@ include file="../include/footer.jsp" %>
<script>
function delCheck(userid){
    if(confirm("탈퇴하시겠습니까? 삭제된 회원정보는 되돌릴 수 없습니다.")){
    	location.href="delete?userid="+userid;
    }
}
</script>
<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    function sample6_execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
                if(data.userSelectedType === 'R'){
                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있고, 공동주택일 경우 추가한다.
                    if(data.buildingName !== '' && data.apartment === 'Y'){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                    if(extraAddr !== ''){
                        extraAddr = ' (' + extraAddr + ')';
                    }
                    // 조합된 참고항목을 해당 필드에 넣는다.
                    document.getElementById("sample6_extraAddress").value = extraAddr;
                
                } else {
                    document.getElementById("sample6_extraAddress").value = '';
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('sample6_postcode').value = data.zonecode;
                document.getElementById("sample6_address").value = addr;
                // 커서를 상세주소 필드로 이동한다.
                document.getElementById("sample6_detailAddress").focus();
            }
        }).open();
    }
</script>
<script>
var reg_email = /^([0-9a-zA-Z_\.-]+)@([0-9a-zA-Z_-]+)(\.[0-9a-zA-Z_-]+){1,2}$/;
$(document).ready(function(){
	$("#send").click(function(){
		//이름이 공백일때
		if($("#name").val()==""){
			alert("이름을 입력하세요");
			return false;
		}
		//암호가 공백일때
		if($("#pwd").val()==""){
			alert("암호를 입력하세요");
			$("#pwd").focus();
			return false;
		}
		//암호확인이 공백일때
		if($("#pwd_check").val()==""){
			alert("암호확인 필수");
			$("#pwd_check").focus();
			return false;
		}
		//암호 일치확인
		if($("#pwd").val()!=$("#pwd_check").val()){
			alert("암호 불일치");
			$("#pwd_check").focus();
			return false;
		}
		if($("#pwd").val().length<6){
	        alert("비밀번호는 6글자 이상이어야 합니다.");
	        pw1.value="";
	        pw1.focus();
	    }
		//이메일이 공백일때
		if($("#email").val()==""){
			alert("이메일을 입력하세요");
			return false;
		}
		//이메일 양식
		if(!$("#email").val().match(reg_email)){
			alert("이메일을 정확하게 입력하세요");
			$("#email").focus();
			return false;
		}
		$("#frm").submit();
	})//send
});//document
</script>

 

  • 주소를 고칠 수 있도록 다음 우편번호 API 자바스크립트 코드를 붙여넣었다.
  • 저장버튼을 누르면 form이 post방식으로 Adminupdate로 이동한다.
  • 삭제버튼을 누르면 자바스크립트 delCheck 함수로 이동하고 userid값을 가지고 delete로 이동한다.

 


WMemberAdminUpdateAction.java 

("저장"버튼을 눌렀을때 회원정보 수정할 수 있는 서블릿. 경로는 "/Tutoring/member/Adminupdate"에 해당)

package com.wmember.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.WMemberDAO;
import com.wmember.model.WMemberDTO;


/**
 * Servlet implementation class MemberUpdate
 */
@WebServlet("/member/Adminupdate")
public class WMemberUpdateAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberUpdateAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WMemberDTO member=new WMemberDTO();
		member.setName(request.getParameter("name"));
		member.setUserid(request.getParameter("userid"));
		member.setPwd(request.getParameter("pwd"));
		member.setEmail(request.getParameter("email"));
		member.setPostcode(Integer.parseInt(request.getParameter("sample6_postcode")));
		member.setAddress(request.getParameter("sample6_address"));
		member.setDetailAddress(request.getParameter("sample6_detailAddress"));
		member.setExtraAddress(request.getParameter("sample6_extraAddress"));
		
		WMemberDAO dao=WMemberDAO.getInstance();
		int flag=dao.memberUpdate(member);
		if(flag==1) {
			response.sendRedirect("/Tutoring/member/Adminview");
		}

	}
}

 

  • member객체에 파라미터 값으로 받아온 변수들을 저장하고 WMemberDAO.java의 memberUpdate메소드를 실행
  • 업데이트가 여부에 따라 flag 변수 값을 달리하고, 업데이트가 되었다면 상세정보 화면으로 다시 이동

 


 

<WMemberDAO.java의 memberUpdate메소드>

 

//회원정보 수정
	public int memberUpdate(WMemberDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		int flag=0;
		try {
			con=getConnection();
			String sql="update wmember set name=?, pwd=?, email=?, postcode=?, address=?, detailaddress=?, extraaddress=? where userid=?";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getName());
			ps.setString(2, vo.getPwd());
			ps.setString(3, vo.getEmail());
			ps.setInt(4, vo.getPostcode());
			ps.setString(5, vo.getAddress());
			ps.setString(6, vo.getDetailAddress());
			ps.setString(7, vo.getExtraAddress());
			ps.setString(8, vo.getUserid());
			flag=ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
		return flag;
	}

 

 


WMemberDeleteAction.java

("회원탈퇴"버튼을 눌렀을때 회원정보를 삭제할 수 있는 서블릿. 경로는 "/Tutoring/member/delete"에 해당)

 

package com.wmember.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 javax.servlet.http.HttpSession;
import com.wmember.model.WMemberDAO;


/**
 * Servlet implementation class MemberDelete
 */
@WebServlet("/member/delete")
public class WMemberDeleteAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberDeleteAction() {
        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");
		String userid=request.getParameter("userid");
		WMemberDAO dao=WMemberDAO.getInstance();
		dao.memberDel(userid);
		HttpSession session=request.getSession();
		session.invalidate();
		response.sendRedirect("login");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request,response);
	}
}

 

  • 파라미터 값으로 받아온 userid를 이용하여 WMemberDAO.java의 memberDel 메소드를 수행한다.

<WMemberDAO.java의 memberDel 메소드>

 

//삭제
	public void memberDel(String userid) {
		Connection con=null;
		Statement st=null;
		try {
			con=getConnection();
			String sql="delete from wmember where userid='"+userid+"'";
			st=con.createStatement();
			st.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, null);
		}
	}

 


관리자로 로그인을 하면 계정설정 외에도 강의입력과 강의목록 탭이 보인다. 각각 jsp로 링크를 걸었다.

강의에 관련된 작업은 DB의 WClass 테이블을 활용한다.

 

강의 DB관련 DTO (WClassDTO.java)

package com.wmember.model;

public class WClassDTO {
	private String clevel;
	private int classnum;
	private String classname;
	private int stu_num;
	private String stu_regdate;
	private String topic;
	private String content;
	private String uploadFile;
	
	public String getUploadFile() {
		return uploadFile == null ? "" : uploadFile.trim();
	}
	public void setUploadFile(String uploadFile) {
		this.uploadFile = uploadFile;
	}
	public String getClevel() {
		return clevel == null ? "" : clevel.trim();
	}
	public void setClevel(String clevel) {
		this.clevel = clevel;
	}
	public int getClassnum() {
		return classnum;
	}
	public void setClassnum(int classnum) {
		this.classnum = classnum;
	}
	public String getClassname() {
		return classname == null ? "" : classname.trim();
	}
	public void setClassname(String classname) {
		this.classname = classname;
	}
	public int getStu_num() {
		return stu_num;
	}
	public void setStu_num(int stu_num) {
		this.stu_num = stu_num;
	}
	public String getStu_regdate() {
		return stu_regdate == null ? "" : stu_regdate.trim();
	}
	public void setStu_regdate(String stu_regdate) {
		this.stu_regdate = stu_regdate;
	}
	public String getTopic() {
		return topic == null ? "" : topic.trim();
	}
	public void setTopic(String topic) {
		this.topic = topic;
	}
	public String getContent() {
		return content == null ? "" : content.trim();
	}
	public void setContent(String content) {
		this.content = content;
	}
}

 


ClassInsert.jsp

강의 입력폼

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
a{
	text-decoration: none;
}
a:hover{
	text-decoration: none;
}
.back2{
	margin-top: 20px;
	background-color: #f8f9fa;
	border-radius: 20px;
}
#frm{
	margin: 0 auto;
	width: 50%;
}
.button{
	text-align: center;
	margin: 0 auto;
	padding: 20px;
}
.sidebar{
	float: left;
	width: 200px;
	height:200px;
	margin-top: 60px;
	margin-left: 60px;
}
.sidebar ul{
	list-style: none;
}
.sidebar ul a{
	line-height: 2em;
}
.thumb-image{
 float:left;
 width:200px;
 position:relative;
 padding:5px;
}
</style>
<aside class="sidebar">
	<ul id="menu">
        <li><h5><a href="/Tutoring/class/ClassInsert"> 강의입력</a></h5></li>
        <li><h5><a href="/Tutoring/class/ClassList.jsp"> 강의목록</a></h5></li>
        <li><h5><a href="/Tutoring/member/Adminview"> 계정설정</a></h5></li>
	</ul>
</aside>
<div class="container">
<br/>
<h5>강의입력</h5>
<div class="back2">
<form action="ClassInsert" method="post" id="frm" enctype="multipart/form-data">
  <br/><br/>
  	<div id="image-holder"></div>
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의 이미지</span>
    </div>
      <input type="file" class="form-control" id="uploadFile" name="uploadFile"><br>
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의분류</span>
    </div>
      <select name="clevel" id="clevel" name="clevel">
      	<option value="basic" class="form-control">유창한 영어의 기본 요소</option>
      	<option value="career" class="form-control">경력 개발</option>
      	<option value="expression" class="form-control">자신을 표현해보세요</option>
      	<option value="test" class="form-control">시험 준비</option>
      </select>
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의명</span>
    </div>
      <input type="text" class="form-control" id="classname" name="classname">
  </div>
  <br/>
   
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의 주제</span>
    </div>
      <input type="text" class="form-control" id="topic" name="topic">
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의설명</span>
    </div>
      <textarea rows="5" cols="20" class="form-control" id="content" name="content"></textarea>
  </div>
  
  <div class="button">
 	  <input type="reset" class="btn btn-gray" value="취소">
 	  <button  id="send"  class="btn btn-primary">강의등록</button>
  </div>
</form>
</div>
</div>
<br/><br/>
<%@ include file="../include/footer.jsp" %>
<script>
$(document).ready(function(){
	$("#send").click(function(){
		if($("#classname").val()==""){
			alert("강의명을 입력하세요");
			$("#classname").focus();
			return false;
		}
		if($("#topic").val()==""){
			alert("강의주제를 입력하세요");
			$("#topic").focus();
			return false;
		}
		if($("#content").val()==""){
			alert("강의설명을 입력하세요");
			$("#content").focus();
			return false;
		}
		$("#frm").submit();
	})//send
	$("#uploadFile").on('change', function () {
        if (typeof (FileReader) != "undefined") {
            var image_holder = $("#image-holder");
            image_holder.empty();
            var reader = new FileReader();
            reader.onload = function (e) {
                $("<img />", {
                    "src": e.target.result,
                    "class": "thumb-image"
                }).appendTo(image_holder);
            }
            image_holder.show();
            reader.readAsDataURL($(this)[0].files[0]);
        } else {
            alert("이 브라우저에서 지원하지 않는 확장자 입니다.");
        }
    });
});//document
</script>

 

  • 입력 후 send 버튼을 누르면 form이 ClassInsert로 이동한다.
  • 강의 이미지를 넣어야하기 때문에 form태그 안에 enctype="multipart/form-data" 를 추가하였다.
  • 이미지 입력 프리뷰는 javascript image preview를 구글링하여 복사 붙여넣기 했다.

 

(이미지는 freepic.com에서 찾았다.)


WClassInsertAction.java 

(강의입력 폼에서 넘어온 서블릿. 경로는 "/Tutoring/class/ClassInsert" 이다.)

 

package com.wclass.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.wmember.model.WClassDAO;
import com.wmember.model.WClassDTO;
import com.wmember.model.WMemberDAO;
import com.wmember.model.WMemberDTO;

/**
 * Servlet implementation class WClassInsertAction
 */
@WebServlet("/class/ClassInsert")
public class WClassInsertAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WClassInsertAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("ClassInsert.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WClassDAO dao=WClassDAO.getInstance();
		int uploadFileSizeLimit=5*1024*1024;
		String encType="UTF-8";
		String savePath="upload";
		ServletContext context=getServletContext();
		String uploadFilePath=context.getRealPath(savePath);
		
		//multipart/form 방식은 request.getParameter로 받아올 수 없음
		MultipartRequest multi=new MultipartRequest(
				request, //request객체
				uploadFilePath, //서버상의 실제 디렉토리
				uploadFileSizeLimit, //최대 업로드 파일 크기
				encType, //인코딩 방법
				new DefaultFileRenamePolicy()); //동일 파일 새이름 부여
		
		//업로드된 파일이름 구하기
		String fileName=multi.getFilesystemName("uploadFile");
		
		if(fileName==null) { //파일 업로드 안됨
			System.out.println("파일 업로드 되지 않았음");
		}
		
		WClassDTO wclass=new WClassDTO();
		wclass.setUploadFile(fileName);
		wclass.setClassname(multi.getParameter("classname"));
		wclass.setClevel(multi.getParameter("clevel"));
		wclass.setContent(multi.getParameter("content"));
		wclass.setTopic(multi.getParameter("topic"));
		
		int flag=dao.classInsert(wclass);
		if(flag==1) {
			response.setContentType("text/html; charset=utf-8");
			PrintWriter out = response.getWriter();
			out.println("<script>");
			out.println("alert('강의가 등록되었습니다');");
			out.println("history.back(-1);");
			out.println("</script>");
		}
	}

}

 

  • multipart로 값들을 받아왔기 때문에 request 파라미터로 받아올 수 없다.
  • 업로드한 이미지의 파일 이름을 구하고 wclass 객체에 담는다. 
  • WClassDAO.java의 classInsert 메소드를 수행하고 입력이 되었다면 return 된 flag 값을 판단하여 alert창을 띄운다.
  • 여기서 오류가 많이 났는데.. 이유는 WClassDTO의 객체 이름을 처음에 class로 설정했었기 때문이다. 예약어로 변수명을 설정할 수 없다. 

<WClassDAO.java의 classInsert 메소드>

 

//디비셋팅
	private static WClassDAO instance=new WClassDAO();
	public static WClassDAO getInstance() {
		return instance;
	}
	private Connection getConnection() throws Exception{
		Context initCtx=new InitialContext();
		Context envCtx=(Context) initCtx.lookup("java:comp/env");
		DataSource ds=(DataSource) envCtx.lookup("jdbc/wiser");
		return ds.getConnection();
	}
	
	//강의등록
	public int classInsert(WClassDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		int flag=0;
		
		try {
			con=getConnection();
			String sql="INSERT INTO wclass(classnum, classname, stu_num, stu_regdate, topic, content, "
					+ "clevel, uploadfile)"
					+ "VALUES(wclass_seq.nextval,?,0,0,?,?,?,?)";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getClassname());
			ps.setString(2, vo.getTopic());
			ps.setString(3, vo.getContent());
			ps.setString(4, vo.getClevel());
			ps.setString(5, vo.getUploadFile());
			flag=ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
		return flag;
	}
    
    //닫기 closeConnection
	private void closeConnection(Connection con, PreparedStatement ps) {
		try {
			if(ps!=null) ps.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}
	private void closeConnection(Connection con, Statement st, ResultSet rs) {
		try {
			if(st!=null) st.close();
			if(con!=null) con.close();
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

 

 


강의목록 탭을 클릭하면 ClassList.jsp으로 이동한다.

 

 

ClassList.jsp

  • 강의목록에 관련된 jsp는 ClassList.jsp와 ClassListResult.jsp로 jsp로 나뉜다.
  • ClassList.jsp는 $.get 방식으로 WClassListAction.java에서 받아온 강의목록을 정해진 영역에 뿌려주는 기능과, 검색 영역을 포함하고 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/include/header.jsp" %>
<script>
$(document).ready(function(){
	getData(1,"","");
	$("#btnSearch").on("click",function(){//검색버튼 클릭
		getData(1,$("#field").val(),$("#word").val());
	})
})//document
function getData(pageNum, field, word){
	$.get("ClassList",
		  {"pageNum":pageNum, "field":field, "word":word}, 
		  function(d){
		  $("#result").html(d);
	})
}
</script>
</head>
<body>
<div id="result"></div>
<div align = "center">
<form name = "search" id = "search" class="selectpicker" data-live-search="true">
	<select name = "field" id = "field">
		<option value = "classname">강의명</option>
	</select>
	<input type = "text" name = "word" id = "word">
	<input type = "button" value = "검색" id = "btnSearch"> 
</form>
</div>
<br/>
</body>
</html>
<%@ include file="/include/footer.jsp" %>

 


WClassListAction.java

(ClassList.jsp와 ClassListResult.jsp로 값을 넘기는 서블릿. 경로는 "/Tutoring/class/classList"이다.)

 

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.PageUtil;
import com.wmember.model.WClassDAO;
import com.wmember.model.WClassDTO;

/**
 * Servlet implementation class WClassListAction
 */
@WebServlet("/class/ClassList")
public class WClassListAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WClassListAction() {
        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();
		
		String pageNum=request.getParameter("pageNum")==null? "1":request.getParameter("pageNum");
		int currentPage=Integer.parseInt(pageNum);
		int pageSize=5;
		int startRow=(currentPage-1)*pageSize+1;
		int endRow=currentPage*pageSize;
		
		int count=0;
		String field=request.getParameter("field")==null? "":request.getParameter("field");
		String word=request.getParameter("word")==null? "":request.getParameter("word");
		count=dao.getCount(field,word);
		
		int totPage=(count/pageSize)+(count%pageSize==0?0:1);
		int pageBlock=3;
		int startPage=((currentPage-1)/pageBlock)*pageBlock+1;
		int endPage=startPage+pageBlock-1;
		if(endPage>totPage) endPage=totPage;
		
		PageUtil pu=new PageUtil();
		pu.setCurrentPage(currentPage);
		pu.setEndPage(endPage);
		pu.setField(field);
		pu.setPageBlock(pageBlock);
		pu.setStartPage(startPage);
		pu.setTotPage(totPage);
		pu.setWord(word);
		
		ArrayList<WClassDTO> arr=null;
		if(word.equals("")) {
			arr=dao.classList(startRow,endRow);
		}else {
			arr=dao.classList(field, word, startRow, endRow);
		}
		
		int rowNo=count-((currentPage-1)*pageSize);
		
		request.setAttribute("rowNo", rowNo);
		request.setAttribute("pu", pu);
		request.setAttribute("wclass", arr);
		request.setAttribute("count", count);
		
		RequestDispatcher rd=request.getRequestDispatcher("ClassListResult.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);
	}

}

 

  • if else문으로 검색일때와 검색이 아닐때를 나누어서 WClassDAO.java의 classList 메소드를 수행한다.
  • 페이징을 위해 PageUtil.java를 만들었다. 게터세터 생성.
  • 페이징 관련 객체들, 강의 수 출력 관련 객체들, 강의목록을 request.setAttribute 메소드에 담고 ClassListResult.jsp에서 뿌려준다.

<PageUtil.java>

package com.wmember.model;

public class PageUtil {
	private int currentPage;
	private int endPage;
	private int startPage;
	private int totPage;
	private int pageBlock;
	private String field;
	private String word;
	private int classnum;
	
	public int getClassnum() {
		return classnum;
	}
	public void setClassnum(int classnum) {
		this.classnum = classnum;
	}
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getEndPage() {
		return endPage;
	}
	public void setEndPage(int endPage) {
		this.endPage = endPage;
	}
	public int getStartPage() {
		return startPage;
	}
	public void setStartPage(int startPage) {
		this.startPage = startPage;
	}
	public int getTotPage() {
		return totPage;
	}
	public void setTotPage(int totPage) {
		this.totPage = totPage;
	}
	public int getPageBlock() {
		return pageBlock;
	}
	public void setPageBlock(int pageBlock) {
		this.pageBlock = pageBlock;
	}
	public String getField() {
		return field == null ? "" : field.trim();
	}
	public void setField(String field) {
		this.field = field;
	}
	public String getWord() {
		return word == null ? "" : word.trim();
	}
	public void setWord(String word) {
		this.word = word;
	}
}

 


<WClassDAO.java의 classList 메소드> (검색 아닐때)

//검색 아닌 전체보기
	public ArrayList<WClassDTO> classList(int startRow, int endRow) {
		Connection con=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		ArrayList<WClassDTO>arr=new ArrayList<WClassDTO>();
		
		try {
			con=getConnection();
			StringBuilder sb=new StringBuilder();
			sb.append("select * from");
			sb.append(" (select aa.*, rownum rn from");
			sb.append(" (select * from wclass order by classnum desc) aa");
			sb.append(" where rownum<=?) where rn>=?");
			ps=con.prepareStatement(sb.toString());
			ps.setInt(1, endRow);
			ps.setInt(2, startRow);
			rs=ps.executeQuery();
			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, ps, rs);
		}
		return arr;
	}

 


<WClassDAO.java의 classList 메소드> (검색했을때)

//검색 전체보기
	public ArrayList<WClassDTO> classList(String field, String word, int startRow, int endRow) {
		Connection con=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		ArrayList<WClassDTO>arr=new ArrayList<WClassDTO>();
		
		try {
			con=getConnection();
			StringBuilder sb=new StringBuilder();
			sb.append("select * from");
			sb.append(" (select aa.*, rownum rn from");
			sb.append(" (select * from wclass where upper ("+field+") like upper ('%"+word+"%')");
			sb.append(" order by classnum desc) aa");
			sb.append(" where rownum<=?) where rn>=?");
			ps=con.prepareStatement(sb.toString());
			ps.setInt(1, endRow);
			ps.setInt(2, startRow);
			rs=ps.executeQuery();
			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, ps, rs);
		}
		return arr;
	}

 

 


<WClassDAO.java의 getCount 메소드> (if else를 이용해 검색과 검색아닌 경우를 분리)

 

//강의수 출력
	public int getCount(String field, String word) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		int count=0;
		String sql="";
		
		try {
			con=getConnection();
			st=con.createStatement();
			if(word.equals("")) {
				sql="select count(*) from wclass";
			}else {
				sql="select count(*) from wclass where upper ("+field+") like upper ('%"+word+"%')";
			}
			rs=st.executeQuery(sql);
			if(rs.next()) {
				count=rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return count;
	}

ClassListResult.jsp

  • ClassListResult.jsp는 WClassListAction.java에서 넘어온 강의목록과 페이징 영역을 포함하고 있다.
  • 강의목록을 클릭했을때 ClassList.jsp->WClassListAction.java->ClassResult.jsp로 이동한다. 
  • 나중에 설명할 장바구니 cartList.jsp와는 차이점이 있다. (cartList.jsp에는 페이징과 검색기능이 없다. $.getJSON으로 cartList.java에 가고 JSONObject과 JSONArray객체를 만들어서 뿌릴 값들을 저장한다. 그다음 다시 cartList.jsp로 돌아와서 $.each로 뿌린다.)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<style>
h5 a{
 	text-decoration: none;
 	color: black;
 }
.back2{
	margin-top: 20px;
	background-color: #f8f9fa;
}
.sidebar{
	float: left;
	width: 200px;
	height:200px;
	margin-top: 60px;
	margin-left: 60px;
}
.sidebar ul{
	list-style: none;
}
.sidebar ul a{
	line-height: 2em;
}
</style>
</head>
<body>
<aside class="sidebar">
	<ul id="menu">
        <li><h5><a href="/Tutoring/class/ClassInsert"> 강의입력</a></h5></li>
        <li><h5><a href="/Tutoring/class/ClassList.jsp"> 강의목록</a></h5></li>
        <li><h5><a href="/Tutoring/member/Adminview"> 계정설정</a></h5></li>
	</ul>
</aside>
<div class="container">
<br/>
<h5><a href="ClassList.jsp">강의목록(<span id="cntSpan">${count}</span>)</a></h5>
<div class="back2">
<table class="table table-hover">
	<thead>
		<tr>
			<th>번호</th>
			<th>강의분류</th>
	        <th>강의명</th>
	        <th>강의 주제</th>
		</tr>
	</thead>
	<tbody>
		<c:forEach items="${wclass}" var="wclass" varStatus="st">
		<tr>
			<td>${rowNo-st.index}</td>
			<c:if test="${wclass.clevel eq 'basic'}">
				<td>유창한 영어의 기본 요소</td>
			</c:if>
			<c:if test="${wclass.clevel eq 'career'}">
				<td>경력 개발</td>
			</c:if>
			<c:if test="${wclass.clevel eq 'expression'}">
				<td>자신을 표현해보세요</td>
			</c:if>
			<c:if test="${wclass.clevel eq 'test'}">
				<td>시험 준비</td>
			</c:if>
      		<td><a href="ClassDetail?num=${wclass.classnum}">${wclass.classname}</a></td>
      		<td>${wclass.topic}</td>
      	</tr>
		</c:forEach>
	</tbody>
</table>
</div>
</div>
<div align="center" class="text-success">
	<c:if test="${pu.startPage>pu.pageBlock }"> <!-- 이전 -->
		<a href="javascript:getData(${pu.startPage-pu.pageBlock},'${pu.field}','${pu.word}')">[이전]</a>
	</c:if>
	<c:forEach begin="${pu.startPage}" end="${pu.endPage}" var="i"><!-- 페이지 출력 -->
		<c:if test="${i==pu.currentPage}"> <!-- 현재 페이지 -->
			<c:out value="${i}"/>
		</c:if>
		<c:if test="${i!=pu.currentPage}"> <!-- 현재 페이지 아닌 경우 링크 부여-->
			<a href="javascript:getData(${i},'${pu.field}','${pu.word}')">${i}</a>
		</c:if>
	</c:forEach>
	<c:if test="${pu.endPage<pu.totPage}"> <!-- 다음-->
		<a href="javascript:getData(${pu.endPage+1},'${pu.field}','${pu.word}')">[다음]</a>
	</c:if>
</div>
<br/>

 

제목을 클릭하면 다음 코드에 의해 강의 상세보기 페이지로 이동한다.

<td><a href="ClassDetail?num=${wclass.classnum}">${wclass.classname}</a></td>

 


WClassDetail.java

(강의 상세보기 서블릿. 경로는 "/Tutoring/class/ClassDetail")

 

package com.wclass.action;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.wmember.model.WClassDAO;
import com.wmember.model.WClassDTO;

@WebServlet("/class/ClassDetail")
public class WClassDetailAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WClassDetailAction() {
        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("ClassDetail.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

  • ClassListResult.jsp에서 받아온 num값을 이용하여 WClassDAO.java의 classView 메소드를 실행한다.
  • dto객체를 dto 이름으로 저장하여 ClassDetail.jsp로 내보낸다.

 


 

<WClassDAO.java의 classView 메소드>

//강의 상세보기
	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;
	}

 


ClassDetail.jsp

회원정보 수정과 마찬가지로 강의를 수정하고 삭제할 수 있는 폼을 포함하고 있다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
a{
	text-decoration: none;
}
a:hover{
	text-decoration: none;
}
.back2{
	margin-top: 20px;
	background-color: #f8f9fa;
	border-radius: 20px;
}
#frm{
	margin: 0 auto;
	width: 50%;
}
.button{
	text-align: center;
	margin: 0 auto;
	padding: 20px;
}
.sidebar{
	float: left;
	width: 200px;
	height:200px;
	margin-top: 60px;
	margin-left: 60px;
}
.sidebar ul{
	list-style: none;
}
.sidebar ul a{
	line-height: 2em;
}
.thumb-image{
	float:left;
	width:200px;
	position:relative;
	padding:5px;
}
img{
	width:200px;
}
</style>
<aside class="sidebar">
	<ul id="menu">
        <li><h5><a href="/Tutoring/class/ClassInsert.jsp"> 강의입력</a></h5></li>
        <li><h5><a href="/Tutoring/class/ClassList.jsp"> 강의목록</a></h5></li>
        <li><h5><a href="/Tutoring/member/Adminview"> 계정설정</a></h5></li>
	</ul>
</aside>
<div class="container">
<br/>
<h5>강의입력</h5>
<div class="back2">
<form action="ClassUpdate" method="post" id="frm" enctype="multipart/form-data">
  <br/><br/>
  	<div id="image-holder"></div>
      <img src="/Tutoring/upload/${dto.uploadFile}">
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의 이미지</span>
    </div>
      <input type="file" class="form-control" id="uploadFile" name="uploadFile">
      <input type="text" class="form-control" value="${dto.uploadFile}">
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의분류</span>
    </div>
      <select name="clevel" id="clevel" name="clevel">
      	<option value="basic" class="form-control" >유창한 영어의 기본 요소</option>
      	<option value="career" class="form-control">경력 개발</option>
      	<option value="expression" class="form-control">자신을 표현해보세요</option>
      	<option value="test" class="form-control">시험 준비</option>
      </select>
  </div>
  <br/>
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의명</span>
    </div>
      <input type="text" class="form-control" id="classname" name="classname" value="${dto.classname}">
  </div>
  <br/>
   
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의 주제</span>
    </div>
      <input type="text" class="form-control" id="topic" name="topic" value="${dto.topic}">
  </div>
  <br/>
  
  <div class="input-group mb-3">
    <div class="input-group-prepend">
      <span class="input-group-text">강의설명</span>
    </div>
      <textarea rows="5" cols="20" class="form-control" id="content" name="content">${dto.content}</textarea>
  </div>
  <br/>
  
  <div class="button">
 	  <button  id="send"  class="btn btn-info">저장</button>
 	  <input type="button" class="btn btn-danger" value="강의삭제" onclick="delClassCheck('${dto.classnum}')">
  </div>
<input type="hidden" id="classnum" name="classnum" value="${dto.classnum}">
</form>
</div>
</div>
<br/><br/>
<%@ include file="../include/footer.jsp" %>
<script>
$("select[name=clevel] option").each(function(){
	if($(this).val()=='${dto.clevel}'){
		 $(this).prop("selected", true);
	}
});
function delClassCheck(classnum){
	 if(confirm("삭제하시겠습니까? 삭제된 강의정보는 되돌릴 수 없습니다.")){
    	location.href="delete?classnum="+classnum;
    }
}
$(document).ready(function(){
	$("#send").click(function(){
		if($("#classname").val()==""){
			alert("강의명을 입력하세요");
			$("#classname").focus();
			return false;
		}
		if($("#topic").val()==""){
			alert("강의주제를 입력하세요");
			$("#topic").focus();
			return false;
		}
		if($("#content").val()==""){
			alert("강의설명을 입력하세요");
			$("#content").focus();
			return false;
		}
		$("#frm").submit();
	})//send
	
	$("#uploadFile").on('change', function () {
        if (typeof (FileReader) != "undefined") {
            var image_holder = $("#image-holder");
            image_holder.empty();
            var reader = new FileReader();
            reader.onload = function (e) {
                $("<img />", {
                    "src": e.target.result,
                    "class": "thumb-image"
                }).appendTo(image_holder);
            }
            image_holder.show();
            reader.readAsDataURL($(this)[0].files[0]);
        } else {
            alert("이 브라우저에서 지원하지 않는 확장자 입니다.");
        }
    });
});//document
</script>

 

  • send버튼을 누르면 ClassUpdate로 post방식으로 넘어간다. 강의 이미지를 포함하고 있기 때문에 form 태그 안에 enctype="multipart/form-data"를 포함하고 있다.


WClassUpdate.java

(ClassDetail.jsp에서 넘어온 서블릿. 경로는 "/Tutoring/class/ClassUpdate"이다.)

 

package com.wclass.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.wmember.model.WClassDAO;
import com.wmember.model.WClassDTO;

/**
 * Servlet implementation class MemberUpdate
 */
@WebServlet("/class/ClassUpdate")
public class WClassUpdateAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WClassUpdateAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WClassDAO dao=WClassDAO.getInstance();
		int uploadFileSizeLimit=5*1024*1024;
		String encType="UTF-8";
		String savePath="upload";
		ServletContext context=getServletContext();
		String uploadFilePath=context.getRealPath(savePath);
		
		//multipart/form 방식은 request.getParameter로 받아올 수 없음
		MultipartRequest multi=new MultipartRequest(
				request, //request객체
				uploadFilePath, //서버상의 실제 디렉토리
				uploadFileSizeLimit, //최대 업로드 파일 크기
				encType, //인코딩 방법
				new DefaultFileRenamePolicy()); //동일 파일 새이름 부여
		
		//업로드된 파일이름 구하기
		String fileName=multi.getFilesystemName("uploadFile");
		
		if(fileName==null) { //파일 업로드 안됨
			System.out.println("파일 업로드 되지 않았음");
		}
		
		WClassDTO wclass=new WClassDTO();
		wclass.setUploadFile(fileName);
		wclass.setClassname(multi.getParameter("classname"));
		wclass.setClevel(multi.getParameter("clevel"));
		wclass.setContent(multi.getParameter("content"));
		wclass.setTopic(multi.getParameter("topic"));
		int classnum=Integer.parseInt(multi.getParameter("classnum"));
		wclass.setClassnum(classnum);
		int flag=dao.classUpdate(wclass);
		if(flag==1) {
			response.setContentType("text/html; charset=euc-kr");
			PrintWriter out = response.getWriter();
			out.println("<script>");
			out.println("alert('강의정보가 수정되었습니다');");
			out.println("history.back(-1);");
			out.println("</script>");
		}

	}
}

 

  • ClassInsert와 마찬가지로 MultipartRequest 메소드를 이용하여 객체를 선언한다.
  • WClassDAO.java의 classUpdate 메소드를 수행하고 return 값이 있으면 alert 창을 띄운다.

 


<WClassDAO.java의 classUpdate 메소드>

 

//강의정보 수정
	public int classUpdate(WClassDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		int flag=0;
		try {
			con=getConnection();
			String sql="update wclass set classname=?, topic=?, content=?, clevel=?, uploadfile=? where classnum=?";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getClassname());
			ps.setString(2, vo.getTopic());
			ps.setString(3, vo.getContent());
			ps.setString(4, vo.getClevel());
			ps.setString(5, vo.getUploadFile());
			ps.setInt(6, vo.getClassnum());
			flag=ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
		return flag;
	}

 


강의 상세보기(ClassDetail.jsp)에서 강의삭제 버튼을 누르면 자바스크립트의 delClassCheck로 강의번호를 들고 넘어간다.

 

function delClassCheck(classnum){
	 if(confirm("삭제하시겠습니까? 삭제된 강의정보는 되돌릴 수 없습니다.")){
    	location.href="delete?classnum="+classnum;
    }
}

 

 

WClassDeleteAction.java

(강의 삭제 서블릿. 경로는 "/Tutoring/class/delete"이다.)

 

package com.wclass.action;

import java.io.IOException;

import javax.servlet.ServletContext;
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.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.wmember.model.WClassDAO;

/**
 * Servlet implementation class WClassDeleteAction
 */
@WebServlet("/class/delete")
public class WClassDeleteAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WClassDeleteAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WClassDAO dao=WClassDAO.getInstance();
		int classnum=Integer.parseInt(request.getParameter("classnum"));
		dao.classDel(classnum);
		response.sendRedirect("ClassList.jsp");
	}

}

 

  • 파라미터 값으로 받아온 classnum(강의번호)을 들고 WClassDAO.java의 classDel메소드를 수행한다. 
  • 삭제하고 난 뒤에는 ClassList.jsp로 다시 이동한다.

 


<WClassDAO.java의 classDel 메소드>

 

//삭제
	public void classDel(int classnum) {
		Connection con=null;
		Statement st=null;
		try {
			con=getConnection();
			String sql="delete from wclass where classnum='"+classnum+"'";
			st=con.createStatement();
			st.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, null);
		}
	}

 


WMemberLogout.java

(로그아웃 기능을 구현하는 서블릿. 경로는 "/Tutoring/member/logout"이다.)

 

package com.wmember.action;

import java.io.IOException;
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;

/**
 * Servlet implementation class MemberLogout
 */
@WebServlet("/member/logout")
public class WMemberLogout extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberLogout() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session=request.getSession();
		session.invalidate();
		response.sendRedirect("login");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

https://github.com/kkj0712/JspProject_Tutoring

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

+ Recent posts