본문 바로가기
CLASS/JSP

#4-5 / 상품 리뷰 등록,list,삭제,수정

by hingu 2024. 6. 28.

with 짝꿍

A part :

리뷰 등록페이지 A (고객명,제목,textarea,radio로 점수,첨부파일 / insert) => product_insert.jsp

파일첨부는 필수 아님

 

B part : 

리뷰 출력 리스트 페이지 B (sql select 활용)

삭제버튼 클릭시 데이터 삭제

단,첨부파일 있을 경우 첨부파일명 출력

=> review_list.jsp

 

⚡ DB table 생성

create table review(
ridx int(8) not null auto_increment,
rname varchar(100) not null,
rsubject varchar(200) not null,
rtext text not null,
rscore int(1) not null default '1',
rfile text null,
rdate timestamp not null default current_timestamp,
primary key(ridx)
);

 

⚡ 리뷰 등록

- insert.jsp
<body>
	<form id="frm" enctype="multipart/form-data">
		<p>상품 리뷰 등록</p>
		<input type="text" name="rname" placeholder="고객명"><br>
		<input type="text" name="rsubject" placeholder="제목"><br>
		<textarea rows="10" cols="25" name="rtext" placeholder="내용"></textarea><br>
		<label><input type="radio" name="rscore" value="5" checked>5점</label>
		<label><input type="radio" name="rscore" value="4">4점</label>
		<label><input type="radio" name="rscore" value="3">3점</label>
		<label><input type="radio" name="rscore" value="2">2점</label>
		<label><input type="radio" name="rscore" value="1">1점</label>
		<br><br>
		<input type="file" name="rfile"><br><br>
		<button type="button" onclick="review_in()">리뷰등록</button>
	</form>	
</body>
<script type="text/javascript">
	function review_in(){
		frm.method = "post";
		frm.action = "./review_insertok.jsp";
		
		var f = frm.rfile.value;
		if(f != ""){ //첨부가 되었을 때
			var filesize = document.getElementsByName("rfile")[0].files[0].size;
			if(filesize > 2097152){ //2MB - 용량체크
				alert("첨부파일 용량은 2MB까지 입니다.")
			}else{
				frm.submit();
			}
		}else{
			frm.submit();
		}
	} 
</script>

 


🔽

- review_insertok.jsp : 실제 jsp는 아님.. (servlet임)
=> web.xml에서 servlet 파일을 do가 아닌 .jsp로 세팅, 실제 jsp명과 겹치면 x
     name value값을 가져와서 r_ok.jsp로 보내고 r_ok.jsp에서 insert 해줄거임

setAttribute : jsp(view part)로 값 전달시 사용
getAttribute : java에서 jsp로 값을 가져올때만 사용
=> 배열로 전달해서 받는게 좋다

@MultipartConfig(
	fileSizeThreshold = 1024*1024*2,
	maxFileSize = 1024*1024*4,
	maxRequestSize = 1024*1024*10
)
public class review_insertok extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private InputStream is = null;
	private FileOutputStream fs = null;
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=uft-8");
		
		String rname = request.getParameter("rname");
		String rsubject = request.getParameter("rsubject");
		String rtext = request.getParameter("rtext");
		String rscore = request.getParameter("rscore");
		Part rfile = request.getPart("rfile");
		
		//웹 디렉토리 저장 경로
		String url = request.getServletContext().getRealPath("/upload/");
		String filename = rfile.getSubmittedFileName();
		String result = ""; //첨부파일이 없으면 걍 ""
		if(!filename.equals("")) { //첨부파일이 있을때
			this.is = rfile.getInputStream();
			//이름변경
			rename rn = new rename(filename);
			result = rn.filenm; //변경된 이름을 변수로받음
			
			this.fs = new FileOutputStream(url+result);
			byte[] bg = new byte[1024*2];
			int size = 0;
			//1도트가 깨질 수도 있음
			do {
				this.fs.write(bg,0,size); //실제 저장
			}while((size=this.is.read(bg)) != -1);
			
			//첨부파일이 있을경우엔 경로를 붙여줘야해서 if안에 작성
			request.setAttribute("rfile", "http://172.30.1.83:8080/upload/"+result);	
		}else {
			request.setAttribute("rfile", result);			
		}
		//setAttribute : r_ok.jsp(view part)로 값 전달 위해 => 배열로 하는게 좋다
		request.setAttribute("rname", rname);
		request.setAttribute("rsubject", rsubject);
		request.setAttribute("rtext", rtext);
		request.setAttribute("rscore", rscore);
		
		RequestDispatcher rd = request.getRequestDispatcher("./r_ok.jsp");
		rd.forward(request, response);
		
		this.fs.close();
		this.is.close();
	}
}



- rename.java : 이름을 재구성하여 결과값을 리턴하는 module

public class rename {
	String filenm = "";
	public rename(String z) {
		this.filenm = z;
		this.re();
	}
	
	private void re() {
		Date today = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
		String day = sf.format(today); 
		
		String rnd = String.valueOf((int)Math.ceil(Math.random()*1500)); //랜덤숫자
		
		//실제 파일에서 속성명만 추출
		int dot = this.filenm.lastIndexOf(".");
		String property = this.filenm.substring(dot+1);
		
		this.filenm = day+"_"+rnd+"."+property; //20240628_636.jpg 요런형태
	}
}



🔽

- r_ok.jsp : 실제 jsp ( db연결한 파일 - 여기서 insert할거임 )

<%@page import="java.io.PrintWriter"%>
<%@page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="./dbconfig.jsp"%>
<%
	//getAttribute : java에서 jsp로 값을 가져올때만 사용
	String data_1 = (String)request.getAttribute("rname");
	String data_2 = (String)request.getAttribute("rsubject");
	String data_3 = (String)request.getAttribute("rtext");
	String data_4 = (String)request.getAttribute("rscore");
	String data_5 = (String)request.getAttribute("rfile");

	String sql = "insert into review values ('0',?,?,?,?,?,now())";
	
	PreparedStatement ps = dbcon.prepareStatement(sql);
	ps.setString(1,data_1);
	ps.setString(2,data_2);
	ps.setString(3,data_3);
	ps.setString(4,data_4);
	ps.setString(5,data_5);
	
	int call = ps.executeUpdate();
	//이게 정통방식
	try{
		if(call > 0){
			out.print("<script>alert('리뷰 등록이 완료되었습니다');location.href='./review_select.jsp';</script>");	
		}		
	}catch(Exception e){
		out.print("<script>alert('서버오류로 인하여 저장되지 않았습니다.'); location.href=history.go(-1);</script>");
	}finally{
		dbcon.close();
		ps.close();
	}
%>

 

 

🔽

⚡ 리뷰 list 출력 , 삭제

👀
삭제시

진짜 디렉토리 내 파일 삭제 후 -> database 삭제해야함
=> (Ajax 사용)

1. auto_increment값을 A파트로 보내서
2. A에서 파일 삭제 후
3. A에서 다시보냄
4. B에서 data삭제

- review_select.jsp 
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="./dbconfig.jsp" %>
<%
	String sql = "select count(*) as count from review";
	PreparedStatement ps = dbcon.prepareStatement(sql);
	ResultSet rs = ps.executeQuery();
	rs.next();
	int row = rs.getInt("count");
	
	ResultSet rs2 = null;
	if(row > 0){ //data가 없다면 돌아갈 필요가 없음
		String sql2 = "select * from review order by ridx desc";
		ps = dbcon.prepareStatement(sql2);
		rs2 = ps.executeQuery();
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>리뷰 리스트 출력 파트</title>
<script src="./js/jquery.js"></script>
</head>
<body>
	<table border="1">
		<thead>
			<tr>
				<th>번호</th>
				<th>제목</th>
				<th>등록자</th>
				<th>리뷰내용</th>
				<th>등록일</th>
				<th>첨부파일</th>
				<th>삭제</th>
			</tr>
		</thead>
		<tbody>
			<%
			if(row <= 0){
			%>
			<tr><td colspan="7">등록된 리뷰가 없습니다</td></tr>
			<%
			}else{
				rs2.next();//do~while문은 해당 내용이 뒤에 등장하기 때문에 앞에 한번 넣어줘야함!
				int no=row;
				do{
			%>
				<tr>
					<td><%=no%></td>
					<td><%=rs2.getString("rsubject")%></td>
					<td><%=rs2.getString("rname")%></td>
					<td>
						<%
						if(rs2.getString("rtext").length() > 20){
							out.print(rs2.getString("rtext").substring(0,20)+"...");
						}else{
							out.print(rs2.getString("rtext"));	
						}
						int w=1;
						while( w < rs2.getInt("rscore") ){
						%>⭐<%w++;}%>
					</td>
					<td><%=rs2.getString("rdate")%></td>
					<td>
						<%if(!rs2.getString("rfile").equals("")){ 
							out.print("<a style='font-size:12px;' href='"+ rs2.getString("rfile") +"' target='_blank'>[첨부파일]</a>"); 
						}%>	
					</td>
					<td>
						<input type="button" value="삭제" class="del_btn" data-load="<%= rs2.getInt("ridx")%>">
						<input type="button" value="수정" class="modify_btn" data-load="<%= rs2.getInt("ridx")%>">
					</td>
				</tr>
			<%
				no--;
				}while(rs2.next());
			}
			%>
		</tbody>
	</table>
	<br><br>
	<input type="button" value="쓰기" id="write_btn">
	<br><br><br><br>
</body>

<script>
	$(function(){
    		$(".modify_btn").click(function(){
			var node = $(this).attr("data-load");
			modify_form.ridx.value = node;
			modify_form.method = "post";
			modify_form.action = "./review_modify.jsp";
			modify_form.submit();
		});
    
		$(".del_btn").click(function(){
			var node = $(this).attr("data-load");
			
			$.ajax({
				url : "./review_file_delete.jsp",
				cache : false,
				type : "post",
				dataType : "html",
				data : {
					ridx : node
				},
				contentType : "application/x-www-form-urlencoded",
				success : function($data){
					if($data == "ok"){
						alert("정상적으로 삭제처리 되었습니다.");
						window.location.reload();
					}else{
						alert("통신 장애로 인하여 올바른 데이터 삭제가 되지 않았습니다");
					}
				},
				error : function(){
					alert("통신서버 오류 발생");
				}
			});
		})
		
		$("#write_btn").click(function(){
			location.href= "./review_insert_t.jsp";
		})		
	})
</script>

</html>



- review_file_del.jsp 

<%@page import="java.io.File"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="com.mysql.cj.protocol.Resultset"%>
<%@page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %>
<%@ include file="./dbconfig.jsp" %>
<%
	String ridx = request.getParameter("ridx");
	if(ridx == null){ //첨부파일 유무 확인
		out.print("error");
	}else{
		/* 경로 찾아서 파일 삭제 */
		
		//경로만 찾아서 파일만 삭제하면 되므로 해당 colomn만 적어줘두댐
		String sql = "select rfile from review where ridx=?";
		PreparedStatement ps = dbcon.prepareStatement(sql);
		ps.setString(1,ridx);
		
		ResultSet rs = ps.executeQuery();
		rs.next(); //data 1개밖에 없음
		
		//파일명만 로드하기 위해
		String fileurl = rs.getString("rfile"); 
		int sl = fileurl.lastIndexOf("/");  
		String filenm = fileurl.substring(sl+1);
		
		//해당 파일 실제 웹경로 출력
		String wurl = request.getServletContext().getRealPath("/upload/");
		
		File fe = new File(wurl+filenm); //실제 웹경로 + 저장되어있는 파일명
		fe.delete(); //삭제ㅎ
		
		/* database 삭제 */
		String sql2 = "delete from review where ridx=?";
		ps = dbcon.prepareStatement(sql2);
		ps.setString(1,ridx);
		
		try{
			int result = ps.executeUpdate();
			if(result > 0){
				out.print("ok");
			}			
		}catch(Exception e){
			out.print("error");
		}
		
		rs.close();
		ps.close();
		dbcon.close();
	}
%>


[ 삭제완료 ]

 

🔽

⚡ 리뷰 수정
..수정 진짜 미쳣다
요렇게


- review_modify.jsp

<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="./dbconfig.jsp" %>
<%
	String ridx = request.getParameter("ridx");
	
	String sql = "select * from review where ridx=?";
	PreparedStatement ps = dbcon.prepareStatement(sql);
	ps.setString(1, ridx);
	
	ResultSet rs = ps.executeQuery();
	rs.next();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>< 리뷰 수정 ></title>
</head>
<body>
	<form id="frm" enctype="multipart/form-data">
		<input type="hidden" value="<%=rs.getString("rfile")%>" name="old_filename">
		<input type="hidden" value="<%=rs.getString("ridx")%>" name="ridx">
		<p>상품 리뷰 수정</p>
		<input type="text" name="rname" placeholder="고객명" value="<%= rs.getString("rname")%>" readonly><br>
		<input type="text" name="rsubject" placeholder="제목" value="<%= rs.getString("rsubject")%>"><br>
		<textarea rows="10" cols="25" name="rtext" placeholder="내용" value=""><%= rs.getString("rtext")%></textarea><br>
		<%
			int w=5;
			while(w>=1){
				if(rs.getInt("rscore") == w){
		%>
			<label><input type="radio" name="rscore" value="<%=w%>" checked><%=w%>점</label>
		<%
				}else{
		%>
			<label><input type="radio" name="rscore" value="<%=w%>"><%=w%>점</label>
		<%
				}
				w--;
				}
			if(!rs.getString("rfile").equals("")){
		%>
			<br><br>
			<input type="text" value="<%=rs.getString("rfile")%>" id="t_input" readonly>
			<input type="button" value="삭제" onclick="modify_del_file()" id="b_input"><br><br>
		<%	
			}else{
		%>
			<br><br>
			<input type="file" name="rfile" value=""><br><br>	
		<%
			}
		%>
		<button type="button" onclick="review_modify()">리뷰수정</button>
	</form>	
</body>
<script type="text/javascript">
	//이미 첨부되어있는 파일 삭제 
	function modify_del_file(){		
		var t_input = document.getElementById("t_input");
		var b_input = document.getElementById("b_input");
		b_input.insertAdjacentHTML("afterend", "<input type='file' name='rfile' value=''>");
		t_input.remove();
		b_input.remove();
	}

	function review_modify(){
		frm.method = "post";
		frm.action = "./review_modifyok.jsp";
		
		var f = "";
		if(frm.old_filename.value == ""){
			f = frm.rfile.value;
			if(f != ""){ //첨부가 되었을 때
				var filesize = document.getElementsByName("rfile")[0].files[0].size;
				if(filesize > 2097152){ //2MB - 용량체크
					alert("첨부파일 용량은 2MB까지 입니다.")
				}else{
					frm.submit();
				}
			}else{
				frm.submit();
			}
		}else{
			f = document.getElementById("t_input").value;
			frm.submit();
		}
	} 
</script>
<%
rs.close();
ps.close();
dbcon.close();
%>
</html>



- review_modifyok.jsp (실제로는 java파일 web.xml으로 jsp인척ㅋ)

package shop;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

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

@MultipartConfig(
	fileSizeThreshold = 1024*1024*2,
	maxFileSize = 1024*1024*4,
	maxRequestSize = 1024*1024*10
)
public class review_modifyok extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private InputStream is = null;
	private FileOutputStream fs = null;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=uft-8");
		
		String old_filename = request.getParameter("old_filename");
		String ridx = request.getParameter("ridx");
		String rname = request.getParameter("rname");
		String rsubject = request.getParameter("rsubject");
		String rtext = request.getParameter("rtext");
		String rscore = request.getParameter("rscore");
		
		Part rfile = request.getPart("rfile");
		String filename = rfile.getSubmittedFileName();
		
		String url = request.getServletContext().getRealPath("/upload/");
		String result = ""; //첨부파일이 없으면 걍 ""
		if(!filename.equals("")) { //첨부파일이 있을때
			this.is = rfile.getInputStream();
			//이름변경
			rename rn = new rename(filename);
			result = rn.filenm; //변경된 이름을 변수로받음
			
			this.fs = new FileOutputStream(url+result);
			byte[] bg = new byte[1024*2];
			int size = 0;
			//1도트가 깨질 수도 있음
			do {
				this.fs.write(bg,0,size); //실제 저장
			}while((size=this.is.read(bg)) != -1);
			
			//첨부파일이 있을경우엔 경로를 붙여줘야해서 if안에 작성
			request.setAttribute("rfile", "http://172.30.1.83:8080/upload/"+result);	
		}else {
			request.setAttribute("rfile", result);			
		}
		//setAttribute : r_ok.jsp(view part)로 값 전달 위해 => 배열로 하는게 좋다
		request.setAttribute("ridx", ridx);
		request.setAttribute("rsubject", rsubject);
		request.setAttribute("rtext", rtext);
		request.setAttribute("rscore", rscore);
		request.setAttribute("oldfilename", old_filename);
		
		this.fs.flush(); //싹비우기
		this.fs.close();
		this.is.close();
		
		RequestDispatcher rd = request.getRequestDispatcher("./r_update.jsp");
		rd.forward(request, response);
	}

}



- rename() module

public class rename {
	String filenm = "";
	public rename(String z) {
		this.filenm = z;
		this.re();
	}
	
	private void re() {
		Date today = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
		String day = sf.format(today); 
		
		String rnd = String.valueOf((int)Math.ceil(Math.random()*1500)); //랜덤숫자
		
		//실제 파일에서 속성명만 추출
		int dot = this.filenm.lastIndexOf(".");
		String property = this.filenm.substring(dot+1);
		
		this.filenm = day+"_"+rnd+"."+property; //20240628_636.jpg 요런형태
	}
}



- r_update.jsp
  : 실제파일 삭제 파트

<%@page import="java.io.File"%>
<%@page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="./dbconfig.jsp" %>
<%
String ridx = (String)request.getAttribute("ridx");
String data_1 = (String)request.getAttribute("rsubject");
String data_2 = (String)request.getAttribute("rtext");
String data_3 = (String)request.getAttribute("rscore");
String data_4 = (String)request.getAttribute("rfile");
String oldfilename = (String)request.getAttribute("oldfilename");

out.print(ridx);
String sql = "update review set rsubject=?,rtext=?,rscore=?,rfile=? where ridx=?";
PreparedStatement ps = dbcon.prepareStatement(sql);

ps.setString(1, data_1);
ps.setString(2, data_2);
ps.setString(3, data_3);
ps.setString(4, data_4);
ps.setString(5, ridx);

try{
	int result = ps.executeUpdate();
	if(result > 0){
		out.print("<script>alert('수정내용이 정상적으로 반영되었습니다');location.href='./review_select.jsp'</script>");
	}		
}catch(Exception e){
	out.print("<script>alert('오류발생');</script>");
}finally{
	ps.close();		
}

//-- 실제파일 삭제 파트
if(!oldfilename.equals("")){ //파일첨부가 없다가 새로 업로드한 경우
	String fileurl = oldfilename; 
	int sl = fileurl.lastIndexOf("/");  
	String filenm = fileurl.substring(sl+1);
	
	//해당 파일 실제 웹경로 출력
	String wurl = request.getServletContext().getRealPath("/upload/");
	
	File fe = new File(wurl+filenm); //실제 웹경로 + 저장되어있는 파일명
	fe.delete(); //삭제ㅎ	
}


dbcon.close();
%>