에러 페이지 띄우기
설정
- web.xml
# servlet-context.xml 파일 위치 변경해줌
>> web.xml에서 경로 변경해주어야함
- error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style>
</style>
</head>
<body>
<h2>ERROR CODE : ${code}</h2>
<h3>${msg}</h3>
</body>
<script></script>
</html>
- Controller
package kr.co.gudi.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ErrorController {
Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping(value="/error/404")
public String notFound(Model model) {
model.addAttribute("code","404");
model.addAttribute("msg","원하시는 요청 또는 페이지가 없습니다.");
return "error";
}
@RequestMapping(value="/error/500")
public String serverError(Model model) {
model.addAttribute("code","500");
model.addAttribute("msg","서버처리 중 문제가 발생했습니다.");
return "error";
}
@RequestMapping(value="/error/IOException")
public String ioException(Model model) {
model.addAttribute("code","500");
model.addAttribute("msg","데이터 입출력 중 문제 발생!");
return "error";
}
}
CSS 설정
- src > main > webapp > resources 파일에 css 파일 생성
- connons라는 css 파일 생성해서
- style 태그에 작성하듯 동일하게 작성
- connons라는 css 파일 생성해서
- 적용시킬 jsp에 아래 태그 삽입
<link rel="stylesheet" href="resources/css/commons.css" type="text/css">
# 다음과 같이 resources 경로 설정으로 인해 모든 jsp에 적용됨
게시판 사진 업로드
# DB 연결 설정 해주어야함
# 기존 Board에서 JSP는 변경된 부분만 올림
- writeForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<link rel="stylesheet" href="resources/css/commons.css" type="text/css">
<style>
</style>
</head>
<body>
<form action="write.do" method="post" enctype="multipart/form-data">
<table>
<tr>
<th>제목</th>
<td><input type="text" name="subject"/></td>
</tr>
<tr>
<th>작성자</th>
<td><input type="text" name="user_name"/></td>
</tr>
<tr>
<th>내용</th>
<td><textarea name="content"></textarea></td>
</tr>
<tr>
<th>사진</th>
<td><input type="file" name="photo"/></td>
</tr>
<tr>
<th colspan="2">
<input type="button" onclick="location.href='./list.do'" value="리스트"/>
<button>저장</button>
</th>
</tr>
</table>
</form>
</body>
<script></script>
</html>
- detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<link rel="stylesheet" href="resources/css/commons.css" type="text/css">
<style>
</style>
</head>
<body>
<table>
<tr>
<th>제목</th>
<td>${dto.subject}</td>
</tr>
<tr>
<th>작성일</th>
<td>${dto.reg_date}</td>
</tr>
<tr>
<th>작성자</th>
<td>${dto.user_name}</td>
</tr>
<tr>
<th>내용</th>
<td>${dto.content}</td>
</tr>
<c:if test="${dto.newFileName ne null }">
<tr>
<th>사진</th>
<td><img src="/photo/${dto.newFileName}"></td>
</tr>
</c:if>
<tr>
<th colspan="2">
<input type="button" onclick="location.href='./list.do'" value="리스트"/>
<input type="button" onclick="location.href='./update.go?idx=${dto.idx}'" value="수정"/>
</th>
</tr>
</table>
</body>
<script></script>
</html>
- updateForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<link rel="stylesheet" href="resources/css/commons.css" type="text/css">
<style>
</style>
</head>
<body>
<form action="update.do" method="post" enctype="multipart/form-data">
<input type="hidden" name="idx" value="${dto.idx}"/>
<table>
<tr>
<th>제목</th>
<td><input type="text" name="subject" value="${dto.subject}"/></td>
</tr>
<tr>
<th>작성자</th>
<td><input type="text" name="user_name" value="${dto.user_name}"/></td>
</tr>
<tr>
<th>내용</th>
<td><textarea name="content">${dto.content}</textarea></td>
</tr>
<tr>
<th>사진</th>
<td>
<c:if test="${dto.newFileName eq null}">
<input type="file" name="photo"/>
</c:if>
<c:if test="${dto.newFileName ne null}">
<img src="/photo/${dto.newFileName}">
</c:if>
</td>
</tr>
<tr>
<th colspan="2">
<input type="button" onclick="location.href='./list.do'" value="리스트"/>
<button>저장</button>
</th>
</tr>
</table>
</form>
</body>
<script></script>
</html>
- Controller
package kr.co.gudi.controller;
import java.util.ArrayList;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import kr.co.gudi.dto.BoardDTO;
import kr.co.gudi.service.BoardService;
@Controller
public class BoardController {
@Autowired BoardService service;
Logger logger = LoggerFactory.getLogger(getClass());
@RequestMapping(value={"/","/list.do"})
public String list(Model model) {
logger.info("list call");
ArrayList<BoardDTO> list = service.list();
logger.info("list size : "+list.size());
model.addAttribute("list", list);
return "list";
}
@RequestMapping(value="/write.go")
public String writeForm() {
logger.info("write page 이동");
return "writeForm";
}
@RequestMapping(value="/write.do", method = RequestMethod.POST)
public String write(MultipartFile photo, @RequestParam HashMap<String, String> params) {
//logger.info("params : " + params);
return service.write(photo,params);
}
@RequestMapping(value="/detail.do")
public String detail(Model model, @RequestParam String idx) {
logger.info("detail : "+idx);
String page = "redirect:/list.do";
BoardDTO dto = service.detail(idx,"detail");
if(dto != null) {
page = "detail";
model.addAttribute("dto", dto);
}
return page;
}
@RequestMapping(value="/delete.do")
public String delete(@RequestParam String idx) {
service.delete(idx);
return "redirect:/list.do";
}
@RequestMapping(value="/update.go")
public String update(Model model, @RequestParam String idx) {
logger.info("update : "+idx);
String page = "redirect:/list.do";
BoardDTO dto = service.detail(idx,"update");
logger.info("dto : "+dto);
if(dto != null) {
page = "updateForm";
model.addAttribute("dto", dto);
}
return page;
}
@RequestMapping(value="/update.do", method = RequestMethod.POST)
public String update(MultipartFile photo, @RequestParam HashMap<String, String> params) {
logger.info("params : " + params);
return service.update(photo,params);
}
}
- DTO
package kr.co.gudi.dto;
import java.sql.Date;
public class BoardDTO {
private int idx;
private String subject;
private String content;
private String user_name;
private int bHit;
private Date reg_date;
private int photoIdx;
private String newFileName;
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public int getbHit() {
return bHit;
}
public void setbHit(int bHit) {
this.bHit = bHit;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
public int getPhotoIdx() {
return photoIdx;
}
public void setPhotoIdx(int photoIdx) {
this.photoIdx = photoIdx;
}
public String getNewFileName() {
return newFileName;
}
public void setNewFileName(String newFileName) {
this.newFileName = newFileName;
}
}
- Service
package kr.co.gudi.service;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import kr.co.gudi.dao.BoardInter;
import kr.co.gudi.dto.BoardDTO;
@Service
public class BoardService {
@Autowired BoardInter dao;
Logger logger = LoggerFactory.getLogger(getClass());
public ArrayList<BoardDTO> list() {
logger.info("list 요청");
return dao.list();
}
public String write(MultipartFile photo, HashMap<String, String> params) {
String page = "redirect:/list.do";
//1. 게시글만 작성한 경우
//방금 insert 한 값의 key를 반환 받는 방법
//조건 1. 파라메터를 DTO로 보내야함(Spring에서만)
BoardDTO dto = new BoardDTO();
dto.setSubject(params.get("subject"));
dto.setUser_name(params.get("user_name"));
dto.setContent(params.get("content"));
int row = dao.write(dto);
//logger.info("update row : "+row);
//조건 3 : 받아온 키는 파라메터 DTO에서 뺀다
int idx = dto.getIdx();
//logger.info("방금 insert 한 idx : "+idx);
page = "redirect:/detail.do?idx="+idx;
//2. 파일도 업로드 한 경우
if(!photo.getOriginalFilename().equals("")) {
//logger.info("파일 업로드 작업");
fileSave(idx, photo);
}
return page;
}
private void fileSave(int idx, MultipartFile file) {
//2-1. 파일을 C:/img/upload/ 에 저장
//2-1-1. 원본이름 추출
String oriFileName = file.getOriginalFilename();
//2-1-2. 확장자 추출
String ext = oriFileName.substring(oriFileName.lastIndexOf("."));
//2-1-3. 새 이름 생성 + 확장자
String newFileName = System.currentTimeMillis()+ext;
//logger.info(oriFileName+" >> "+newFileName);
//2-1-4. 바이트 추출
try {
byte[] bytes = file.getBytes();
//2-1-5. 추출한 바이트 저장
Path path = Paths.get("C:/img/upload/"+newFileName);
Files.write(path, bytes);
//logger.info(newFileName+" save OK");
} catch (IOException e) {
e.printStackTrace();
}
//2-2. 저장정보를 DB에 저장
dao.fileWrite(idx,oriFileName,newFileName);
//2-2-1. 가져온 idx, oriFileName, newFileName을 insert
}
public BoardDTO detail(String idx, String flag) {
if(flag.equals("detail")) {
dao.upHit(idx); //조회수 증가
}
BoardDTO dto = dao.detail(idx);
logger.info("dto : "+dto);
return dto;
}
public void delete(String idx) {
//1. photo에 해당 idx 값이 있는지
String newFileName = dao.findFile(idx);
logger.info("file name : "+newFileName);
//2. 없을 경우?
int row = dao.delete(idx);
logger.info("delete deta : "+row);
//3. 있을 경우?
//3-1. bbs와 photo가 확실히 삭제되었는지?
if(newFileName != null && row > 0) {
//3-2. 해당 파일이 존재하는지?
File file = new File("C:/img/upload/"+newFileName);
if(file.exists()) {
//3-3. 삭제
file.delete();
}
}
}
public String update(MultipartFile photo, HashMap<String, String> params) {
String page = "redirect:/list.do";
int idx;
//1. update 실행
int row = dao.update(params);
//2. photo에 파일명이 존재 한다면?
idx = Integer.parseInt(params.get("idx"));
if(photo != null && !photo.getOriginalFilename().equals("")) {
fileSave(idx,photo);
}
page = "redirect:/detail.do?idx="+idx;
return page;
}
}
- Inter(=DAO)
package kr.co.gudi.dao;
import java.util.ArrayList;
import java.util.HashMap;
import kr.co.gudi.dto.BoardDTO;
public interface BoardInter {
ArrayList<BoardDTO> list();
int write(BoardDTO dto);
void fileWrite(int idx, String oriFileName, String newFileName);
void upHit(String idx);
BoardDTO detail(String idx);
int delete(String idx);
String findFile(String idx);
int update(HashMap<String, String> params);
}
- board_mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- xml 을 java 에서 쓰기 위해 연결되는 interface 가 필요 하다. -->
<mapper namespace="kr.co.gudi.dao.BoardInter">
<select id="list" resultType="kr.co.gudi.dto.BoardDTO">
SELECT
idx,subject,user_name,bHit,reg_date
FROM bbs ORDER BY idx
</select>
<!-- 방금 insert 한 값의 key를 반환 받는 방법 -->
<!-- 조건 2 : generatedKey 옵션을 사용해야함 -->
<!-- useGeneratedKeys="true"
keyColumn="idx" : 가져올 키 컬럼의 이름
keyProperty="idx" : DTO에 담을 필드 이름
-->
<insert
useGeneratedKeys="true"
keyColumn="idx"
keyProperty="idx"
id="write" parameterType="kr.co.gudi.dto.BoardDTO">
INSERT INTO bbs(subject,user_name,content)
VALUES(#{subject},#{user_name},#{content})
</insert>
<insert id="fileWrite">
INSERT INTO photo(idx,oriFileName,newFileName)
VALUES(#{param1},#{param2},#{param3})
</insert>
<update id="upHit">
UPDATE bbs SET bHit = bHit+1 WHERE idx = #{param1}
</update>
<select id="detail" resultType="kr.co.gudi.dto.BoardDTO">
SELECT b.subject, b.user_name, b.content, b.reg_date, b.idx,
p.photoIdx, p.newFileName
FROM bbs b LEFT JOIN photo p ON b.idx = p.idx WHERE b.idx = #{param1}
</select>
<delete id="delete">
DELETE FROM bbs WHERE idx = #{param1}
</delete>
<select id="findFile" resultType="String">
SELECT newFileName FROM photo WHERE idx = #{param1}
</select>
<update id="update" parameterType="hashmap">
UPDATE bbs SET subject = #{subject}, user_name= #{user_name}, content = #{content}
WHERE idx = #{idx}
</update>
</mapper>
'코딩도전기 > Spring' 카테고리의 다른 글
CODO Day46_Spring(Paging) (0) | 2023.04.07 |
---|---|
CODO Day45_Spring(AJAX) (0) | 2023.04.05 |
CODO Day43_Spring(FileService) (0) | 2023.04.03 |
CODO Day42_Spring(BoardApp) (0) | 2023.03.31 |
CODO Day41_Spring(MemberApp) (0) | 2023.03.30 |