완성본 파일 업로드
유의해야할 점
이미지 첨부파일이 있기 때문에 register, modify에서 신경써야할게 조금 있음
src/main/java
kr.controller - Action / DispatcherServlet.java
kr.util - DBUtil / FileUtil / PagingUtil.java 제외
+파일 업로드 위해
webapp-upload(folder) 생성
혼자 다시 복습하면서 순서 정리해봤음..! (아닐수도)
Servlet + Action.interface + web.xml설정 + css + .jar 파일 다 있는 project 라는 가정 하에
1) index.jsp
2) ListAction.java - list.jsp - ActionMap.properties (첫화면 목록)
3) sql로 테이블 생성
4) DAO, VO 생성
5) 그외 create, modify, delete 도 2와 같은 순으로 생성
<글작성>
DAO 수정 - WriteFormAction.java - writeForm.jsp - ActionMap.properties
DAO 수정 - WriteAction.java - write.jsp - ActionMap.properties
<글상세>
DAO 수정 - DetailAction.java - detail.jsp - ActionMap.properties
<글수정>
DAO 수정 - ModifyFormAction.java - modifyForm.jsp - ActionMap.properties
DAO 수정 - ModifyAction.java - modify.jsp - ActionMap.properties
<글삭제>
DAO 수정 - DeleteFormAction.java - deleteForm.jsp - ActionMap.properties
DAO 수정 - DeleteAction.java - delete.jsp - ActionMap.properties
kr.news.vo
NewsVO.java
package kr.news.vo;
import java.sql.Date;
public class NewsVO {
private int num; //뉴스 번호
private String title; //뉴스 제목
private String writer; //작성자
private String passwd; //비밀번호
private String email; //이메일
private String article; //기사 내용
private String filename;//이미지명
private Date reg_date; //작성일
//비밀번호 일치 여부 체크
public boolean isCheckedPassword(String userPasswd) {
if(passwd.equals(userPasswd)) {
return true;
}
return false;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
}
kr.news.dao
NewsDAO
package kr.news.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import kr.news.vo.NewsVO;
import kr.util.DBUtil;
public class NewsDAO {
//싱글턴 패턴
private static NewsDAO instance = new NewsDAO();
public static NewsDAO getInstance() {
return instance;
}
private NewsDAO() {}
//뉴스 등록
public void registerNews(NewsVO vo)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//커넥션 풀로부터 커넥션 할당
conn = DBUtil.getConnection();
//SQL문 작성
sql="INSERT INTO dailynews (num,title,writer,passwd,email,article,filename)
values (dailynews_seq.nextval,?,?,?,?,?,?)";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setString(1, vo.getTitle());
pstmt.setString(2, vo.getWriter());
pstmt.setString(3, vo.getPasswd());
pstmt.setString(4, vo.getEmail());
pstmt.setString(5, vo.getArticle());
pstmt.setString(6, vo.getFilename());
//SQL문 실행
pstmt.executeUpdate();
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(null, pstmt, conn);
}
}
//뉴스의 총 개수
public int getCount()throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int count = 0;
String sql = null;
try {
//커넥션풀로부터 커넥션을 할당
conn = DBUtil.getConnection();
//SQL문 작성
sql = "SELECT COUNT(*) FROM dailynews";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//SQL문을 실행
rs = pstmt.executeQuery();
if(rs.next()) {
count = rs.getInt(1);
}
}catch(Exception e) {
throw new Exception(e);
}finally {
//자원정리
DBUtil.executeClose(rs, pstmt, conn);
}
return count;
}
//목록
public List<NewsVO> getList(int startRow, int endRow)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<NewsVO> list = null;
String sql = null;
try {
conn = DBUtil.getConnection();
sql = "SELECT * FROM (SELECT a.*,rownum rnum "
+ "FROM (SELECT * FROM dailynews ORDER BY "
+ "num DESC)a) WHERE rnum>=? AND rnum<=?";
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setInt(1, startRow);
pstmt.setInt(2, endRow);
rs = pstmt.executeQuery();
list = new ArrayList<NewsVO>();
while(rs.next()) {
NewsVO vo = new NewsVO();
vo.setNum(rs.getInt("num"));
vo.setTitle(rs.getString("title"));
vo.setWriter(rs.getString("writer"));
vo.setReg_date(rs.getDate("reg_date"));
list.add(vo);
}
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(rs, pstmt, conn);
}
return list;
}
//뉴스 상세 정보
public NewsVO getNews(int num)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
NewsVO newsVO = null;
String sql = null;
try {
conn = DBUtil.getConnection();
sql = "SELECT * FROM dailynews WHERE num=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if(rs.next()) {
newsVO = new NewsVO();
newsVO.setNum(rs.getInt("num"));
newsVO.setTitle(rs.getString("title"));
newsVO.setWriter(rs.getString("writer"));
newsVO.setPasswd(rs.getString("passwd"));
newsVO.setEmail(rs.getString("email"));
newsVO.setArticle(rs.getString("article"));
newsVO.setFilename(rs.getString("filename"));
newsVO.setReg_date(rs.getDate("reg_date"));
}
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(rs, pstmt, conn);
}
return newsVO;
}
//뉴스 수정
public void updateNews(NewsVO vo)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
String sub_sql = ""; // 상황에 따라 동적으로 처리하기 위해 sql과 분리해서 sub를 만듦
int cnt = 0;
try {
//커넥션풀로부터 커넥션 할당
conn = DBUtil.getConnection();
if(vo.getFilename()!=null) { //파일이 업로드 된 경우
sub_sql += ",filename=?";
}
sql = "UPDATE dailynews SET title=?, writer=?, email=?, article=?"
+ sub_sql + " WHERE num=?";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩 (물음표 번호가 달라지기 때문에 cnt로 자동으로 일치시켜줌)
pstmt.setString(++cnt, vo.getTitle());
pstmt.setString(++cnt, vo.getWriter());
pstmt.setString(++cnt, vo.getEmail());
pstmt.setString(++cnt, vo.getArticle());
if(vo.getFilename()!=null) {
pstmt.setString(++cnt, vo.getFilename());
}
pstmt.setInt(++cnt, vo.getNum());
//SQL문 실행
pstmt.executeUpdate();
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(null, pstmt, conn);
}
}
//뉴스 삭제
public void deleteNews(int num)throws Exception{
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
//커넥션풀로부터 커넥션 할당
conn = DBUtil.getConnection();
//SQL문 작성
sql = "DELETE FROM dailynews WHERE num=?";
//PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
//?에 데이터 바인딩
pstmt.setInt(1, num);
//SQL문 실행
pstmt.executeUpdate();
}catch(Exception e) {
throw new Exception(e);
}finally {
DBUtil.executeClose(null, pstmt, conn);
}
}
}
DAO 에서는 filename도 그냥 String 처리함
- registerNews(NewsVO vo) 뉴스등록
- getCount() 뉴스의 총 개수
rs.next()가 true라면 count = rs.getInt(1) - getList(int startRow, int endRow) 목록
데이터를 자바빈에 넣고 자바빈을 list하나로 묶은 후 return list; - getNews(int num) 뉴스 상세 정보
- updateNews(NewsVO vo) 뉴스 수정
+ vo.getFilename()!=null 이라면 sub_sql += ",filename=?"
filename이 null값이 아니라면 sub_sql에 filename=? 값 주기
+ vo.getFilename()!=null 이라면 pstmt.setString(++cnt, vo.getFilename());
filename이 null값이 아니라면 sub_sql(++cnt)에 데이터 바인딩 - deleteNews 뉴스 삭제
기사 보드 첫 화면 만들기 (목록)
kr.news.action
ListAction.java
package kr.news.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
import kr.news.dao.NewsDAO;
import kr.news.vo.NewsVO;
import kr.util.PagingUtil;
public class ListAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String pageNum = request.getParameter("pageNum");
if(pageNum==null) pageNum = "1";
NewsDAO dao = NewsDAO.getInstance();
int count = dao.getCount();
//페이지 처리
PagingUtil page = new PagingUtil(Integer.parseInt(pageNum),
count,20,10,"list.do");
List<NewsVO> list = null;
if(count>0) {
list = dao.getList(page.getStartRow(), page.getEndRow());
}
request.setAttribute("count", count);
request.setAttribute("list", list);
request.setAttribute("page", page.getPage());
//JSP 경로 반환
return "/WEB-INF/views/list.jsp";
}
}
- pageNum==null 일 경우에 pageNum = "1"로 줌
첫 화면은 당연히 null값이기 때문에 기본값으로 1을 줌 - NewsDAO객체 생성 후 뉴스의 총 개수를 count로 가져옴(getCount() )
- 페이지 처리 시 한 페이지에 20개/ 10페이지를 list.do에 보이게 함
views
list.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>뉴스 목록</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>뉴스 목록</h2>
<div class="align-right">
<input type="button" value="등록" onclick="location.href='registerForm.do'">
</div>
<c:if test="${count == 0}">
<div class="result-display">
표시할 게시물이 없습니다.
</div>
</c:if>
<c:if test="${count > 0}">
<table>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>등록일</th>
</tr>
<c:forEach var="news" items="${list}">
<tr>
<td>${news.num}</td>
<td><a href="detail.do?num=${news.num}">${news.title}</a></td>
<td>${news.writer}</td>
<td class="align-center">${news.reg_date}</td>
</tr>
</c:forEach>
</table>
<div class="align-center">
${page}
</div>
</c:if>
</div>
</body>
</html>
- 등록 button > location.href='registerForm.do'
- <c:forEach var="news" items="${list}"> news == 식별자
++ActionMap.properties에 기입 (글 맨 아래 첨부)
뉴스 등록
registerFormAction.java
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
public class RegisterFormAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//JSP 경로 반환
return "/WEB-INF/views/registerForm.jsp";
}
}
views
registerForm.jsp (뉴스 등록 화면)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>뉴스 등록</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<script type="text/javascript">
window.onload=function(){
let myForm = document.getElementById('register_form');
myForm.onsubmit=function(){
let items = document.querySelectorAll('.input-check');
for(let i=0;i<items.length;i++){
if(items[i].value.trim()==''){
let label = document.querySelector('label[for="'+items[i].id+'"]');
alert(label.textContent + ' 항목은 필수 입력');
items[i].value = '';
items[i].focus();
return false;
}
}
};
};
</script>
</head>
<body>
<div class="page-main">
<h2>뉴스 등록</h2>
<form id="register_form" action="register.do" method="post"
enctype="multipart/form-data">
<ul>
<li>
<label for="title">제목</label>
<input type="text" name="title" id="title"
size="30" maxlength="50" class="input-check">
</li>
<li>
<label for="writer">작성자</label>
<input type="text" name="writer" id="writer"
size="10" maxlength="10" class="input-check">
</li>
<li>
<label for="passwd">비밀번호</label>
<input type="password" name="passwd" id="passwd"
size="12" maxlength="12" class="input-check">
</li>
<li>
<label for="email">이메일</label>
<input type="email" name="email" id="email"
size="30" maxlength="50" class="input-check">
</li>
<li>
<label for="article">내용</label>
<textarea rows="5" cols="40" name="article"
id="article" class="input-check"></textarea>
</li>
<li>
<label for="filename">이미지</label>
<input type="file" name="filename" id="filename"
class="input-check"
accept="image/gif,image/png,image/jpeg">
</li>
</ul>
<div class="align-center">
<input type="submit" value="등록">
<input type="button" value="목록"
onclick="location.href='list.do'">
</div>
</form>
</div>
</body>
</html>
- class="input-check"를 줘서 querySelectorAll 입력 시 더 편하게 기입 가능
- 이미지 첨부파일이 있기 때문에
1) method="post"
2) enctype="multipart/form-data"
3) type="file" / accept="image/gif, image/png, image/jpeg" 기입
kr.news.action
RegisterAction.java (뉴스 등록)
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
import kr.controller.Action;
import kr.news.dao.NewsDAO;
import kr.news.vo.NewsVO;
import kr.util.FileUtil;
public class RegisterAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
MultipartRequest multi = FileUtil.createFile(request);
NewsVO vo = new NewsVO();
vo.setTitle(multi.getParameter("title"));
vo.setWriter(multi.getParameter("writer"));
vo.setPasswd(multi.getParameter("passwd"));
vo.setEmail(multi.getParameter("email"));
vo.setArticle(multi.getParameter("article"));
vo.setFilename(multi.getFilesystemName("filename"));
NewsDAO dao = NewsDAO.getInstance();
dao.registerNews(vo);
return "/WEB-INF/views/register.jsp";
}
}
- MultipartRequest multi = FileUtil.createFile(request); 를 줬기 때문에 title, writer 등 모든 데이터를 request가 아닌 multi에서 불러옴
- Filename은 multi.getFilesystemName으로 불러옴
getParameter: 우리가 입력한 데이터 읽어오기
getFilesystemName: 전송돼서 저장된 파일명 읽어오기
views
register.jsp (등록완료 화면)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>뉴스 등록 완료</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
</head>
<body>
<div class="page-main">
<h2>뉴스 등록 완료</h2>
<div class="result-display">
<div class="align-center">
뉴스 등록을 완료했습니다.<br>
<button onclick="location.href='list.do'">목록</button>
</div>
</div>
</div>
</body>
</html>
상세정보 보기
kr.news.action
DetailAction.java
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
import kr.news.dao.NewsDAO;
import kr.news.vo.NewsVO;
public class DetailAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
int num = Integer.parseInt(request.getParameter("num"));
NewsDAO dao = NewsDAO.getInstance();
NewsVO newsVO = dao.getNews(num);
request.setAttribute("newsVO", newsVO);
return "/WEB-INF/views/detail.jsp";
}
}
- request에서 num값을 읽어와서 그에 맞는 상세정보 detail.jsp 에 보임
- request.setAttribute("newsVO", newsVO); 라고 request에 data set
detail.jsp에는 따로 명시하는 부분이 없고 newsVO가 식별자가 됨
views
detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>뉴스 상세 정보</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"></head>
<body>
<div class="page-main">
<h2>${newsVO.title}</h2>
<p>
뉴스번호 : ${newsVO.num}<br>
작성자 : ${newsVO.writer}<br>
이메일 : ${newsVO.email}<br>
등록일 : ${newsVO.reg_date}
</p>
<hr size="1" width="100%" noshade="noshade">
<div class="align-center">
<img src="${pageContext.request.contextPath}/upload/${newsVO.filename}"
style="max-width: 500px">
</div>
<p>
${newsVO.article}
</p>
<hr size="1" width="100%" noshade="noshade">
<div class="align-right">
<input type="button" value="수정"
onclick="location.href='modifyForm.do?num=${newsVO.num}'">
<input type="button" value="삭제"
onclick="location.href='deleteForm.do?num=${newsVO.num}'">
<input type="button" value="목록"
onclick="location.href='list.do'">
</div>
</div>
</body>
</html>
- DetailAction에서 지정한 식별자로 값을 읽어옴 (newsVO)
- img 파일을 불러올 때에 위치
src="${pageContext.request.contextPath}/upload/${newsVO.filename}"
글 수정
kr.news.action
ModifyFormAction.java
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
import kr.news.dao.NewsDAO;
import kr.news.vo.NewsVO;
public class ModifyFormAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
int num = Integer.parseInt(request.getParameter("num"));
NewsDAO dao = NewsDAO.getInstance();
NewsVO newsVO = dao.getNews(num);
request.setAttribute("newsVO", newsVO);
//JSP 경로 반환
return "/WEB-INF/views/modifyForm.jsp";
}
}
- request의 뉴스 num을 불러와서 수정
- request.setAttribute("newsVO", newsVO);
뉴스 상세 정보 보기에서 그랬던 것처럼 (DetailAction - detail) 데이터 식별자를 미리 지정 (newsVO)
views
modifyForm (기사 수정 화면)
<%@ 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>뉴스 등록</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css">
<script type="text/javascript">
window.onload=function(){
const myForm = document.getElementById('modify_form');
myForm.onsubmit=function(){
let items = document.querySelectorAll('.input-check');
for(let i=0;i<items.length;i++){
if(items[i].value.trim()==''){
let label = document.querySelector('label[for="'+items[i].id+'"]');
alert(label.textContent + ' 항목은 필수 입력');
items[i].value = '';
items[i].focus();
return false;
}
}
};
};
</script>
</head>
<body>
<div class="page-main">
<h2>뉴스 수정</h2>
<form id="modify_form" action="modify.do" method="post" enctype="multipart/form-data">
<input type="hidden" name="num" value="${newsVO.num}">
<ul>
<li>
<label for="title">제목</label>
<input type="text" name="title"
id="title" size="30" value="${newsVO.title}"
maxlength="50" class="input-check">
</li>
<li>
<label for="writer">작성자</label>
<input type="text" name="writer"
id="writer" size="10" value="${newsVO.writer}"
maxlength="10" class="input-check">
</li>
<li>
<label for="passwd">비밀번호</label>
<input type="password" name="passwd"
id="passwd" size="12"
maxlength="12" class="input-check">
</li>
<li>
<label for="email">이메일</label>
<input type="email" name="email"
id="email" size="30" value="${newsVO.email}"
maxlength="50" class="input-check">
</li>
<li>
<label for="article">내용</label>
<textarea rows="5" cols="40" name="article"
id="article" class="input-check">${newsVO.article}</textarea>
</li>
<li>
<label for="filename">이미지</label>
<input type="file" name="filename" id="filename"
accept="image/gif,image/png,image/jpeg">
<br>
<img src="${pageContext.request.contextPath}/upload/${newsVO.filename}"
width="100" style="margin-left:100px;">
</li>
</ul>
<div class="align-center">
<input type="submit" value="수정">
<input type="button" value="목록"
onclick="location.href='list.do'">
</div>
</form>
</div>
</body>
</html>
- ModifyFormAction에서 지정한 식별자 사용
- 수정 항목에 이미지도 있기 때문에
1) method="post"
2) enctype="multipart/form-data"
3) type="file" accept="image/gif, image/png, image/jpeg" - num항목은 보이지 않게 가리고 전송해야하기 때문에 hidden type으로 설정
kr.news.action
ModifyAction.java (기사 수정)
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
import kr.controller.Action;
import kr.news.dao.NewsDAO;
import kr.news.vo.NewsVO;
import kr.util.FileUtil;
public class ModifyAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("utf-8");
MultipartRequest multi = FileUtil.createFile(request);
NewsVO vo = new NewsVO();
vo.setNum(Integer.parseInt(multi.getParameter("num")));
vo.setTitle(multi.getParameter("title"));
vo.setWriter(multi.getParameter("writer"));
vo.setPasswd(multi.getParameter("passwd"));
vo.setEmail(multi.getParameter("email"));
vo.setArticle(multi.getParameter("article"));
vo.setFilename(multi.getFilesystemName("filename"));
NewsDAO dao = NewsDAO.getInstance();
//비밀번호 인증을 위해 한 건의 레코드를 자바빈에 담아서 반환
NewsVO db_news = dao.getNews(vo.getNum());
boolean check = false;
if(db_news!=null) {
//비밀번호 일치 여부 체크
check = db_news.isCheckedPassword(vo.getPasswd());
}
if(check) {
dao.updateNews(vo);
if(vo.getFilename()!=null) { // 전송되는 파일이 있을 경우에
//새 파일로 교체할 원래 파일 제거 (이전파일-db_news에 있음)
//utility class에 remove file도 있기 때문에 그걸 쓰면됨
FileUtil.removeFile(request,db_news.getFilename());
}
//상세페이지로 이동하기 위해 글번호 저장
request.setAttribute("num", vo.getNum());
}else {
if(vo.getFilename()!=null) {
//인증 오류일 경우 업로드된 파일 삭제
FileUtil.removeFile(request, vo.getFilename());
}
}
//UI처리를 위해 check 저장
request.setAttribute("check", check);
//JSP 경로 반환
return "/WEB-INF/views/modify.jsp";
}
}
- 수정이기 때문에 인코딩 처리 + RegisterAction과 동일하게 multi 사용
- 조건 체크문
1) db_news(수정한 내용) 이 null이 아닐 경우에 비밀번호 일치 여부 체크
2) 비밀번호 일치여부 = true // dao.updateNews(vo);
2-2) true Filename!=null인 경우 기존 파일 삭제 (새 파일로 교체 시 쓰레기 파일을 지우기 위함)
FileUtil.removeFile(request, db_news.getFilename(); // 파일 삭제
request.setAttribute("num", vo.getNum()); // 다시 상세 페이지로 돌아가기 위해 num 저장
2-3) false Filename=null인 경우 업로드 된 파일 삭제
3) UI 처리를 위해 check 저장
views
modify.jsp (수정 완료 화면)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${check}">
<script>
alert('뉴스 수정을 완료했습니다.');
location.href='detail.do?num=${num}';
</script>
</c:if>
<c:if test="${!check}">
<script>
alert('비밀번호 불일치');
history.go(-1);
</script>
</c:if>
- check == true (ModifyAction 의 비밀번호 일치 여부)
alert -> 자동으로 상세 페이지 이동
check == false
alert -> history.go(-1);
글 삭제
kr.news.action
DeleteFormAction.java
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
public class DeleteFormAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 전송된 데이터 받기
int num = Integer.parseInt(request.getParameter("num"));
request.setAttribute("num", num);
//JSP 경로 반환
return "/WEB-INF/views/deleteForm.jsp";
}
}
views
deleteForm.jsp (삭제 화면/ 비밀번호 일치 체크)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>기사 삭제</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<script type="text/javascript">
window.onload=function(){
let myForm = document.getElementById('delete_form');
myForm.onsubmit = function(){
let passwd = document.getElementById('passwd');
if(passwd.value.trim()==''){
alert('비밀번호를 입력하세요');
passwd.value='';
passwd.focus();
return false;
}
};
};
</script>
</head>
<body>
<div class="page-main">
<h2>뉴스 삭제</h2>
<form id="delete_form" action="delete.do" method="post">
<input type="hidden" name="num" value="${num}">
<ul>
<li>
<label for="passwd">비밀번호</label>
<input type="password" name="passwd" id="passwd" size="12" maxlength="12">
</li>
</ul>
<div class="align-center">
<input type="submit" value="글 삭제">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form>
</div>
</body>
</html>
- deleteForm을 포함한 모든 폼의 유효성 검사는 trim()밖에 입력하지 않음
불일치하거나 등의 조건은 다 model class에서 시행 - num값을 hidden으로 전송
kr.news.action
DeleteAction.jsp (삭제)
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
import kr.news.dao.NewsDAO;
import kr.news.vo.NewsVO;
import kr.util.FileUtil;
public class DeleteAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("utf-8");
//전송된 데이터 반환
int num = Integer.parseInt(request.getParameter("num"));
String passwd = request.getParameter("passwd");
NewsDAO dao = NewsDAO.getInstance();
NewsVO db_news = dao.getNews(num);
boolean check = false;
if(db_news!=null) {
//비밀번호 일치 여부 체크
check=db_news.isCheckedPassword(passwd);
}
if(check) {
//글 삭제
dao.deleteNews(num);
//쓰레기 파일 삭제 (쌓이는걸 방지하기 위함)
FileUtil.removeFile(request, db_news.getFilename());
}
//UI처리를 위해 check 저장
request.setAttribute("check", check);
//JSP 경로 반환
return "/WEB-INF/views/delete.jsp";
}
}
- db_news = getNews(뉴스 상세정보)
if db_news!=null > 비밀번호 일치 여부 체크
views
delete.jsp (삭제 완료 화면)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${check}">
<script>
alert('뉴스 삭제를 완료했습니다.');
location.href='list.do';
</script>
</c:if>
<c:if test="${!check}">
<script>
alert('비밀번호 불일치');
history.go(-1);
</script>
</c:if>
webapp
ActionMap.properties (꼭 처리해야함..!!!!)
# key value
# 요청URL 모델클래스
/list.do=kr.news.action.ListAction
/registerForm.do=kr.news.action.RegisterFormAction
/register.do=kr.news.action.RegisterAction
/detail.do=kr.news.action.DetailAction
/modifyForm.do=kr.news.action.ModifyFormAction
/modify.do=kr.news.action.ModifyAction
/deleteForm.do=kr.news.action.DeleteFormAction
/delete.do=kr.news.action.DeleteAction
'학원 > servlet jsp' 카테고리의 다른 글
11.23-27일 (ch08-mvcPage 회원 및 관리자 관리) (0) | 2023.11.27 |
---|---|
11.23일 (mvc / ajax / jackson object class) (3) | 2023.11.24 |
11.22일 ( tomcat.war import / export) (0) | 2023.11.23 |
11.22일 (model-2(mvc) 패턴으로 News 기사 게시판 생성-1) (0) | 2023.11.22 |
11.21일 (model-2(mvc)) (0) | 2023.11.22 |