[Servlet] 게시판 만들기

2025. 3. 6. 18:55·Web
  • 게시판 글 쓸때 Editor를 사용
  • [국내 - WEB EDITOR]
    • 1. Daum Editor(Kakao)
    • 2. Naver Editor
    • 3. Namo Editor
  • [국외 - WEB EDITOR]
    • 1. CKEditor
    • 2. Toast Editor - React전용
    • 3. DEXTUpload Editor
    • 4. Quill Editor - Vue전용
  • WEB EDITOR의 글은 코드 형식으로 DB에 저장! 

CKEditor

  • 버전, 다운로드 
    • LTS는 유료임 작동X
    • CKEditor4 > Full Package > Easy Image 체크하지않고 다운해서 적용하기  
    • 압축 풀어서 ckeditor 아래사진 항목만 사용 why? 다른 파일 넣으면 보안 쓰레기됨

 

  • 이미지 미리보기에 주저리주저리 지우기 셋팅
    • ./ckeditor/plugins/image/dialogs/image.js 에서 Lorem ipsum검색
    • 해당 따옴표 안을 모두 비우기
  • 버전 보안 빨간 알림창 지우기
    • ./ckeditor/config.js 파일의 함수 안에
    • config.versionCheck = false; 넣기
  • 에디터 상단 기능을 핸들링 (필요한 기능만 쓰기, 물음표,버전 안보이게하기)
    • 에디터 홈페이지 > Customize > Online Builder > 필요한건 넣고 필요없는건 빼기
      > 최하단 Download CKEditor (OS) 다운해서 config.js파일만 덮어쓰기함
    • 거기에 알람지우는 config.versionCheck = false; 만 추가하기 
  • 이놈은 textarea 마냥 resize가 됨 줄었다 늘었다.. 그거 세팅
    • config.js파일에 config.resize_enable = false; 추가

DB 설계시 주의사항

html에는 없지만 넣어야하는 것들

아이디가 없지만 아이디를 히든으로 해서 HTML에 넣어줘야함

DB에 같이 넣어줘야함 

+ "아이디" 넣어야함 !

+ "작성 날짜, 시간"도 넣어야함 !

+ "조회수"도 넣어야함 !

+ 추천이있는 게시판이라면 추천수도 !

=> 게시판은 항상 리스트를 같이 봐야함 !  

 

첨부파일 처리시 

사용자 첨부파일 => 123.xlsx => Server => 20250306_123.xlsx

이렇게 해야 덮어쓰기되지 않음 !

사용자가 게시판 첨부파일 확인시

123.xlsx => 20250306_123.xlsx

DB엔 "파일 이름", "파일 경로" 를 넣으며 null 속성을 넣어줌 ! 파일 첨부 안할수도 있으니까 


notice_write.html

글쓰기 페이지

+ notice_write.js

게시물 등록시 체크

↓

notice_writeok.java (servlet)

html에서 넘어온 정보와 기타 정보들을 합쳐서 DB에 저장하는 Controller

+ m_notice.java (class)

첨부파일이 있을 경우 DB에 저장하는 Model

↓

게시판 먼저 출력할때 notice_list.do

notice_list.java (servlet) 

게시판 리스트를 출력하기 위해 DB의 모든 게시물 데이터들을 가져오는 Controller

+ m_noticelist.java (class)

DB에 있는 모든 데이터를 가져오는 Model

↓

notice_list.jsp

게시판을 출력, 게시물 클릭시 해당 게시물로 이동

↓

notice_view.java (servlet)

게시물 출력을 위한 Controller

+ m_noticeview.java (class)

Database에 Table 사항 중 where 및 조회수 증가 Model

↓

notice_view.jsp

게시물을 출력

글 수정, 글 삭제 버튼 (미구현)

 


notice_write.html

글쓰기 페이지

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 글등록 페이지</title>
<script src="./ckeditor/ckeditor.js?v=6"></script>
</head>
<body>

<form id="frm" method="post" action="./notice_writeok.do" enctype="multipart/form-data">
제목 : <input type="text" name="subject"><br>
글쓴이 : <input type="text" name="writer"><br>
비밀번호 : <input type="password" name="pw"><br>
내용 : <textarea name="texts" id="editor"></textarea><br>
첨부파일 : <input type="file" name="nfile"><br>
<input type="button" value="글등록" onclick="writeck()">
</form>

</body>
<script>
//window.onload : 현재 페이지가 실행됐을때
//이건 꼭 하단 스크립트에 적어야함! 
	window.onload = function() {
		var ck = CKEDITOR.replace("editor", {
			width : 900,
			height : 400,
			versionCheck : false
		});
	}
</script>
<script src="./notice_write.js?v=1"></script>
</html>
  • 첨부파일 핸들링시 필수사항
    • 1. post로 전송 
    • 2. enctype 속성
    • 3. @MultipartConfig (servlet)
  • window.onload : 현재 페이지가 실행됐을때
    • 이건 꼭 하단 스크립트에 적어야함! 
  • 에디터 핸들링
    • window.onload 함수에 editor 올리기 

notice_write.js

게시물 등록시 체크

//게시물 등록시 체크하는 함수 
//여기에 texts 게시판 내용을 체크하면 망가짐 => 내용을 넣어도 안넣었다고 인식 ! 주의 
function writeck(){
	if(frm.subject.value==""){
		alert("제목을 입력하셔야 합니다.");
		frm.subject.focus();
	}else if(frm.writer.value==""){
		alert("글쓴이를 입력하셔야 합니다.");
		frm.writer.focus();
	}else if(frm.pw.value==""){
		alert("비밀번호를 입력하셔야 합니다.");
		frm.pw.focus();
	}else {
		//CKEDITOR.instances.HTML의 id명.getData() : ckeditor를 로드
		var txt = CKEDITOR.instances.editor.getData();
		if(txt == ""){
			alert("내용을 입력하셔야합니다.")
		}else if(txt.length < 40){	//엔터바바박 방지 
			alert("최소 40자 이상 입력되어야 합니다.");
		}else{
			frm.submit();
		}
	}
}
  • 에디터의 내용을 확인할 때
    • input 태그의 name으로 핸들링 불가능!
    • ckeditor를 로드해서 확인해야 함

notice_writeok.java (servlet)

html에서 넘어온 정보와 기타 정보들을 합쳐서 DB에 저장하는 Controller

package notice;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import shop.m_dbinfo;
import shop.m_md5;

//원래는 컨트롤러에 10줄도 안씀! 다 모델로 만들어야함 !!! 
//실무에서 이렇게 만들면 욕을 바가지로 먹는다 !!!

//파일첨부시 필수 ! 
@MultipartConfig(
	fileSizeThreshold = 1024 * 1024 * 5,	//파일하나 5MB
	maxFileSize = 1024 * 1024 * 50,			//파일들의 총 용량 50MB
	maxRequestSize = 1024 * 1024 * 500		//파일이 여러개 날아올때만 필요한 라인 //파일 하나만 날아올땐 필요없음 
)
public class notice_writeok extends HttpServlet {
	private static final long serialVersionUID = 1L;
	Connection con = null;
	//ResultSet 필요없음! 쓰기 할거니까
	PreparedStatement ps = null;
	PrintWriter pw = null;
	//Model
	m_dbinfo db = new m_dbinfo();	//DB 접속 정보 
	m_md5 md5 = new m_md5();		//md5 암호화 
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		this.pw = response.getWriter();
		
		//첨부파일이 있고, 없고 따라서 SQL 저장방식이 변경됨 
		Part nfile = request.getPart("nfile");
		long filesize = nfile.getSize();	//getSize()는 long값으로 return해줌
		
		try {
			this.con = this.db.getConnection();		//DB 연결 
			String subject = request.getParameter("subject");
			String writer = request.getParameter("writer");
			String pw = request.getParameter("pw");
			String texts = request.getParameter("texts");
			
			//패스워드를 암호화
			pw = this.md5.md5_code(pw);
			
			String sql = "";	//DB Query문 
			int result = 0;		//DB에서 저장된 결과를 받는 변수 (저장되면 1) select에는 필요없음 i,u,d에만 필요  
			
			if(filesize == 0) {		//첨부파일이 없을 경우
				sql = "insert into notice (nidx,subject,writer,pw,texts,ndate)"
						+ "values ('0',?,?,?,?,now())";
				this.ps = this.con.prepareStatement(sql);
				this.ps.setString(1, subject);
				this.ps.setString(2 , writer);
				this.ps.setString(3, pw);
				this.ps.setString(4, texts);
				//System.out.println(sql);
				result = this.ps.executeUpdate();	//DB에 저장 
				if(result > 0) {	//저장이 된 경우 
					this.pw.write("<script>"
							+ "alert('게시물이 올바르게 등록되었습니다.');"
							+ "location.href = './notice_list.jsp';"
							+ "</script>");
				}else {	//저장이 안된 경우 
					
				}
				
			}else {		//첨부파일이 있을 경우 
				//Model을 이용하여 첨부파일을 저장하는 방식 
				m_notice nt = new m_notice(nfile,subject,writer,pw,texts,request);
				//return 메소드가 private이므로 전역변수의 값을 직접 로드 
				String msg = nt.msg;	//모델의 필드에 올라온 변수는 이렇게 처리 가능 
				//리턴 받으려고 굳이굳이 public사용하지 않아도됨 !! 필드 사용하기
				
				if(msg.equals("ok")) {
					this.pw.write("<script>"
							+ "alert('올바르게 공지사항이 등록되었습니다.');"
							+ "location.href = './notice_list.jsp';"
							+ "</script>");
				}else {
					this.pw.write("<script>"
							+ "alert('데이터베이스 및 첨부파일 오류 발생');"
							+ "history.go(-1);"
							+ "</script>");
				}
			}
			
		}catch (Exception e) {
			this.pw.write("<script>"
					+ "alert('데이터베이스 문제로 인하여 저장되지 않았습니다.');"
					+ "history.go(-1);"
					+ "</script>");
		}finally {
			try {
				this.ps.close();
				this.con.close();
				this.pw.close();
			}catch (Exception e) {
				
			}
		}
	}
}
  • 저장이 잘 되었을 경우 notice_list.jsp로 이동
  • 저장이 안된 경우 에러메세지 출력 후 이전페이지로 이동

m_notice.java (class)

위 서블릿파일에서 사용

첨부파일이 있을 경우 DB에 저장하는 Model

package notice;

import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import shop.m_dbinfo;

//공지사항 게시판 파일을 저장하는 Model 
//원래 DTO도 써야됨 !!
public class m_notice extends HttpServlet{
	Connection con = null;
	PreparedStatement ps = null;
	m_dbinfo db = new m_dbinfo();	
	
	String sql = "";	//DB 쿼리문 
	int result = 0;		//DB 저장 결과값 
	String msg = "";	//Model에서 처리된 값을 Controller로 결과값을 반환 
	String subject,writer,pw,texts;		//ArrayList로 만들어도됨

	//즉시실행메소드에서는 첨부파일을 저장하는 역할만 수행 => 다른메소드에서 DB로 연결  
	public m_notice(Part nfile,String subject,String writer,String pw,String texts,HttpServletRequest request) throws Exception{
		//DTO를 안만들어서 이모양으로 해야함 
		this.subject = subject;
		this.writer = writer;
		this.pw = pw;
		this.texts = texts;
		
		long filesize = nfile.getSize();	//파일 용량 
		String filenm = nfile.getSubmittedFileName();	//파일명 
//		System.out.println(request.getServletContext().getRealPath(""));	//파일 저장 경로 확인
		String url = request.getServletContext().getRealPath("/notice_file/");	//첨부파일 저장될 Web Directory 설정 
		try {//io니까 트캐 넣기 
			nfile.write(url + filenm);	//웹에 저장 
			this.fileok(filenm);	//정상적으로 저장되었을 경우 
		}catch (Exception e) {
			this.fileok("error");	//비정상적으로 해당 디렉토리에 파일이 저장되지 않을 경우 
		}
	}
	
	//DB로 저장 및 Controller로 결과값을 return하는 메소드 
	private String fileok(String data) throws Exception{
		if(data.equals("error")) {
			this.msg = "error";
		}else {	//파일이 정상적으로 저장되었을 경우 
			try {
				this.con = this.db.getConnection();
				this.sql = "insert into notice (nidx,subject,writer,pw,texts,filenm,nfile,ndate)"
						+ "values ('0',?,?,?,?,?,?,now())";
				this.ps = this.con.prepareStatement(sql);
				this.ps.setString(1, this.subject);
				this.ps.setString(2, this.writer);
				this.ps.setString(3, this.pw);
				this.ps.setString(4, this.texts);
				this.ps.setString(5, data);
				this.ps.setString(6, data);
				//물음표개수랑 setString개수 다르면 에러남 !
				this.result = this.ps.executeUpdate();
				
				if(result > 0) {	//저장이 된 경우 
					this.msg = "ok";
				}else {	//저장이 안된 경우 
					this.msg = "error";
				}
			}catch (Exception e) {
				this.msg = "error";
			}finally {
				//원래 여기에 트캐 넣어야하는데 throws사용 => 즉시실행 메소드에도 throws 사용 
				//서블릿에서는 post메소드 스스로 만들어져있어서 못썼었지만 모델에서는 가능  
				this.ps.close();
				this.con.close();
			}
		}
		return this.msg;	//Controller로 보내는 값 
	}
}

 

notice_list.java (servlet)

게시판 리스트를 출력하기 위해 DB의 모든 게시물 데이터들을 가져오는 Controller

package notice;

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

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class notice_list extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//사용자가 페이지 번호를 클릭시 해당 값을 받는 역할 
		String pageno = request.getParameter("pageno");
		
		//페이지번호 인티저로 받으면 null일때 parseInt에서 오류남 
		//String으로 받고 조건 확인하고 parseInt로 넘기기 
		if(pageno == null || pageno.equals("1")) {	//게시판 최초 접속 or 1번 페이지일때  페이지 배열번호 0으로 처리 
			pageno = "0";
		}
		
		//list를 출력하기 위한 Database Table을 로드하는 Model
		m_noticelist nl = new m_noticelist(Integer.parseInt(pageno));
		//2차 클래스배열로 저장된 Table에 모든 데이터를 셋팅함 
		ArrayList<ArrayList<String>> result = nl.db_data();
		
		//JSP로 2차 클래스 배열 값을 전달(View)
		request.setAttribute("result", result);
		request.setAttribute("pageno", pageno);
//		System.out.println(result);
		RequestDispatcher rd = request.getRequestDispatcher("./notice_list.jsp");
		rd.forward(request,response);
	}
}
  • 페이징
    • pageno : 페이지 번호 
    • View에서 넘어오는 경우 => 자료형 String
    • 숫자라고 int로 받은 경우 null 처리 불가능
    • null 값을 받는다고 Integer로 설정시 View에서는 String으로 넘어오는데 Integer.parseInt()가 null을 처리불가능
    • => String으로 받고 조건문으로 처리 후 다른곳으로 넘길 때 Integer로 변환하여 넘기기 
  • 최초접속 or 1번째 페이지 선택시 => pageno = 0
  • 리스트를 출력해주는 Model에 페이지 번호를 인수값으로 넣어 전달 

m_noticelist.java (class)

위 서블릿파일에서 사용

DB에 있는 모든 데이터를 가져오는 Model

package notice;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import shop.m_dbinfo;

//DB에 있는 모든 데이터를 가져오는 역할(Model)
public class m_noticelist {
	Connection con = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	String sql;	//sql Query
	
	m_dbinfo db = new m_dbinfo();
	ArrayList<String> data = null;	//1차배열 각 컬럼별 값을 저장 
	ArrayList<ArrayList<String>> alldata = null;	//Database 전체 데이터를 저장 

	int spage = 0; //첫번째 배열값
	int ea = 3;		//페이지당 출력할 게시물 수 
	
	public m_noticelist(int s) {
		if(s > 0){	//1번 페이징 번호 외의 번호를 클릭했을 경우 
			//(페이지번호 -1) * 한 페이지당 출력할 갯수 
			this.spage = (s - 1) * ea;
		}else {
			this.spage = s;		//sql query문의 limit를 사용하기 위함 
		}
	}
	
	public ArrayList<ArrayList<String>> db_data(){
		try {
			this.con = db.getConnection();
			//필요한 컬럼만 지정하여 select 문법으로 데이터를 가져오는 코드 
			this.sql = "select nidx,subject,writer,nview,ndate,(select count(*) from notice) as total from notice order by nidx desc limit ?,?";	//nidx도 가져와야함!!
			this.ps = this.con.prepareStatement(this.sql);
			this.ps.setInt(1, this.spage);
			this.ps.setInt(2, this.ea);
			
			this.rs = this.ps.executeQuery();	//select여서 executeQuery쓴거임 
			
			//반복문으로 Table에 있는 컬럼을 1차 배열로 이관 후 2차배열에 담는 코드  
			this.alldata = new ArrayList<>();
			while(this.rs.next()) {
				this.data = new ArrayList<>();
				this.data.add(this.rs.getString("nidx"));
				this.data.add(this.rs.getString("subject"));
				this.data.add(this.rs.getString("writer"));
				this.data.add(this.rs.getString("nview"));
				this.data.add(this.rs.getString("ndate"));
				this.data.add(this.rs.getString("total"));	//게시물 전체 갯수 저장한 값 
				this.alldata.add(this.data);
			}
//			System.out.println(this.alldata);
		}catch (Exception e) {
			this.alldata = null;
		}finally {
			try {
				this.ps.close();
				this.con.close();
			}catch (Exception e) {
				this.alldata = null;
			}
		}
		//Model에서 Controller로 데이터를 회신함 
		return this.alldata;
	}
}
  • 페이징
    • spage : limit 시작 인덱스 (첫번째 배열값) 
      • 0일때 : Controller에서 넘어온 pageno 그대로 사용 (0)
      • 0이 아닐때 : (pageno -1) * 한페이지출력개수
  • 즉시실행 메소드 실행 : 모델의 페이지번호 설정
  • 설정해둔 페이지번호를 이용해 해당 페이지의 데이터 가져옴 

notice_list.jsp

게시판을 출력, 게시물 클릭시 해당 게시물로 이동

<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
ArrayList<ArrayList<String>> notice = (ArrayList<ArrayList<String>>)request.getAttribute("result");
//페이지 번호 생성
/* 
페이징 생성방법
1. 한 페이지당 몇개씩 데이터를 출력할 것인지를 설정합니다.
2. 데이터베이스에 있는 데이터의 총 갯수 / 한페이지당 갯수 (소수점)
3. Math.ceil 사용하는 이유는 1.1 1.6 => 올림으로 페이지가 추가 되도록 합니다.
*/
String total_page = notice.get(0).get(5);
int pg = 1;
if(total_page != null || !total_page.equals(null)){
	float pg2 = Integer.parseInt(total_page) / 3f;
	pg = (int)Math.ceil(pg2); 
}

/*
get page번호를 가져오는 방식
최초 공지사항 리스트 페이지에 접근시 페이지 번호가 없을 수 있음 또는 
페이지번호가 1을 클릭했을 경우
*/
String pno = request.getParameter("pageno");
if(pno == null || pno.equals("1")){
	pno = "1";
}
%>
<!-- View -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 리스트</title>
</head>
<body>
<p>현재 등록된 게시물 : <%=notice.get(0).get(5)%></p>
<table border="1" cellpadding="0" cellspacing="0">
<thead>
	<tr>
		<th width="50">번호</th>
		<th width="500">제목</th>
		<th width="100">글쓴이</th>
		<th width="100">조회</th>
		<th width="150">등록일</th>
	</tr>
</thead>
<tbody>
<%
	int f;
	//리스트 출력 번호를 총 데이터 갯수로 처리
	//총 데이터 갯수 - ((페이지번호 - 1) * 한페이지당 출력갯수)
	int total = Integer.parseInt(total_page) - ((Integer.parseInt(pno)-1) * 3);	
	for(f=0; f<notice.size(); f++){
%>
	<tr height="30" align="center">
		<td><%=total%></td>
		<td align="left" onclick="notice_view('<%=notice.get(f).get(0)%>')"><%=notice.get(f).get(1)%></td>
		<td><%=notice.get(f).get(2)%></td>
		<td><%=notice.get(f).get(3)%></td>
		<td><%=notice.get(f).get(4).substring(0,10)%></td>
	</tr>
<%
	total--;
	}
%>	
</tbody>
</table>
<br><br><br>
<table border="1">
<tr>
<% 
	int w = 1;
	while(w <= pg){
%>
<td width=20 height=20 align="center"><a href="./notice_list.do?pageno=<%=w%>"><%=w%></a></td>
<%
	w++;
	}
%>
</tr>
</table>
</body>
<script>
function notice_view(no){
	//해당 게시물의 내용 및 첨부파일을 확인 할 수 있는 view 페이지
	location.href='./notice_view.do?nidx='+no;
}

</script>
</html>
  • 상단에서 이전 servlet에서 받아온 DB의 모든 게시판 데이터를 로드
  • 게시물 수 : 배열의 크기
  • 테이블에 반복문 적용
    • 배열의 크기(게시물의 수)만큼 반복
    • 게시물의 정보를 출력
    • 제목 클릭시 해당 게시물 페이지로 이동 
    • 날짜는 DB에 시간까지 적용되어있음 => substring() 이용하여 "년월일" 만 출력 
  • 페이징
    • total_page : Controller에서 넘어온 notice 배열의 total => 게시물의 총 개수
      • pno : total_page가 null이 아닐때 한페이지출력개수만큼 나눈것을 올림 => 페이지 번호 
  • 게시물 번호
    • total : 총데이터개수 - ( (페이지번호 -1) * 한페이지당출력개수 )
    • 반복문 돌리며 total--;

notice_view.java (servlet)

게시물 출력을 위한 Controller

package notice;

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

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class notice_view extends HttpServlet {
	private static final long serialVersionUID = 1L;
  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		int nidx = Integer.parseInt(request.getParameter("nidx"));
//		System.out.println(nidx);
		
		//조회수 +1 증가 및 데이터를 출력 
		m_noticeview mv = new m_noticeview();
		mv.viewcount(nidx);
		
		//게시물 1개의 데이터 내용을 JSP로 전달 
		ArrayList<String> notice_v = mv.db_data;
//		System.out.println(notice_v);
		request.setAttribute("notice_v", notice_v);
		
		RequestDispatcher rd = request.getRequestDispatcher("./notice_view.jsp");
		rd.forward(request, response);
	}
}

 

m_noticeview.java (class)

위 서블릿파일에서 사용

Database에 Table 사항 중 where 및 조회수 증가 Model

package notice;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import shop.m_dbinfo;

//Database에 Table 사항 중 where 및 조회수 증가
//Query : select, update
public class m_noticeview {
	Connection con = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	
	String sql = "";	//Query문법
	m_dbinfo db = new m_dbinfo();	//Database 정보 
	
	ArrayList<String> db_data = null;	//한개의 데이터 그룹만 저장시킴 
	
	public void viewcount(int nidx) {
		
		try {
			this.con = this.db.getConnection();
			//해당 컬럼에 값을 +1씩 증가시키는 Query문 
			this.sql = "update notice set nview= nview+1 where nidx=?";
			this.ps = this.con.prepareStatement(this.sql);
			this.ps.setInt(1, nidx);		//nidx는 숫자니까 setInt
			this.ps.executeUpdate();		//Query문을 실행!@!
			
			//해당 테이블에 맞는 컬럼 값을 select 함
			this.sql = "select * from notice where nidx=? order by nidx desc";
			this.ps = this.con.prepareStatement(this.sql);
			this.ps.setInt(1, nidx);
			this.rs = this.ps.executeQuery();
			if(this.rs.next() == true) {	//해당 조건에 맞는 데이터가 있을 경우 
				this.db_data = new ArrayList<>();
				this.db_data.add(this.rs.getString("nidx"));
				this.db_data.add(this.rs.getString("subject"));
				this.db_data.add(this.rs.getString("writer"));
				this.db_data.add(this.rs.getString("pw"));
				this.db_data.add(this.rs.getString("texts"));
				this.db_data.add(this.rs.getString("filenm"));
				this.db_data.add(this.rs.getString("nfile"));
				this.db_data.add(this.rs.getString("nview"));
				this.db_data.add(this.rs.getString("ndate"));
			}
			
			
			
		}catch (Exception e) {
			
		}finally {
			try {
				this.ps.close();
				this.con.close();
			}catch (Exception e) {
				
			}
		}
	}
}

 

notice_view.jsp

게시물을 출력

글 수정, 글 삭제 버튼

<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
//Controller에서 1차 클래스 배열값을 JSP애서 받아서 출력하는 방식
ArrayList<String> views = (ArrayList<String>)request.getAttribute("notice_v");
if(views == null){	//데이터가 없을 경우 script 발동 후 리스트 페이지로 이동 
	out.print("<script>alert('올바른 접근이 아닙니다'); location.href='./notice_list.do';</script>");
}else{		//null이 아닐 경우 HTML을 활성화 
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 내용확인</title>
<style>
.data1{
width:400px;
height:30px;
line-height:30px;
border-bottom: 1px solid gray;
}
.n{
display:flex;
flex-direction: row;
justify-content: flex-start;
align-content: center;
}
.data2{
border:1px solid gray;
width:800px;
height:400px;
overflow-y:auto; 
}
</style>
</head>
<body>
<span class="n">등록일 : <div class="data1"><%= views.get(8)%></div></span><br>
<span class="n">제목 : <div class="data1"><%= views.get(1)%></div></span><br>
<span class="n">글쓴이 : <div class="data1"><%= views.get(2)%></div></span><br>
<span class="n">조회수 : <div class="data1"><%= views.get(7)%></div></span><br>
<span class="n">내용 : <div class="data2"><%= views.get(4)%> </div></span><br>

<%
if(views.get(5) != null){	//첨부파일이 있을 경우만 해당 태그가 작동되도록 설정함 
%>
<span class="n">첨부파일 : <div class="data1">
<a href="../notice_file/<%= views.get(5)%>" target="_blank"><%= views.get(5)%></a>
</div></span><br>
<%
}
%>
<br><br>

<!-- 패스워드 확인 후 데이터 삭제 -->
<form id="frm" method="post" action="./notice_delete.do">
<!-- 자동증가값을 hidden에 적용하여 form 전송 -->
<input type="hidden" name="nidx" value="<%= views.get(0)%>">
<!-- DB에 저장된 MD5 암호화 패스워드 -->
<input type="hidden" name="ori_pw" value="<%= views.get(3)%>">
<!-- 사용자가 해당 게시물에 패스워드를 입력한 값 -->
패스워드 : <input type="password" name="npw">
</form>

<br><br>
<input type="button" value="글목록" onclick="notice_info(1)">
<input type="button" value="글수정" onclick="notice_info(2)">
<input type="button" value="글삭제" onclick="notice_info(3)">
</body>

<script>
function notice_info(p){
	switch(p){
	case 1:
		location.href='./notice_list.do';
	break;
	case 2:
		location.href='./notice_modify.do';
	break;
	case 3:
		if(confirm("해당 게시물을 삭제시 복구되지 않습니다.")){
			if(frm.npw.value==""){
				alert("게시물 삭제시 패스워드를 입력하셔야 합니다.");
			}else{
				frm.submit();
			}
		}
	break;
	}
}
</script>
</html>
<%
}
%>

notice_delete.java (servlet)

게시물을 삭제하는 Controller

package notice;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//Database 게시물 삭제 처리 Controller

import shop.m_dbinfo;
import shop.m_md5;
public class notice_delete extends HttpServlet {
   private static final long serialVersionUID = 1L;
    
   Connection con = null;
   PreparedStatement ps= null;
   String sql = null;
   int result = 0;
   m_dbinfo db = new m_dbinfo(); //DB 정보
   m_md5 md5 = new m_md5(); //MD5 암호화
   PrintWriter pw = null;
   
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      response.setContentType("text/html;charset=utf-8");
      String nidx = request.getParameter("nidx");
      String ori_pw = request.getParameter("ori_pw");
      String npw = request.getParameter("npw");
      this.pw = response.getWriter();
      try {
         //사용자가 입력한 패스워드와 자동 증가값이 올바르게 (post전송)전달되지 않을 경우 작동 해제시킴
         if(nidx.equals(null)||npw.equals(null)) {
            this.pw.write("<script>"
                  + "alert('올바른 접근이 아닙니다.');"
                  + "history.go(-1);"
                  + "</script>");
         }else {
            npw = md5.md5_code(npw); //사용자가 입력한 패스워드를 md5로 변환후 DB의 패스워드와 비교 
            if(npw.equals(ori_pw)) {
               this.con = this.db.getConnection(); //DB연결
               this.sql = "delete from notice where nidx=?";
               this.ps = this.con.prepareStatement(this.sql);
               this.ps.setString(1, nidx);
               this.result = this.ps.executeUpdate();
               System.out.println(this.result);
               if(this.result > 0) {
                  this.pw.write("<script>"
                        + "alert('게시물을 삭제하였습니다.');"
                        + "location.href='./notice_list.do';"
                        + "</script>");
               }
            }else {
               this.pw.write("<script>"
                     + "alert('패스워드가 틀립니다.');"
                     + "history.go(-1);"
                     + "</script>");
            }
         }
      } catch (Exception e) {
         this.pw.write("<script>"
               + "alert('Database삭제 오류 발생!!');"
               + "history.go(-1);"
               + "</script>");
      }finally {
         try {
            this.ps.close();
            this.con.close();
            this.pw.close();
            
         } catch (Exception e2) {
            System.out.println("DB 접속에 따른 해제권한 오류 발생!!");
         }
      }
   }
}
저작자표시 비영리 변경금지 (새창열림)
'Web' 카테고리의 다른 글
  • [Servlet] 아이디 찾기, 비밀번호 변경
  • [Servlet] 제휴 메일 시스템
  • [jQuery] 기초
  • [Javascript] 정규식 코드
9na0
9na0
응애
  • 9na0
    구나딩
    9na0
  • 전체
    오늘
    어제
    • 분류 전체보기 (211)
      • Web (118)
      • Java (28)
      • 데이터베이스 (14)
      • 세팅 (12)
      • 과제 (3)
      • 쪽지시험 (2)
      • 정보처리기사 (4)
      • 서버 (25)
  • 블로그 메뉴

    • 링크

      • 포폴
      • 구깃
    • 공지사항

    • 인기 글

    • 태그

      file25_t
      file24
      java_io1~10
      spring-boot
      net4
      exam1_1~10
      net2
      Oracle
      ab1
      re2
      macbook pro m4
      notice_writer
      net1
      re_java10
      net5~10
      file25
      noticewriteok
      datalist
      io_dto
      net3
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    9na0
    [Servlet] 게시판 만들기
    상단으로

    티스토리툴바