NoticeVO
package kr.or.ddit.vo;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import lombok.Data;
@Data
public class NoticeVO {
private int boNo;
private String boTitle;
private String boContent;
private String boWriter;
private String boDate;
private int boHit;
private Integer[] delNoticeNo;
private MultipartFile[] boFile;
// private List<NoticeFileVO> noticeFileList;
}
Controller
package kr.or.ddit.controller.noticeboard.web;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.controller.noticeboard.service.INoticeService;
import kr.or.ddit.vo.NoticeVO;
@Controller
@RequestMapping("/notice")
public class NoticeInsertController {
@Inject
private INoticeService noticeService;
**// 등록 폼으로 이동하는 메소드**
@RequestMapping(value="/form.do", method = RequestMethod.GET)
public String noticeInsertForm() {
return "notice/form";
}
**// 게시글 등록하는 메소드**
@RequestMapping(value="/insert.do", method = RequestMethod.POST)
public String noticeInsert(
HttpServletRequest req,
RedirectAttributes ra,
NoticeVO noticeVO, Model model) {
String goPage = "";
Map<String, String> errors = new HashMap<String, String>();
if(StringUtils.isBlank(noticeVO.getBoTitle())) {
errors.put("boTitle", "제목을 입력해주세요.");
}
if(StringUtils.isBlank(noticeVO.getBoContent())) {
errors.put("boContent", "내용을 입력해주세요");
}
if(errors.size() > 0) { // 에러가 발생
model.addAttribute("errors", errors);
model.addAttribute("noticeVO", noticeVO);
goPage = "notice/form";
}else {
HttpSession session = req.getSession();
DDITMemberVO memberVO = (DDITMemberVO) session.getAttribute("SessionInfo");
if(memberVO != null) {
noticeVO.setBoWriter(memberVO.getMemId()); // 로그인 한 상용자 아이디로 작성자 셋팅
ServiceResult result = noticeService.insertNotice(req, noticeVO);
if(result.equals(ServiceResult.OK)) {
goPage = "redirect:/notice/detail.do?boNo="+noticeVO.getBoNo();
}else {
model.addAttribute("message", "서버에러, 다시 시도해주세요!");
goPage = "notice/form";
}
}else {
ra.addFlashAttribute("message","로그인 후에 사용 가능합니다.");
goPage = "redirect:/notice/login.do";
}
}
return goPage;
}
}
Service
package kr.or.ddit.controller.noticeboard.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.NoticeVO;
@Service
public class NoticeServiceImpl implements INoticeService {
@Inject
private NoticeMapper noticeMapper;
**// 게시글 등록서비스**
@Override
public ServiceResult insertNotice(HttpServletRequest req, NoticeVO noticeVO) {
ServiceResult result = null;
int status = noticeMapper.insertNotice(noticeVO);
if(status > 0) {
List<NoticeFileVO> noticefileList = noticeVO.getNoticeFileList();
try {
noticeFileUpload(noticefileList, noticeVO.getBoNo(), req);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
result = ServiceResult.OK;
}else {
result = ServiceResult.FAILED;
}
return result;
}
**// 파일 경로 설정 및 업로드 하기 위한 메소드**
private void noticeFileUpload(List<NoticeFileVO> noticeFileList, int boNo, HttpServletRequest req) throws IllegalStateException, IOException {
String savePath = "/resources/notice/";
if(noticeFileList != null && noticeFileList.size() > 0) {
for (NoticeFileVO noticeFileVO : noticeFileList) {
String saveName = UUID.randomUUID().toString();
// 파일명을 설정할 때 원본 파일명의 공백을 '_'로 변경한다.
saveName = saveName + "_" + noticeFileVO.getFileName().replaceAll(" ", "_");
String endFileName = noticeFileVO.getFileName().split("\\\\.")[1]; // 확장자(디버깅 및 확장자 추출 참고용)
// /resources/notice/1 -> 게시글 번호 별로 폴더를 생성하여 사진 관리 위함
String saveLocate = req.getServletContext().getRealPath(savePath + boNo);
File file = new File(saveLocate);
if(!file.exists()) {
file.mkdirs();
}
saveLocate += "/" + saveName;
File saveFile = new File(saveLocate);
noticeFileVO.setBoNo(boNo);
noticeFileVO.setFileSavepath(saveLocate);
noticeMapper.insertNoticeFile(noticeFileVO);
noticeFileVO.getItem().transferTo(saveFile); //파일 복사
}
}
}
}
Mapper
package kr.or.ddit.mapper;
import kr.or.ddit.vo.NoticeVO;
public interface NoticeMapper {
public int insertNotice(NoticeVO noticeVO);
public void insertNoticeFile(NoticeFileVO noticeFileVO);
}
NoticeMapper (SQL)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"<https://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="kr.or.ddit.mapper.NoticeMapper">
**<!-- 공지사항 등록하는 쿼리 -->**
<insert id="insertNotice" parameterType="noticeVO" useGeneratedKeys="true">
<selectKey keyProperty="boNo" resultType="int" order="BEFORE">
select seq_notice.nextval from dual
</selectKey>
insert into notice(
bo_no, bo_title, bo_content, bo_writer, bo_date
)values(
#{boNo}, #{boTitle}, #{boContent}, #{boWriter}, sysdate
)
</insert>
**<!-- 파일 삽입하는 쿼리 -->**
<insert id="insertNoticeFile" parameterType="noticeFileVO">
insert into noticefile(
file_no, bo_no, file_name, file_size, file_fancysize, file_mime, file_savepath, file_downcount
) values (
seq_noticefile.nextval, #{boNo}, #{fileName}, #{fileSize}, #{fileFancysize}, #{fileMime}, #{fileSavepath}, 0
)
</insert>
</mapper>
JSP 페이지
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="<http://tiles.apache.org/tags-tiles>" prefix="tiles" %>
<%@ taglib uri="<http://java.sun.com/jsp/jstl/core>" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AdminLTE 3 | Simple Tables</title>
<link rel="stylesheet" href="<https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback>">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/plugins/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/dist/css/adminlte.min.css">
<script src="${pageContext.request.contextPath }/resources/plugins/jquery/jquery.min.js"></script>
<script src="${pageContext.request.contextPath }/resources/ckeditor/ckeditor.js"></script>
</head>
<c:if test="${not empty message }">
<script type="text/javascript">
alert("${message}");
<c:remove var="message" scope="request"/>
<c:remove var="message" scope="session"/>
</script>
</c:if>
<body class="hold-transition sidebar-mini">
<div class="wrapper">
<!-- header 영역 -->
<tiles:insertAttribute name="header"/>
<div class="content-wrapper">
<!-- content 영역 -->
<tiles:insertAttribute name="content"/>
</div>
<!-- footer 영역 -->
<tiles:insertAttribute name="footer"/>
<aside class="control-sidebar control-sidebar-dark">
</aside>
</div>
<script src="${pageContext.request.contextPath }/resources/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="${pageContext.request.contextPath }/resources/dist/js/adminlte.min.js"></script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="<http://java.sun.com/jsp/jstl/core>" prefix="c" %>
<section class="content-header">
<c:set value="등록" var="name"/>
<c:if test="${status eq 'u' }">
<c:set value="수정" var="name"/>
</c:if>
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>공지사항 ${name }</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">DDIT HOME</a></li>
<li class="breadcrumb-item active">공지사항 ${name }</li>
</ol>
</div>
</div>
</div>
</section>
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="card card-primary">
<form action="/notice/insert.do" method="post" id="noticeForm" enctype="multipart/form-data">
<c:if test="${status eq 'u' }">
<input type="hidden" name="boNo" id="boNo" value="${notice.boNo }">
</c:if>
<div class="card-header">
<h3 class="card-title">공지사항 ${name }</h3>
<div class="card-tools"></div>
</div>
<div class="card-body">
<div class="form-group">
<label for="inputName">제목을 입력해주세요</label>
<input type="text" id="boTitle" name="boTitle" class="form-control" value="${notice.boTitle }" placeholder="제목을 입력해주세요">
</div>
<div class="form-group">
<label for="boContent">내용을 입력해주세요</label>
<textarea id="boContent" name="boContent" class="form-control" rows="14">${notice.boContent }</textarea>
</div>
<div class="form-group">
<div class="custom-file">
<label for="inputDescription">파일 선택</label>
<input type="file" class="custom-file-input" name="boFile" id="boFile" multiple="multiple">
<label class="custom-file-label" for="boFile">파일을 선택해주세요</label>
</div>
</div>
</div>
<div class="card-footer bg-white">
<ul class="mailbox-attachments d-flex align-items-stretch clearfix">
<li><span class="mailbox-attachment-icon"><i
class="far fa-file-pdf"></i></span>
<div class="mailbox-attachment-info">
<a href="#" class="mailbox-attachment-name"><i
class="fas fa-paperclip"></i> Sep2014-report.pdf</a> <span
class="mailbox-attachment-size clearfix mt-1"> <span>1,245
KB</span> <a href="#" class="btn btn-default btn-sm float-right"><i
class="fas fa-times"></i></a>
</span>
</div></li>
<li><span class="mailbox-attachment-icon"><i
class="far fa-file-word"></i></span>
<div class="mailbox-attachment-info">
<a href="#" class="mailbox-attachment-name"><i
class="fas fa-paperclip"></i> App Description.docx</a> <span
class="mailbox-attachment-size clearfix mt-1"> <span>1,245
KB</span> <a href="#" class="btn btn-default btn-sm float-right"><i
class="fas fa-times"></i></a>
</span>
</div></li>
<li><span class="mailbox-attachment-icon has-img"><img
src="../../dist/img/photo1.png" alt="Attachment"></span>
<div class="mailbox-attachment-info">
<a href="#" class="mailbox-attachment-name"><i
class="fas fa-camera"></i> photo1.png</a> <span
class="mailbox-attachment-size clearfix mt-1"> <span>2.67
MB</span> <a href="#" class="btn btn-default btn-sm float-right"><i
class="fas fa-times"></i></a>
</span>
</div></li>
<li><span class="mailbox-attachment-icon has-img"><img
src="../../dist/img/photo2.png" alt="Attachment"></span>
<div class="mailbox-attachment-info">
<a href="#" class="mailbox-attachment-name"><i
class="fas fa-camera"></i> photo2.png</a> <span
class="mailbox-attachment-size clearfix mt-1"> <span>1.9
MB</span> <a href="#" class="btn btn-default btn-sm float-right"><i
class="fas fa-times"></i></a>
</span>
</div></li>
</ul>
</div>
<div class="card-footer bg-white">
<div class="row">
<div class="col-12">
<!--
등록일때는 목록, 등록
수정일때는 취소, 수정
-->
<input type="button" id="insertBtn" value="${name }" class="btn btn-primary float-right">
<c:if test="${status eq 'u' }">
<input type="button" id="cancleBtn" value="취소" class="btn btn-success float-right">
</c:if>
<c:if test="${status ne 'u' }">
<input type="button" id="listBtn" value="목록" class="btn btn-success float-right">
</c:if>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<script>
$(function(){
CKEDITOR.replace("boContent", {
footnotesPrefix: "a",
filebrowserUploadUrl: '/imageUpload.do'
});
var listBtn = $("#listBtn");
var insertBtn = $("#insertBtn");
var cancleBtn = $("#cancleBtn");
var noticeForm = $("#noticeForm");
listBtn.on("click", function(){
location.href = "/notice/list.do"
})
insertBtn.on("click", function(){
var title = $("#boTitle"); // 제목
var content = CKEDITOR.instances.boContent.getData(); //내용
if(title == null || title == ""){
alert("제목을 입력해주세요.")
return false;
}
if(content == null || content == ""){
alert("내용을 입력해주세요.")
return false;
}
if($(this).val() == "수정"){
noticeForm.attr("action", "/notice/update.do");
}
noticeForm.submit();
});
cancleBtn.on("click", function(){
var boNo = $("#boNo").val();
location.href = "/notice/detail.do?boNo=" +boNo
})
})
</script>