<!-- 1개의 dto값 얻기 -->
<select id="getDataOfReboard" parameterType="int" resultType="bdto">
select * from reboard where num=#{num}
</select>
<!-- readcount 증가
sql문에서만 인자값이나 결과값으로 넘어가는데 2가지 이상일 경우 Map 사용 -->
<update id="UpdateReadCountOfReboard" parameterType="int">
update reboard set readcount=readcount+1 where num=#{num}
</update>
public BoardDto getData(int num);
public void UpdateReadcount(int num);
@Override
public BoardDto getData(int num) {
// TODO Auto-generated method stub
return session.selectOne("getDataOfReboard", num);
}
@Override
public void UpdateReadcount(int num) {
// TODO Auto-generated method stub
session.update("UpdateReadCountOfReboard", num);
}
@GetMapping("/board/content")
public ModelAndView content(@RequestParam int num,@RequestParam int currentPage)
{
ModelAndView model=new ModelAndView();
//조회수 증가
dao.UpdateReadcount(num);
BoardDto dto=dao.getData(num);
model.addObject("dto", dto);
model.addObject("currentPage", currentPage);
model.setViewName("reboard/content");
return model;
}
a태그에 img의 주소를 그대로 적으면 원본 사진으로 나오게 할 수 있다
<a href="../upload/${pho }">
<img alt="" src="../upload/${pho }" style="width: 150px;
border: 1px solid green; border-radius: 20px;">
</a>
BaordWriteController에서 넘겨준 것처럼 num,regroup,restep,relevel,currentPage 5가지를 넘겨줘야한다
<button class="btn btn-outline-secondary" onclick="location.href='writeform?num=${dto.num}®roup=${dto.regroup }&restep=${dto.restep }&relevel=${dto.relevel }¤tPage=${currentPage }'">답글달기</button>
1줄로 안쓰고 중간에 내리면 오류발생
게시물 마다의 비밀번호 입력 폼 띄우기
n페이지에 있는걸 넘겨주고 수정 해야지 그 페이지로 돌아가기 때문에 currentPage도 함께 넘겨줘야함
<button class="btn btn-outline-warning" onclick="location.href='updatepassform?num=${dto.num}¤tPage=${currentPage }'">수정</button>
삭제 동일
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 100px 100px;">
<table class="table table-bordered" style="width: 600px;">
<caption align="top"><b>내용보기</b></caption>
<tr>
<td>
<h2><b>${dto.subject }</b></h2>
<span style="float: right; margin-right: 20px;">
조회:${dto.readcount }
<fmt:formatDate value="${dto.writeday }" pattern="yyyy-MM-dd HH:mm"/>
</span>
</td>
<br>
<h5><b>작성자: ${dto.writer }</b></h5>
</tr>
<tr>
<td>
<pre>${dto.content }</pre>
<br><br>
<c:if test="${dto.photo!='no' }">
<c:forTokens var="pho" items="${dto.photo }" delims=",">
<!-- a태그에 img의 주소를 그대로 적으면 원본 사진으로 나오게 할 수 있다 -->
<a href="../upload/${pho }">
<img alt="" src="../upload/${pho }" style="width: 150px;
border: 1px solid green; border-radius: 20px;">
</a>
</c:forTokens>
</c:if>
</td>
</tr>
<tr>
<td align="right">
<button class="btn btn-outline-info" onclick="location.href='writeform'">글쓰기</button>
<button class="btn btn-outline-secondary" onclick="location.href='writeform?num=${dto.num}®roup=${dto.regroup }&restep=${dto.restep }&relevel=${dto.relevel }¤tPage=${currentPage }'">답글달기</button>
<!-- 게시물 마다의 비밀번호 입력 폼 띄우기
n페이지에 있는걸 넘겨주고 수정 해야지 그 페이지로 돌아가기 때문에 currentPage도 함께 넘겨줘야함 -->
<button class="btn btn-outline-warning" onclick="location.href='updatepassform?num=${dto.num}¤tPage=${currentPage }'">수정</button>
<button class="btn btn-outline-danger" onclick="location.href='deletepassform?num=${dto.num}¤tPage=${currentPage }'">삭제</button>
<button class="btn btn-outline-success" onclick="location.href='list?currentPage=${currentPage}'">목록</button>
</td>
</tr>
</table>
</div>
</body>
</html>
<!-- passform -->
<select id="checkpassEqualOfReboard" parameterType="HashMap" resultType="int">
select count(*) from reboard where num=#{num} and pass=#{pass}
</select>
<update id="updateOfReboard" parameterType="bdto">
update reboard set subject=#{subject},content=#{content}
<if test="photo!='no'"> <!-- photo!='no' 조건이 no일 경우 / 두가지 경우 모두 no나 null이 아닐경우 즉 사진이 있는 경우만 수정해준다는 조건
이렇게 조건 주면 기존 사진을 수정폼에 불러오지 않고 수정을 안해도 기존 사진이 남아있을 수 있다 -->
,photo=#{photo}
</if>
where num=#{num}
</update>
public int getCheckPass(int num,int pass);
public void updateReboard(BoardDto dto);
@Override
public int getCheckPass(int num, int pass) {
// TODO Auto-generated method stub
HashMap<String, Integer> map=new HashMap<String, Integer>();
map.put("num", num);
map.put("pass", pass);
return session.selectOne("checkpassEqualOfReboard", map);
}
@Override
public void updateReboard(BoardDto dto) {
// TODO Auto-generated method stub
session.update("updateOfReboard", dto);
}
@GetMapping("/board/updatepassform")
public ModelAndView upassform(@RequestParam String num,
@RequestParam String currentPage)
{
ModelAndView model= new ModelAndView();
model.addObject("num", num);
model.addObject("currentPage", currentPage);
model.setViewName("reboard/updatepassform");
return model;
}
@PostMapping("/board/updatepass")
public ModelAndView updatepass(@RequestParam int num,@RequestParam int currentPage,@RequestParam int pass)
{
ModelAndView model=new ModelAndView();
//비번이 맞으면 수정폼으로, 틀린 경우는 passfail로 이동
int check=dao.getCheckPass(num, pass);
if(check==1)
{
//비번이 맞으면 dto얻는다(수정폼으로 가기 위해서)
BoardDto dto=dao.getData(num);
model.addObject("currentPage", currentPage);
model.addObject("dto", dto);
model.setViewName("reboard/updateform");
}
else //0
model.setViewName("reboard/passfail");
return model;
}
0번지 사진을 항상 우선 하기 때문에 get(0)...uimage는 배열이기 때문에 0번지가 빈 문자열이면 사진이 없을 경우라는 뜻
if(uimage.get(0).getOriginalFilename().equals(""))
photo="no";
수정 시 기존 사진 파일 삭제 후
else {
if(!photo.equals("no"))
{
String del[]=prephoto.split(",");
for(int i=0;i<del.length;i++)
{
//파일을 생성하는데 해당경로에 num에 해당하는 사진파일만
File file=new File(path+"/"+del[i]);
//기존 사진 파일 삭제
file.delete();
}
}
수정시 추가한 사진 넣기
for(MultipartFile f:uimage)
{
String fName=sdf.format(new Date())+"_"+f.getOriginalFilename();
photo+=fName+",";
try {
f.transferTo(new File(path+"/"+fName));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//for문 안 photo에서 마지막 , 제거(길이 제일 마지막에 , 있음)
photo=photo.substring(0, photo.length()-1);
}
//dto의 photo에 넣기
dto.setPhoto(photo);
//update
dao.updateReboard(dto);
currentPage와 num값을 가져와서 넘겨주기 위해 맵핑주소에 넣어준다
수정 후 content로 이동
return "redirect:content?currentPage="+currentPage+"&num="+num;
@PostMapping("/board/update")
public String update(@ModelAttribute BoardDto dto,
@RequestParam int num,
@RequestParam String currentPage,
@RequestParam ArrayList<MultipartFile> uimage,
HttpSession session)
{
//실제경로
String path=session.getServletContext().getRealPath("/WEB-INF/photo");
System.out.println(path);
String prephoto=dao.getData(num).getPhoto();
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
String photo="";
//0번지 사진을 항상 우선 하기 때문에 get(0)...uimage는 배열이기 때문에 0번지가 빈 문자열이면 사진이 없을 경우라는 뜻
if(uimage.get(0).getOriginalFilename().equals(""))
photo="no";
else {
if(!photo.equals("no"))
{
String del[]=prephoto.split(",");
for(int i=0;i<del.length;i++)
{
//파일을 생성하는데 해당경로에 num에 해당하는 사진파일만
File file=new File(path+"/"+del[i]);
//기존 사진 파일 삭제
file.delete();
}
}
for(MultipartFile f:uimage)
{
String fName=sdf.format(new Date())+"_"+f.getOriginalFilename();
photo+=fName+",";
try {
f.transferTo(new File(path+"/"+fName));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//for문 안 photo에서 마지막 , 제거(길이 제일 마지막에 , 있음)
photo=photo.substring(0, photo.length()-1);
}
//dto의 photo에 넣기
dto.setPhoto(photo);
//update
dao.updateReboard(dto);
//currentPage와 num값을 가져와서 넘겨주기 위해 맵핑주소에 넣어준다
return "redirect:content?currentPage="+currentPage+"&num="+num; //content 일단 없으니까 목록으로
}
package board.data.controller;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import spring.mvc.reboard.BoardDao;
import spring.mvc.reboard.BoardDto;
@Controller
public class BoardUpdateController {
@Autowired
BoardDao dao;
@GetMapping("/board/updatepassform")
public ModelAndView upassform(@RequestParam String num,
@RequestParam String currentPage)
{
ModelAndView model= new ModelAndView();
model.addObject("num", num);
model.addObject("currentPage", currentPage);
model.setViewName("reboard/updatepassform");
return model;
}
@PostMapping("/board/updatepass")
public ModelAndView updatepass(@RequestParam int num,@RequestParam int currentPage,@RequestParam int pass)
{
ModelAndView model=new ModelAndView();
//비번이 맞으면 수정폼으로, 틀린 경우는 passfail로 이동
int check=dao.getCheckPass(num, pass);
if(check==1)
{
//비번이 맞으면 dto얻는다(수정폼으로 가기 위해서)
BoardDto dto=dao.getData(num);
model.addObject("currentPage", currentPage);
model.addObject("dto", dto);
model.setViewName("reboard/updateform");
}
else //0
model.setViewName("reboard/passfail");
return model;
}
@PostMapping("/board/update")
public String update(@ModelAttribute BoardDto dto,
@RequestParam int num,
@RequestParam String currentPage,
@RequestParam ArrayList<MultipartFile> uimage,
HttpSession session)
{
//실제경로
String path=session.getServletContext().getRealPath("/WEB-INF/photo");
System.out.println(path);
String prephoto=dao.getData(num).getPhoto();
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
String photo="";
//0번지 사진을 항상 우선 하기 때문에 get(0)...uimage는 배열이기 때문에 0번지가 빈 문자열이면 사진이 없을 경우라는 뜻
if(uimage.get(0).getOriginalFilename().equals(""))
photo="no";
else {
if(!photo.equals("no"))
{
String del[]=prephoto.split(",");
for(int i=0;i<del.length;i++)
{
//파일을 생성하는데 해당경로에 num에 해당하는 사진파일만
File file=new File(path+"/"+del[i]);
//기존 사진 파일 삭제
file.delete();
}
}
for(MultipartFile f:uimage)
{
String fName=sdf.format(new Date())+"_"+f.getOriginalFilename();
photo+=fName+",";
try {
f.transferTo(new File(path+"/"+fName));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//for문 안 photo에서 마지막 , 제거(길이 제일 마지막에 , 있음)
photo=photo.substring(0, photo.length()-1);
}
//dto의 photo에 넣기
dto.setPhoto(photo);
//update
dao.updateReboard(dto);
//currentPage와 num값을 가져와서 넘겨주기 위해 맵핑주소에 넣어준다
return "redirect:content?currentPage="+currentPage+"&num="+num; //content 일단 없으니까 목록으로
}
}
delete 시 똑같이 사용되서 복사후 delpassform에 작성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 200px 200px;">
<form action="updatepass" method="post">
<input type="hidden" name="num" value="${num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<div class="alert alert-warning" style="width: 300px; font-size: 1.3em;">
<b>비밀번호를 입력해 주세요</b>
</div>
<div class="d-inline-flex">
<input type="password" name="pass" class="form-control"
style="width: 120px;" required="required">
<button type="submit" class="btn btn-outline-warning">수정하기</button>
<button type="button" class="btn btn-outline-secondary"
onclick="history.back()">이전으로</button>
</div>
</form>
</div>
</body>
</html>
alert창을 따로 줄 수 없어서 jsp파일 1개에 더 만듬
updateform과 똑같이 delete에서도 사용되는데 passfail은 mapping 주소가 없어서 그대로 재활용
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
alert("비밀번호가 맞지 않습니다");
history.back();
</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"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 50px 100px;">
<form action="update" method="post" enctype="multipart/form-data">
<!-- hidden 5개 paging이 없다면 4개 -->
<input type="hidden" name="num" value="${dto.num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<table class="table table-bordered" style="width: 500px;">
<caption align="top"><b>
<c:if test="${dto.relevel==0 }">
원글 수정하기
</c:if>
<c:if test="${dto.relevel!=0 }">
답글 수정하기
</c:if>
</b></caption>
<tr>
<th>작성자</th>
<td>
<input type="text" name="writer" class="form-control" required="required"
style="width: 120px;" value="${dto.writer }">
</td>
</tr>
<tr>
<th>제목</th>
<td>
<input type="text" name="subject" class="form-control" required="required"
style="width: 300px;" value="${dto.subject }">
</td>
</tr>
<tr>
<th>사진</th>
<td>
<input type="file" name="uimage" class="form-control" style="width: 220px;" multiple="multiple">
</td>
</tr>
<tr>
<td colspan="2">
<textarea style="width: 480px; height: 130px;" name="content" required="required"
class="form-control">${dto.content }</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="btn btn-outline-warning" style="width: 100px;">수정하기</button>
<button type="button" class="btn btn-outline-success" style="width: 100px;"
onclick="location.href='list'">목록</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
<delete id="deleteOfReboard" parameterType="int">
delete from reboard where num=#{num}
</delete>
public void deleteReboard(int num);
@Override
public void deleteReboard(int num) {
// TODO Auto-generated method stub
session.delete("deleteOfReboard", num);
}
update에서 사용한 것과 똑같은 것
@GetMapping("/board/deletepassform")
public ModelAndView delpassform(@RequestParam String num,
@RequestParam String currentPage)
{
ModelAndView model= new ModelAndView();
model.addObject("num", num);
model.addObject("currentPage", currentPage);
model.setViewName("reboard/delpassform");
return model;
}
@PostMapping("/board/delpass")
public ModelAndView delpass(@RequestParam int num,
@RequestParam int pass,
@RequestParam String currentPage,
HttpSession session)
{
ModelAndView model=new ModelAndView();
int check=dao.getCheckPass(num, pass);
if(check==1)
{
//해당 num의 정보 중 photo만 가져옴
String photo=dao.getData(num).getPhoto();
//photo가 no이면 삭제할 필요가 없음 (업로드한 사진파일이 없기 때문)
if(!photo.equals("no"))
{
String path=session.getServletContext().getRealPath("/WEB-INF/photo/");
String del[]=photo.split(",");
for(int i=0;i<del.length;i++)
{
//파일을 생성하는데 해당경로에 num에 해당하는 사진파일만
File file=new File(path+"/"+del[i]);
//기존 사진 파일 삭제
file.delete();
}
}
dao.deleteReboard(num);
model.setViewName("redirect:list?currentPage="+currentPage);
}
else {
model.setViewName("reboard/passfail");
}
return model;
}
update시 사용한 비밀번호 체크폼과 같은 것
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 200px 200px;">
<form action="delpass" method="post">
<input type="hidden" name="num" value="${num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<div class="alert alert-danger" style="width: 300px; font-size: 1.3em;">
<b>비밀번호를 입력해 주세요</b>
</div>
<div class="d-inline-flex">
<input type="password" name="pass" class="form-control"
style="width: 120px;" required="required">
<button type="submit" class="btn btn-outline-danger">삭제하기</button>
<button type="button" class="btn btn-outline-secondary"
onclick="history.back()">이전으로</button>
</div>
</form>
</div>
</body>
</html>
update에서 사용한 것과 동일한 것
비밀번호 틀릴시 alert용으로 사용
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cute+Font&family=Diphylleia&family=Dokdo&family=Nanum+Brush+Script&family=Nanum+Gothic+Coding&family=Noto+Sans+KR&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
alert("비밀번호가 맞지 않습니다");
history.back();
</script>
</body>
</html>