11.22일 (model-2(mvc) 패턴으로 News 기사 게시판 생성-1)
+ utility 클래스 추가
index.jsp
table.sql
News VO/ DAO
리스트 ListAction.java - list.jsp - ActionMap.properties
index 수정
RegisterFormAction.java - registerForm.jsp - ActionMap.properties - RegisterAction.java - DAO (registerNews)
ActionMap.properties
파일 업로드 위해 webapp - upload (folder) 생성
순으로 register, list, modify, delete 생성
기본 설정
src/main/java - kr.controller(package) - Action(interface) / DispatcherServlet
kr.util(package) - DBUtil / FileUtil / PagingUtil
webapp(folder) - lib - cos.jar / jstl - 1.2.jar / ojdbc8.jar
webapp(folder) - web.xml / ActionMap.properties
webapp
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.sendRedirect(request.getContextPath()+"/list.do");
%>
webapp
sql (folder)
table.sql
--데일리 뉴스
create table dailynews(
num number primary key,
title varchar2(150) not null,
writer varchar2(30) not null,
passwd varchar2(12) not null,
email varchar2(50) not null,
article clob not null,
filename varchar2(100) not null, --파일 업로드 처리
reg_date date default sysdate not null
);
create sequence dailynews_seq;
src/main/java
kr.news.vo (package)
NewsVO.java (class)
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.java
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() {}
//뉴스 등록
//뉴스의 총 개수
//목록
//뉴스 상세 정보
//뉴스 수정
//뉴스 삭제
}
kr.news.action (package)
ListAction (class)
package kr.news.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.controller.Action;
public class ListAction implements Action{
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//JSP 경로 반환
return "/WEB-INF/views/list.jsp";
}
}
WEB-INF
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">
</head>
<body>
<div class="page-main">
<h2>뉴스 목록</h2>
<div class="align-right">
<input type="button" value="등록" onclick="location.href='registerForm.do'">
</div>
</div>
</body>
</html>
ActionMap.properties
# key value
# 요청URL 모델클래스
/list.do=kr.news.action.ListAction
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
response.sendRedirect(request.getContextPath()+"/list.do");
%>
초기 설정+
메인 화면 redirect (index.jsp)
등록 폼 만들기
kr.news.action (package)
RegisterFormAction (class)
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">
</head>
<body>
<div class="page-main">
<h2>뉴스 등록</h2>
<form id="register_form" action="register.do" method="post" enctype="multipart/form-data"> <%-- 파일업로드하는거라 enctype 넣음 --%>
<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>
파일 업로드가 필요하기 때문에 enctype 필수
enctype="multipart/form-data"
이미지 <input type="file" accept="image/gif,image/png,image/jpeg"
ActionMap.properties
# key value
# 요청URL 모델클래스
/list.do=kr.news.action.ListAction
/registerForm.do=kr.news.action.RegisterFormAction
registerForm.jsp 조건체크문 추가 (null값 입력)
<%@ 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"> <%-- 파일업로드하는거라 enctype 넣음 --%>
<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>
kr.util
FileUtil (class)
파일 업로드 처리 시 간편하게 하기 위해 클래스 생성
package kr.util;
import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
public class FileUtil {
//인코딩 타입
private static final String ENCODING_TYPE = "utf-8";
//최대 업로드 사이즈
private static final int MAX_SIZE = 50*1024*1024;
//업로드 상대 경로
private static final String UPLOAD_PATH = "/upload";
//파일 업로드를 실제로 처리하는 메서드를 만들거임
//파일 업로드
public static MultipartRequest createFile(HttpServletRequest request)throws IOException{
//업로드 절대 경로
String upload = request.getServletContext().getRealPath(UPLOAD_PATH); // 상대경로를 주소에 넣기
return new MultipartRequest(request, upload, MAX_SIZE, ENCODING_TYPE, new DefaultFileRenamePolicy());
}
//파일 삭제
public static void removeFile(HttpServletRequest request, String filename) {
if(filename!=null) { // 파일명이 존재할 때
//업로드 절대 경로
String upload = request.getServletContext().getRealPath(UPLOAD_PATH);
File file = new File(upload + "/" + filename); // file안에 file을 삭제하는 기능이 있음
if(file.exists()) file.delete(); //존재할 경우에만 (true) 삭제
}
}
}
kr.news.action (package)
RegisterAction (class)
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.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.getParameter("filename"));
return null;
}
}
ActionMap.properties
# key value
# 요청URL 모델클래스
/list.do=kr.news.action.ListAction
/registerForm.do=kr.news.action.RegisterFormAction
/register.do=kr.news.action.RegisterAction