파라미터 값 받기

ex03_form.jsp

 

입력 받은 값을 출력 ( jstl 문법으로 param."파라미터 이름" 또는 여러개의 파라미터 값이면 paramValues."파라미터 이름" 으로 불러온다

 

코드 실행 결과

 

 

 

 

 

DAO, DTO 활용하기

TestDAO.java, TestDTO.java 파일 생성 후 작성

 

ex04_all_data.jsp, ex04_one_date.jsp 작성 ( bean 객체를 사용하여 TestDAO 에 있는 데이터를 dao 라는 변수로 저장 > dao 의 getList() 메소드를 사용하여 얻어지는 값들을 list 변수에 저장 > 해당 list 를 for Each 문을 사용하여 dto 라는 변수로 받아서 사용

728x90

 

 

 

 

 

EL

EL

 

EL 연산자

 

EL 의 출력방법, jstl 의 if 문, 반복문은 Spring 에서도 사용되니 기억하기 !!!

 

파일 세팅

 

파일 세팅 완료, 미리 ojdbc8.jar 도 세팅함

 

EL 문법의 ${} 는 자바스크립트에서 사용하는 표현 문법인 ${} 과 같이 사용할 수 없다

( jsp 파일에서는 자바스크립트의 ${} 를 사용할 수 없음 )

 

ex01.jsp 에 EL 문법의 단순 출력식 표현 > 결과물

 

EL 연산

 

login.jsp 에 로그인 폼 간단히 작성, result.jsp 에서는 기존 파라미터 값 받아오는 코드와 el 문법으로 파라미터 값을 받아오는 코드 작성

 

 

 

 

 

EL scope

파일 세팅

 

set.jsp 와 get.jsp 를 작성 과 결과물

 

 

 

 

 


 

 

 

 

 

JSTL

 

Apache Taglibs - Apache Standard Taglib: JSP[tm] Standard Tag Library (JSTL) implementations

<!-- Copyright 1999-2011 The Apache Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/

tomcat.apache.org

JSTL 다운로드 사이트

 

jakarta-taglibs-standard-1.1.2.zip 다운로드

 

다운로드 받은 zip 파일 압축 해제 후 lib 폴더에 있는 jstl.jar 파일과 standard.jar 파일 복사하여 프로젝트 내 lib 파일에 붙여넣기

 

파일 세팅

 

파일 세팅 완료

 

JSTL 이란?

 

JSTL 태그

 

JSTL core 기능

 

JSTL 문법을 사용하려면 taglib 으로 jstl 의 core 를 불러와서 c 라는 이름으로 사용한다고 정의해줘야 한다

 

JSTL 문법

 

forEach 문 사용과 forTokens 를 사용해서 특정 문자를 기준으로 잘라서 표현

 

예외처리 ( catch 문 안에 내용이 예외를 발생시킨다면 해당 예외를 result 라는 변수에 담는다 )

 

Scope 정의 및 확인 ( import 로 ex02_test.jsp 파일의 내용을 불러옴 include 와 같은 역할 )

 

ex02_delete.jsp 에서 세션을 삭제하고 다시 ex02_session.jsp 로 리다이렉트로 보냄

 

다양한 절대경로의 표현 방식

 

코드 실행 영상
728x90

 

 

 

 

 

액션 태그

jsp 액션 태그

 

 

 

 

 

forward 태그

파일 세팅

 

파일 세팅 완료

 

login.jsp 작성

 

check.jsp 에 로그인 실패 시 코드 작성

sendRedirect() : 클라이언트에게 주소를 전송한 뒤 클라이언트가 서버에 전달받은 주소를 다시 요청

forward() : 클라이언트에게 주소를 요청하지 않고 서버에서 처리하여 내부의 경로를 출력

 

액션 태그를 사용하여 로그인 성공 시 코드 작성

 

main.jsp 에서는 request 값이 forward 로 넘어와서 scope 의 범위 내에서 작동하기 때문에 id 와 msg 파라미터를 페이지가 이동되었음에도 사용할 수 있다.

 

 

 

 

 

include 태그

파일 세팅

 

파일 세팅 완료

 

ex01.jsp 작성

 

jsp_include.jsp 와 tag_include.jsp 를 작성

 

각각 jsp 액션 태그와 기본 태그를 사용하여 작성

 

ex01.jsp 에 변수 생성 후 각 페이지에서 확인

>> jsp 액션 태그를 사용해서는 include 로 가져온 변수를 사용할 수 없다. ( 기존 태그를 사용해야 함 )

 

 

 

 

 

useBean 태그

파일 세팅

 

create table mem_jsp(
id varchar2(20) primary key,
pwd varchar2(20),
name varchar2(20),
addr varchar2(100),
tel varchar2(20)
);

insert into mem_jsp values('aaa','aaa','홍길동','산골짜기','010-xxx-xxx');
insert into mem_jsp values('bbb','bbb','김개똥','개똥별','010-xxx-xxx');
insert into mem_jsp values('ccc','ccc','고길똥','마포구','010-xxx-xxx');

commit;

sql 문 실행

 

파일 세팅 완료

 

MemberDTO.java 에 DB 에 저장된 데이터 형식 선언 후 getter / setter 생성

 

ex01.jsp 에서 bean 객체에 DTO 객체를 담아 setter 를 이용해 값을 저장하고 getter 를 이용해 불러와 출력

 

register_form.jsp 에 작성

 

register.jsp 에 기존 방식으로 저장하여 사용하는 코드 작성

 

register_form.jsp 에 넘어온 값들을 setProperty 로 한꺼번에 DTO 에 저장 후 각 값에 1 기입 후 전송

단, setProperty 를 이용해서 bean 객체에 저장할때 넘어오는 이름과 DTO 의 변수 이름이 동일해야 한다

 

index.jsp 파일 작성

 

register_form.jsp 와 show_list.jsp 파일에 index.jsp 를 include

 

MemberDAO.java 에 DB 연동 코드 작성

 

ojdbc8.jar 추가

 

show_list.jsp 에 MemberDAO 를 객체화하여 실행시킨 뒤 콘솔창에 --- 드라이브 로드 성공 --- 문구가 출력되면 정상적으로 DB 에 연동되었다는 의미

 

jsp 태그로 bean 객체를 만들어 memberDAO 를 객체를 생성

 

MemberDAO.java 파일에 DB 에서 mem_jsp 테이블의 정보를 DTO 에 담아서 return 하는 getList() 메소드 선언

 

이후 show_list.jsp 에서 이 getList() 메소드를 사용하여 list 변수에 담고 해당 list 사이즈를 출력하면 콘솔 창에 DB 에 저장된 행의 갯수인 3이 출력됨

 

가져온 값을 table 에 출력

 

register.jsp 에 DB 에 회원을 추가하는 코드를 추가

 

MemberDAO.java 에 DB 에 데이터를 저장하는 register 메소드를 정의

 

회원가입 이후 DB 에 저장된 모습 바로 확인됨

728x90

 

 

 

 

 

DB 연동

파일 세팅, ojcbc8 도 lib 폴더에 넣어놔야 함

 

create table member_jsp(
id varchar2(20) primary key,
name varchar2(20),
kor number,
eng number,
math number
);
insert into member_jsp values('aaa','Hong',100,100,100);
insert into member_jsp  values('bbb','Kim',90,90,90);
insert into member_jsp  values('ccc','Go',80,80,80);

commit;

sql 문 실행

 

driver.jsp 작성, 연동 성공 문구 콘솔창에 출력되어야 DB 연동 성공 ( 11 버전 : xe, 이후 버전 : orcl )

DriverManager 와 Connection 클래스 import 필요

 

select_all.jsp 에서 driver.jsp 파일을 include 해서 con 객체를 받아와서 출력 및 각 name 에 a 태그 추가

 

쿼리문 실행 결과를 담은 ResultSet 의 구성 rs.next() 를 사용하여 다음 값이 있는지 확인

 

select_all.jsp 페이지에서 이름을 클릭했을때 a 태그로 파라미터 값과 함께 전달되는 것 select_one.jsp 에서 확인

 

select_all.jsp 에서 넘겨받은 파라미터 값을 가지고 select_all.jsp 에서 DB 에 접근하여 내용을 표시

728x90

 

 

 

 

 

response

ex01.jsp 를 실행하면 응답으로 redirect 가 실행되어 네이버가 출력

 

파일 3개 세팅 check.jsp, login.jsp, main.jsp

 

login.jsp, check.jsp, mian.jsp 작성

 

getWriter() 메소드를 사용하여 script 를 이용해 alert 창을 띄울 수도 있다

 


 

 

 

 

Scope

Scope

 

파일 세팅

 

set_scope.jsp 에서 scope(page, request, session, application) 를 생성, scope 생성 시 괄호의 앞 내용은 키 뒷 내용은 값이다.

 

page : 요청한 페이지 내에만 유지 ( 페이지가 이동되면 삭제 )

request : 요청한 페이지에서 다음 페이지까지 유지된다

session : 현재 켜져있는 브라우저에서만 작동 ( 예를 들어, 크롬에서 scope 를 받고 네이버 웨일로 동일 웹을 작동시키면 session 이 유지되지 않음, 주로 로그인에서 사용 )

application : 작동하는 브라우저를 변경해도 application 은 유지되며 서버가 종료되면 application 도 삭제

 

request 를 다음페이지 까지 유지하고 싶으면 forward 를 사용하여 전달 받은 request 값을 전달해야 한다.

이런 식으로 전달하지 않으면 페이지를 임의로 이동시킨다고 해서 scope 가 다음 페이지까지 저장된 상태로 넘어가지 않는다.

 

 

 

 


 

 

 

 

 

cookie

쿠키 : 클라이언트에서 관리

파일 세팅

 

쿠키 생성

testCookie 라는 key 로 myCookie 라는 내용을 생성, cookie.setMaxAge(5) 로 5초동안 쿠키를 유지

 

스크립트를 사용하여 팝업창을 출력하게끔 설정

 

popup.jsp 간단히 작성

 

요청으로 부터 getCookies() 메소드를 사용해 쿠키의 목록을 Cookie 자료형의 배열로 받아와서 출력

 

최초 요청시에는 기본 발급 쿠키만 존재하지만 5초 내에 새로고침을 하여 요청을 다시 보내면 쿠키 값을 출력한다

 

testCookie 라는 이름의 쿠키가 없을때만 팝업을 출력 ( boolean 값으로 조절 )

 

test.jsp 파일 추가

 

ex01.jsp 에서는 test.jsp 경로로 가는 a 태그를 추가, test.jsp 에서는 현재 쿠키 값을 보여주는 코드를 작성

 

테스트 해보면 cookie 는 발급된 파일의 상위 파일이 실행될때는 존재하지 않는다.

자신의 상위 파일이 실행될때도 쿠키값을 존재하게 하려면 cookie.setPath() 메소드를 사용하여 쿠키의 경로를 설정해줘야 한다.

 

쿠키를 최상위 위치에서 부터 쿠키를 사용할 수 있게 설정 후 쿠키가 정상적으로 확인

 

ex01.jsp 에 쿠키 삭제 경로 추가

 

쿠키는 삭제하는 코드가 따로 없기 때문에 쿠키의 유지 시간을 0초로 조정하여 응답하여 삭제시킨다

※ 쿠키는 삭제하는 코드가 따로 없기 때문에 쿠키의 유지 시간을 0초로 조정하여 응답하여 삭제시킨다

 

 

 

 

 


 

 

 

 

 

session

세션 : 서버에서 관리

파일 세팅

 

set.jsp 에서 세션 설정, get.jsp 에서 세션 출력

 

del.jsp 에서 세션 삭제

 

session.removeAttribute("age") : age 라는 키의 세션을 삭제시킨다.

session.setMaxInactiveInterval(5) : 5초 후 모든 세션을 만료시킨다.

session.invalidate() : 모든 세션을 만료시킨다.

 

간단하게 login.jsp 에 입력받는 폼 작성

 

로그인 정보를 검증하는 check.jsp 작성

 

main.jsp 작성

 

logout.jsp 작성

 

세션으로 로그인을 관리하는 페이지 작성 완료

728x90

 

 

 

 

 

JSP

 

이클립스 다운로드

 

Eclipse Packages | The Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 350 open source pro

520 MB 197,629 DOWNLOADS Tools for developers working with Java and Web applications, including a Java IDE, tools for JavaScript, TypeScript, JavaServer Pages and Faces, Yaml, Markdown, Web Services, JPA and Data Tools, Maven and Gradle, Git, and more. Cli

www.eclipse.org

 

Eclipse Enterprise 버전 다운로드 ( 웹을 구동해야 하므로 Enterprise 버전이 필요한다 )

 

 

 

 

 

 

아파치 톰캣 9 버전 다운로드

 

Apache Tomcat® - Apache Tomcat 9 Software Downloads

Welcome to the Apache Tomcat® 9.x software download page. This page provides download links for obtaining the latest version of Tomcat 9.0.x software, as well as links to the archives of older releases. Unsure which version you need? Specification version

tomcat.apache.org

 

64-bit Windows zip 버튼 눌러서 다운로드 및 압축 해제

 

압축 해제 완료

 

 

 

 

 

워크스페이스 생성 및 설정

 

프로젝트 생성

 

New Runtime 클릭

 

Apache Tomcat v9.0 클릭, Create a new local server 체크 후 Next

 

아파치 톰캣 설치된 경로를 설정 > Browse 클릭

 

아파치 톰캣 설치 경로까지 들어가 폴더 선택 클릭

 

Finish 클릭

 

src - main - webapp 하위에 ex01.jsp 생성 후 body 태그 안에 문자 작성 후 저장하여 웹 테스트

 

Ctrl _ F11 눌러서 실행시킨 뒤 서버를 톰캣으로 실행, Always use this server when running this project 클릭 후 Finish

 

웹 정상 실행

 

 

 

 

 


▼ 만약 서버를 실행시켰는데 에러가 출력된다면 사용하려는 포트 번호가 겹친 경우!! ▼

포트번호가 겹쳐 에러가 발생한다면 하단의 servers 탭에 현재 구동중인 Tomcat v9.0 서버 더블클릭

 

HTTP/1.1 포트 번호가 겹쳐서 문제가 발생하는 것이기 때문에 포트번호를 8080에서 변경해준다


 

 

 

 

 

인코딩 방식 변경

한글을 처리하기 위해서 charset 을 UTF-8 로 변경해야 함
Window - Preferences - General - Workspace 의 Other 항목이 UTF-8 로 선택되어 있는지 확인

 

Web - CSS Files - Encoding 을 UTF-8 로 변경

 

HTML Files 도 인코딩 방식 UTF-8 로 변경

 

JSP Files 도 인코딩 방식 UTF-8 로 변경

 

위 설정 이후 새로 jsp 파일을 생성하면 자동으로 인코딩 방식이 UTF-8 로 변경되어 생성된다

 


 

 

 

 

 

JSP 기본 태그

JSP 기본 태그

 

 

 

 

 

스크립트릿

스크립트릿 > 실행하면 웹이 실행되며 콘솔창에 num : 100 이 출력 > 웹에는 따로 출력한 것이 없기 때문에 빈 페이지가 출력됨

 

스크립트릿 > out.print(); 함수를 사용하여 웹에도 출력

 

 

 

 

주석

<%-- --%>

 

 

 

 

 

표현식

<%= %>

 

스크립트릿과 표현식 함께 사용

 

 

 

 

 

선언문

<%! %> : 서버가 실행될때 처음 한번만 확인.... 그래서 num++ 를 입력한 뒤 새로고침하면 num 의 수가 계속 올라감 ( 서버 재실행 시 초기화 )

 

메소드는 선언문에서만 생성할 수 있다!

 

선언문 사용 예시 ( HashMap 입력 후 Ctrl + Spacebar 눌러서 import 후 실행 )

 

 

 

 

지시자

( 아래서 자세하게 다룸 )

 


 

 

 

 

 

경로 이동 방식

 

새로운 dynamic web project 생성

파일 생성

 

절대경로와 상대경로 사용 방식

각각 상대경로, 절대 경로를 사용하여 각 jsp 파일로 a 태그를 사용하여 경로 변경

 

 

 

 

 

Get 방식, Post 방식

Request & Response

 

파일 세팅

 

form.jsp 작성

 

get.jsp, post.jsp 작성

 

post 방식으로 넘기면 request.setCharacterEncoding("utf-8") 로 인코딩 방식을 명시해줘야 한글이 깨지지 않는다.

!!! post 방식으로 값을 넘길땐 받는 쪽에서 인코딩 방식을 꼭 명시해주기 !!!

 

form2.jsp 와 result.jsp 파일 생성 및 작성

 


 

지시자

지시자

 

 

 

 

 

page 지시자

파일 생성

 

ex02.jsp 에서 값을 0 으로 나눠서 에러 발생시킨 뒤 <%@ %> 사용하여 에러페이지를 error_msg.jsp 로 설정

 

error_msg.jsp 에서는 isErrorPage 를 true 옵션으로 바꿔 에러페이지 파일임을 명시해줘서 exception 을 사용하여 에러 메세지를 출력할 수 있다.

 

 

 

 

 

include 지시자

파일 세팅

 

header.jsp 와 footer.jsp 파일 작성

 

main.jsp 작성 ( header.jsp 와 footer.jsp 를 불러와서 사용 )

 

 

 

 

 

taglib 지시자

 

 

 

 

 

 

 

 

 

 

 

 

 

 

실습 예제

실습 예제

 

예제 풀이

header.jsp ( 각각 파일의 디렉토리가 다르므로 절대 경로를 사용 )

 

main.jsp

 

ex01.jsp

 

ex02.jsp 는 에러가 발생하는 페이지 이므로 error_msg.jsp 에 include 태그 적용

 


 

 

 

 

 

Request / Response

파일 세팅

 

ex02_form.jsp 작성 ( request.getContextPath 를 사용해서 프로젝트의 경로를 받아와서 사용 )

 

ex02_result.jsp 에서 여러 파라미터 값이 같은 name 으로 넘어오는 경우 request.getParameterValues 를 사용하여 문자열 배열로 받아서 사용한다.

 

getParameterNames 를 사용하여 파라미터의 이름을 확인....

반환형태는 Enumeration<String> 형태이며 while 문을 사용하여 다음 내용이 있는지 확인하여 nextElement() 메소드를 사용하여 변수로 해당 파라미터명을 담아서 사용한다.

728x90

 

 

 

 

 

게시판 구현 ( 댓글 기능 추가, 페이징, 게시글 수정, 게시글 삭제, 이미지 수정 )

 

 


 

게시글 상세보기 기능 추가

 

list.ejs 에 댓글기능을 추가할 a 태그 추가

 

라우터에 경로 추가

 

board_ctrl.js 에도 data 함수 추가

 

board_service.js 에서 data 함수 추가

 

board_dao.js 에 data 함수 추가

 

data.ejs 생성 후 코드 입력

<%- include ("../default/header") %>
<div class="content wrap">
    <div style="width:600px; margin: 0 auto;">
    <h3 style="text-align: center; margin-bottom: 10px;"> - 개 인 정 보 - </h3>
    <table border="1" align="center">
        <tr>
            <th width="100">글 번호</th> <td width="200"><%= data.WRITE_NO %></td> 
            <th width="100">작성자</th>  <td width="200"><%= data.ID %></td>
        </tr>
        <tr>
            <th>제목</th> <td><%= data.TITLE %></td> 
            <th>등록일자</th> <td><%= data.SAVE_DATE %></td>
        </tr>
        <tr>
            <th>내용</th><td><%= data.CONTENT %></td> 
            <td colspan="2">
                <% if( data.ORIGIN_FILE_NAME === "nan"){%>
                    <b>이미지가 없습니다
                <%}else{%>
                    <b>이미지 : <%=data.ORIGIN_FILE_NAME%> </b>
                <%}%>
            </td>
        </tr>
        <tr>
            <td colspan="4" align="center">
                <%if(username === data.ID){%>
                    <input type="button" onclick="" value="수정하기"> 
                    <input type="button" onclick="" value="삭제하기">
                <%}%>
                <input type="button" onclick="" value="답글달기"> 
                <input type="button" onclick="" value="리스트로 돌아가기">
            </td>
        </tr>
        </table>
    </div>
</div>

data.ejs 코드

 

게시글 상세보기 기능 구현 완료

 


 

이미지 출력 구현

 

파일 다운로드 경로 입력

 

board_router.js 에 경로 추가

 

board_ctrl.js 에 기능 추가

 

글에 들어가면 이미지 출력 구현 완료

 


 

글 조회수 기능 추가

 

 

board_dao.js 에 조회수 증가 기능 추가

 

조회수 증가 기능 구현 완료

 


 

글 삭제 기능 구현

 

이미지와 글을 모두 삭제해야 하므로 경로에 글 번호와 이미지를 모두 넘겨줌 ( data.ejs 에 작성 )

 

board_router.js 에 경로 추가

 

board_ctrl.js 에서 이미지 삭제 코드 구현

 

board_ctrl.js 에서 글 삭제 관련 코드 service 쪽으로 넘겨준 뒤 다시 글 목록으로 redirect 시킨다

 

board_service.js 에서는 받은 데이터를 dao 쪽으로 넘겨준다

 

board_dao.js 에서 삭제 부분 구현

 

글 삭제 구현 완료

 


 

글 수정 기능 구현

 

data.ejs 에서 수정하기 기능 클릭 시 경로 설정

 

board_router.js 에 경로 추가

 

board_ctrl.js 에 modifyForm 기능 추가

 

modify_form.ejs 작성

<%- include ("../default/header") %>
<script src="/static/js/image_read.js"></script>
<div class="content wrap">
<div style="width:300px; margin: 0 auto;">
    <form action="/board/modify" enctype="multipart/form-data" method="post" >
        <input type="hidden" name="write_no" value="<%=data.WRITE_NO%>">
        <input type="hidden" name="change_file_name" value="<%=data.CHANGE_FILE_NAME%>">
        <input type="hidden" name="origin_file_name" value="<%=data.ORIGIN_FILE_NAME%>">
        제목  <input type="text" size="30" name="title" value="<%=data.TITLE%>"><hr>
        내용  <textarea rows="5" cols="30" name="content"><%=data.CONTENT%></textarea>
        <hr>
        <img width="200px" height="100px" id="img"
                        src="/board/download/<%=data.CHANGE_FILE_NAME%>">
        <input type="file" name="image_file_name" onchange="readURL(this)">
        <hr>
        <input type="submit" value="수정하기">
        <input type="button" onclick="history.back()" value="이전으로 돌아가기">
    </form>
</div>
</div>

modify_form.ejs 코드

 

수정하기 누르면 이동될 경로 board_router.js 에 설정

 

board_ctrl.js 에 modify 기능을 추가

 

board_service.js 에서 modify 기능을 추가

 

board_dao.js 에서 sql 문 작성 및 쿼리문 실행

 

게시글 수정 구현 완료

 


 

페이징 기능 구현

 

list.ejs 에서 코드 추가

    <% if( start <= 1){ %>
        <button disabled>이전</button>
    <%}else{%>
        <button type="button" onclick="
            location.href='/board/list?start=<%=start - 1%>'">이전</button>
    <% }for(let i=1 ; i <= totalPage ; i++ ){ %>
        <a href="/board/list?start=<%= i %>"><%= i %></a>
    <% }if( start < totalPage ){%>
        <button type="button" onclick="
            location.href='/board/list?start=<%=start + 1%>'">다음</button>
    <% }else{ %> <button disabled>다음</button> <% } %>
    <%= start %> / <%= totalPage %>

추가 코드

 

기존에 작성되어 있던 board_ctrl.js 에서 코드 수정

 

board_service.js 에 pageOperation 함수 추가 후 기존에 있던 list 함수 수정

 

board_dao.js 에서 list 의 sql 문 수정 및 totalContent 함수 추가

 

페이징 구현 완료

 


 

댓글 기능 구현

 

파일 추가 세팅

 

create table reply(
id varchar(20),
title varchar(50),
content varchar(300),
write_group number(10),
save_date date default sysdate,
constraint fk_test1 foreign key(write_group) references board(write_no) on delete cascade,
constraint fk_test2 foreign key(id) references members(id) on delete cascade
);

db에 sql 문 실행

 

reply.css 작성

#modal_wrap{
    display: none; position: fixed; z-index: 9;
    margin: 0 auto; top:0; left: 0; right: 0;
    width:100%; height:100%;
    background-color: rgba(0, 0, 0, 0.4);
}
#first{ 
    position: fixed; z-index: 10; margin: 0 auto;
    top:30px; left: 0; right: 0; display:none;
    background-color: rgba(212, 244, 250, 0.9);
    height:350px; width:300px;
}

reply.css 코드

 

reply.js 작성

function reply_form(){
    $("#first").slideDown('slow'); 
    $("#modal_wrap").show();
}
function reply_hide(){
    $("#first").slideUp('fast'); 
    $("#modal_wrap").hide();
}
function rep(){
    let form={}; 
    let arr = $("#frm").serializeArray();
    arr.forEach( d => { form[d.name] = d.value; })
    fetch("/boardrep/register", {
        method : "post",
        headers : {"Content-Type" : "application/json"},
        body : JSON.stringify( form )
    })
    .then(res => res.json() )
    .then( result => {
        if(result === 1)
            alert("답글이 달렸습니다!!")
        reply_hide();
    })
}

reply.js 코드

 

reply_form.ejs 작성

<link href="/static/css/reply.css" rel="stylesheet" >
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="/static/js/reply.js"></script>
<div id="modal_wrap">
    <div id="first">
        <div style="width:250px;margin: 0 auto;padding-top: 20px;">
            <form id="frm">
                <input type="hidden" name="write_no" value="<%= data.WRITE_NO %>">
                <input type="hidden" name="id" value="<%= username %>">
                <b>답글 작성 페이지</b> <hr>
                <b>작성자 : <%= username %></b> <hr>
                <b>제목</b><br><input type="text" size="30" name="title"><hr>
                <b>내용</b><br>
                <textarea name="content" rows="5" cols="30"></textarea>
                <hr>
                <button type="button" onclick="rep()">답글</button>
                <button type="button" onclick="reply_hide()">취소</button>
            </form>
        </div>
    </div>
</div>

reply_form.ejs 코드

 

data.ejs 위에 작성

 

data.ejs 에 추가 작성 ( 이 작업은 댓글 창을 따로 띄우는 것이 아닌 페이지 내에 띄우는 작업, 댓글 창 스타일에 따라 작성 )

 

답글 달기 버튼을 눌렀을때 텍스트 박스와 답변 버튼이 조그맣게 생기는 부분이 data.ejs 하단에 script 와 button, div, form 태그 추가한 부분

 

댓글을 달때 fetch 를 통해 넘어오는 json 형태의 데이터를 받기 위해 app.js 에 json 형태를 받을 수 있게 추가

 

기본 router.js 에서 답글 기능에 대한 라우터를 board_reply_router.js 에 위임

 

board_reply_router.js 에 경로 작성

 

board_reply_ctrl.js 에 로직 작성

 

board_reply_service.js 작성

 

board_reply_dao.js 작성

 

reply_view.js 작성

function init( groupNum ){
        fetch(`/boardrep/replyData/`+groupNum )
        .then( res => res.json() )
        .then( data => {
            let html = ""
            data.forEach((d)=>{
                html += "<div align='left'><b>아이디 : </b>"+d.ID+"님 / ";
                html += "<b>작성일</b> : "+d.SAVE_DATE+"<br>"
                html += "<b>제목</b> : "+d.TITLE+"<br>"
                html += "<b>내용</b> : "+d.CONTENT+"<hr></div>"
            });
            const content = document.getElementById("content");
            content.innerHTML = html;
        });
    }

reply_view.js 코드

 

data.ejs 에 내용 추가 ( td 추가한 부분은 댓글 부분 )

 

header.ejs 에 작성 ( header.ejs 가 onload 로 기본으로 실행될 때 init 함수가 실행되게 함

 

board_reply_router.js 작성

 

board_reply_ctrl.js 작성

 

board_reply_service.js 작성 ( 시간을 설정하기 위해 ser_common 의 기능을 호출하여 사용함 )

 

board_reply_dao.js 작성

 

 

 

현재는 답글 달면 새로고침 하기 전에 보이지 않는데 바로 댓글 입력한 데이터를 바로 출력하게끔 입력 받은 값을 덧붙여서 출력 ( 새로 고침을 하게 되면 DB 에서 끌고온 데이터가 출력되며, 이 방법은 일시적으로 데이터를 출력할 뿐 )

 

댓글을 바로 데이터로 덧붙여서 보여주게끔 설정, 위 코드는 일시적으로 댓글을 달면 자신이 단 댓글을 보여줄 뿐이며 실제 DB 에 적용된 데이터는 새로고침을 하면 출력되게 된다

 

댓글 기능 구현 완료

 


 

코드 실행

코드 실행
728x90

 

 

 

 

 

게시판 구현 ( 페이징, 답변 )

파일 세팅

 

create table paging(
num number not null,
title varchar2(30) not null,
pdate varchar2(10) not null,
count number not null,
primary key(num)
);
create sequence test_num;

DB 테이블 생성

 

npm install express --save
npm install ejs --save
npm install oracledb@5.5.0 --save
npm install supervisor --save
npm install body-parser --save

npm 설치

 


 

게시판 목록보기 구현

 

app.js 기본 세팅

 

router.js 기본세팅

 

page_router.js 기본 세팅

 

page_controller.js 기본 세팅

 

index.ejs 세팅

 

page_router 에 list 경로 추가

 

page_controller.js 작성 ( service 쪽에서 db 에 접근해서 작업할 것 이므로 async 처리 )

 

page_service.js 파일 작성

 

db_config.js 작성

 

pageDAO.js 작성

 

list.ejs 작성 ( DAO 에서 가져온 데이터로 테이블 작성 )

 

서버 실행

 

게시판 목록보기 구현 완료

 


 

글 작성기능 구현

 

page_router.js, page_controller.js 작성 ( /write_form 경로 )

 

write_form.ejs 작성 ( 글 작성 기능 )

 

글 작성시 이동되는 /write 경로 page_router.js 에 작성 ( post 방식 )

 

page_controller.js 에 async - await 을 통해 동기처리 하여 작성

 

page_service.js 에 pageInsert 부분 작성

 

pageDAO.js 에 글에 관련된 데이터 DB 에 저장하는 로직 작성 ( nextval : DB 에 sequence 로 생성해놓은 1씩 값이 증가하며 저장되는 부분을 의미 )

 

서버 실행

 

글 작성부분 구현 완료

 


 

글 상세보기 구현

 

list.ejs 에 글 타이틀에 글 번호를 경로로 하는 a 태그 작성

 

page_router.js 에 경로 작성 :num 으로 글 번호를 변수로 받음

 

page_controller.js 에 변수로 받은 num 을 service 로 넘겨주는 코드 작성

 

page_service.js 에 넘겨받은 글 번호를 dao 쪽으로 넘겨서 연산하는 코드 작성

 

dao 에 넘겨 받은 글 번호랑 일치하는 행을 찾는 코드를 작성 후 return 으로 해당 데이터를 service 로 반환

 

content.ejs 작성

 

 

글 상세보기 구현 완료

 


 

조회수 증가시키는 부분 구현

 

page_service.js 에 조회수 증가시키는 부분 로직 작성

 

dao 에 조회수 증가 로직 작성

 

서버 실행 ( 만약 조회수가 글을 눌러서 상세보기가 켜지자 마자 늘어나길 원한다면 조회수 늘어나는 로직에 async - await 을 적용해주면 된다 )

 

글 조회수 증가 구현 완료

 


 

 

 

 

 

페이징 처리

페이징 방식

 

글의 총 갯수를 가져오는 totalContent 를 page_controller.js 에 작성

 

page_service.js 에 글 전체 갯수 가져오는 로직 작성

 

pageDAO.js 에 DB 에 접근하여 전체 글 갯수 가져오는 로직 작성

 

list.ejs 에 totalContent 출력해 봄 ( 콘솔과 웹 출력 결과물 )

 

페이지를 확인할 수 있는 start 라는 변수를 생성하여 로직을 작성할 것, page_controller.js 작성

 

page_service.js 에서 로직 작성

 

start 값을 출력해 봄

 

이전을 누르면 start -1 값을 전달, 다음을 누르면 start +1 값을 전달, start 값이 1이면 이전 버튼을 비활성화, start 값이 totalContent 와 같아면 다음 버튼을 비활성화

 

rownum : 가상의 행의 수

( 의미는 없지만, 만약 글의 번호로 데이터를 처리한다고 가정했을 때 한 페이지에 글을 5개씩 출력하고자 할 때 2번째 작성 글이 삭제되었다면 오류가 발생하거나 첫번째 페이지에 1, 3, 4, 5 글 4개만 출력되게 된다..... 그래서 오라클에서 지원하는 가상의 행{결과 값이 출력되는 행만큼 임의의 번호를 붙여주는 rownum}인 rownum 을 사용하여 글이 삭제되었어도 빈 값이 없이 1, 3, 4, 5, 6 식으로 출력되게끔 설정한다 )

 

마지막 페이지 값을 담은 page 정보도 page_controller.js 에 작성

 

page_service.js 에서 pageNum 에 한 페이지 당 출력될 글의 갯수 설정 후 연산을 통해 toPage(총 페이지) 설정, startNum 과 endNum 은 DB 에 글의 rownum 연산을 할 때 필요한 값을 선언 ( start 는 현재 몇번째 페이지인지 나타냄 )

 

page_service.js 에서 페이지 정보를 DAO 에 전달하여 연산

 

list.ejs 에서 전달받은 page 의 totPage(토탈 페이지) 값으로 목록을 출력한다

 

서버 실행

 

페이징 처리 완료

 


 

 

 

 

 

댓글

quiz_dbconnect_board.zip
3.00MB

 

위 프로젝트 다운로드 받아서 위와 같이 세팅

 

create table board(
write_no number(10) primary key,
title varchar2(100),
content varchar2(300),
save_date date default sysdate,
hit number(10) default 0,
origin_file_name varchar(100),
change_file_name varchar(100),
id varchar(20) not null,
constraint fk_test foreign key(id) references members(id) on delete cascade
);
create sequence board_seq;

sql developer 에서 쿼리문 작성하여 테이블 생성

 

write no : 글 번호

title : 제목

content : 내용

save_date : 저장 날짜

id : 글 작성자

 

npm install multer@1.4.4 --save

multer npm 설치

( multer - 파일 업로드를 위해 사용되는 Node.js 의 미들웨어 )

 

header.css 작성

* { margin: 0; }
.wrap { width: 1000px; margin: auto; }
.header { width: 1000px; }
.navdiv { width: 100%; background-color: olive; }
.nav { background-color: olive; width: 1000px;}
.nav ul { list-style: none; display: flex;
        justify-content: end; }
.nav ul li { padding: 10px; }

.nav ul li a { text-decoration:none; color:white; }
.nav ul li a:hover{
color: orange; border-bottom: 2px solid black;
transition : all 0.25s; padding-bottom: 3px;
}
.title{ text-shadow: 10px 10px 15px black; 
    font-size: 70pt;
    text-align: center;
    margin-top: 0; 
    padding-bottom: 20px;
    color: burlywood;
    font-family: Gabriola;
}
.content { margin-top: 50px;  }

header.css 코드

 

css 적용을 위해 app.js 에서 /static 설정

 

<link href="/static/css/header.css" rel="stylesheet">
<script >
window.onload = () =>{
    console.log(document.cookie);
    let msg ="<li><a href='/'>HOME</a></li>";
    if(document.cookie.indexOf("isLogin=true") !== -1 ){
        msg += '<li><a href="/member/logout">로그아웃</a></li>';
        msg += '<li><a href="/member/list">회원정보</a></li>';
    }else{
        msg += '<li><a href="/member/login">로그인</a></li>';
        msg += '<li><a href="/member/login">회원정보</a></li>';
    }
    document.querySelector("#nav ul").innerHTML = msg
}
</script>
<div class="wrap">
    <div class="header">
        <h1 class="title">CARE LAB</h1>
    </div>
</div>
<div class="navdiv">
    <div class="wrap">
        <nav id="nav" class="nav">
            <ul></ul>
        </nav>
    </div>
</div>
<hr>

header.ejs 코드 변경 ( link 로 외부 css 파일 적용 )

 

서버 실행 결과

 

board 항목 추가

 

router.js 에 /board 로 접속 시 사용될 boardRouter 선언

 

board_router.js , board_ctrl.js 작성

 

board_service.js 작성

 

DAO 에서 공통으로 사용하는 부분을 common_dao.js 를 생성하여 exports

 

list.ejs 작성

<%- include ("../default/header") %>
<div class="content wrap">
    <table border="1" style="width:100%;">
        <tr>
            <th>번호</th> <th>id</th> <th>제목</th> <th>날짜</th>
            <th>조회수</th> <th>원본 이미지이름</th> <th>변경 이미지이름</th>
        </tr>
        <% if( list.length == 0){ %>
            <tr>
                <th colspan="7">등록된 글이 없습니다</th>
            </tr>
        <%}else{
            list.forEach(data=>{%>
            <tr>
                <td><%=data.WRITE_NO%></td><td><%=data.ID%></td>
                <td><%=data.TITLE%></td><td><%=data.SAVE_DATE%></td>
                <td><%=data.HIT%></td><td><%=data.ORIGIN_FILE_NAME%></td>
                <td><%=data.CHANGE_FILE_NAME%></td>
            </tr>
            <%})
        }%>
        <tr>
            <td colspan="7" align="right">
                <a href="/board/write_form">글 작성</a>
            </td>
        </tr>
    </table>
</div>

list.ejs 코드

 

list.ejs 에서 글 작성을 누르면 이동되는 경로인 /write_form 경로를 board_router.js 에 작성

 

세션을 체크하는 부분과 메세지를 출력하는 공통 기능을 ser_common.js 파일을 생성하여 작성

 

세션을 통해 로그인 정보를 확인한 뒤 로그인 상태라면 board/write_form 경로로 이동시킴

 

write_form.ejs 작성

<%- include ("../default/header") %>
<script src="/static/js/image_read.js"></script>
<div class="content wrap">
    <div style="width: 400px; margin: 0 auto; ">
        <h1 style="text-align: center">글쓰기</h1>
        <form method="post" action="/board/write" 
                                        enctype="multipart/form-data">
            <b>작성자</b><br>   <!-- readonly : 읽기 전용 -->
            <input type="text" name="id" value="<%= username %>" readonly />
            <hr>
            <b>제목</b> <br> <input type="text" size="50" name="title" /><hr>
            <b>내용</b> <br>
            <textarea name="content" rows="10" cols="50"></textarea><hr>
            <b>이미지파일 첨부</b><br>
            <input type="file" name="image_file_name" onchange="readURL(this);" /> 
            <img id="img" src="#" width=100 height=100 alt="선택된 이미지가 없습니다" />
            <hr> 
            <input type="submit" value="글쓰기">
            <input type=button value="목록보기" onClick="location.href='/board/list'">
        </form>
    </div>
</div>

write_form.ejs 코드

 

public 폴더 하위에 js 폴더에 image_read.js 작성 ( 이미지 미리보기 부분 구현 )

const readURL = (input) => {
    console.log(input);
    console.log(input.files[0]);
    const file = input.files[0];
    if(file != ""){
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
            console.log(e.target.result);
            // 파일에 대한 정보가 담겨있는 곳
            document.getElementById("img").src = e.target.result;
        }
    }
}

image_read.js 코드

 

서버 실행 ( 글 작성 진입 및 이미지 미리보기까지 구현 )

 

config - file - file_config.js 생성 및 작성

const multer = require("multer");
const stg = multer.diskStorage({
    destination : ( req , file, cb ) => {
        cb(null,  "upload_file")
    },
    filename : ( req, file, cb) => {
        cb(null, Date.now()+"-"+file.originalname );
    }
})
const f_filter = (req, file, cb)=>{
    const type = file.mimetype.split("/");
    if( type[0] == "image" ){
        cb(null, true);
    }else{
        req.fileValidation = "이미지만 저장하세요";
        cb(null, false);
    }
}
const upload = multer({storage : stg, fileFilter : f_filter })
module.exports = upload;

file_config.js 코드

 

board_router.js 에&nbsp; 이미지 업로드를 post 로 받을때 이동 될 /write 설정

 

이미지가 저장될 upload_file 폴더를 프로젝트 바로 하위에 생성

 

board_controller 작성

 

board_service.js 작성 ( 이미지 형식이 아닐 경우 alert 발생 )

 

board_dao.js 에 boardInsert 작성

 

코드 실행

 

ser_common.js 에서 시간을 지정하는 함수 생성

 

board_service.js 에 ser_common 을 require 했던 부분을 제일 상단으로 올려준 뒤 list 의 값을 timeModify 함수에 집어 넣어 변경 후 list 를 반환한다

 

시간 설정 완료

 

728x90

+ Recent posts