spring - 회원제 게시판 구현하기 - 게시판(7) [게시글 수정] (2022-11-07)
2022. 11. 8. 03:09ㆍ3층 1구역 - 개발의 장/Spring
1. 서론
이제 게시글을 수정해보도록 하자.
2. 본론
viewForm.jsp(전체)
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:url var="root" value="/" />
<center>
<form action="" method="post">
<input type="hidden" name="no" value="${board.no }" />
<input type="hidden" name="id" value="${board.id }" />
<input type="hidden" name="title" value="${board.title }"/>
<input type="hidden" name="content" value="${board.content }"/>
<table style="width: 650px; ">
<tr>
<td style="width: 300px; height:40px;" valign="middle"><h2>${board.title }</h2></td>
<td style="width: 350px; height:40px;" align="right" valign="bottom">${board.writeDate }</td>
</tr>
<tr>
<td colspan=2><hr/></td>
</tr>
<tr>
<td style="width: 300px; height:40px;" valign="top">${board.id }</td>
<td style="width: 350px; height:40px;" align="right" valign="top">
<c:if test="${board.fileName != '파일 없음' }">
<a href="${root }download?file=${board.fileName }">${board.fileName }</a>
</c:if>
</td>
</tr>
<tr>
<td colspan=2 style="width: 650px; height: 300px" valign="top">
<pre>${board.content }</pre>
</td>
</tr>
<tr>
<td colspan=2><hr/></td>
</tr>
<tr>
<td colspan=2 align="right">
<input type=button style="width: 60px; " value='글쓰기' onclick="location.href='${root}index?formpath=write'"/>
<button formaction="${root }index?formpath=modify" style="width: 60px; ">수정</button>
<button formaction="${root }index?formpath=delete" style="width: 60px; ">삭제</button>
<input type=button style="width: 60px; " value='목록' onclick="location.href='${root}boardProc'"/>
</td>
</tr>
</table>
</form>
</center>
만약 수정이나 삭제를 클릭할 경우 form태그에 의해 input 히든에 정보를 담아 보내주도록 해주었다.
그렇게 되면 수정일 경우 modify라는 value값에 히든의 정보가 담길 것이고,
삭제라면 delete이라는 value값에 히든의 정보가 담길 것이다.
HomeController.java(전체)
package com.care.pra;
import javax.servlet.http.HttpSession;
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 com.care.pra.board.BoardDTO;
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
// http://localhost:8085/pra/
// '/'를 입력할 경우 맵핑 시작
@RequestMapping(value = "/")
public String index(Model model) {
// Model을 통해 formpath라는 이름에 들어가는 값을 home.jsp로 지정
model.addAttribute("formpath", "home");
// 맵핑했을 때 index.jsp를 반환하여 웹에 띄워준다.
return "index";
}
@RequestMapping(value = "index")
public void index(String formpath, Model model, String modifyId, HttpSession session) {
// Model을 통해 formpath라는 이름에 들어가는 값을 formpath로 지정
// formpath의 값은 top.jsp에서 쓰이게 된다.
// top.jsp에서 url을 지정하게 되는데 formpath='Controller부분의' value값으로 설정할 경우
// value를 맵핑하여 각각의 값을 return한다.
model.addAttribute("formpath", formpath);
/*
* 수정 버튼에서 보내준 아이디를 세션에 저장하여 modifyCheck(비밀번호) 요청 처리함.
* if("modifyCheck".equals(formpath) )
*
* 세션에 저장된 값이 없으면 동작, 담겨 있다면 동작되지 않음.(비밀번호가 틀린 경우) A계정에서 B계정으로 변경해서 수정을 한다면 세션의
* modifyId 변경 if(sessionId == null || sessionId.equals(modifyId) == false)
*/
String sessionId = (String) session.getAttribute("modifyId");
if ("modifyCheck".equals(formpath) || "memberDelete".equals(formpath)) {
// 관리자가 A계정을 수정하려고 클릭한다면 modifyId에 A계정이 저장이 됨.
// 근데 A계정은 실수로 수정을 클릭한 것이고 원래는 B계정을 수정하고 싶었음.
// 근데 이미 modifyId에 A계정이 저장되어 있기 때문에
// A계정이 현재 선택한 B계정과 같지 않다면(sessionId.equals(modifyId) == false)
// 새로 B계정을 세션에 저장해줘 라는 뜻.(session.setAttribute("modifyId", modifyId);)
if (sessionId == null || sessionId.equals(modifyId) == false)
session.setAttribute("modifyId", modifyId);
}
}
// index메소드, memberDelete(패스워드 입력), deleteAndCheckProc(패스워드 체크 및 삭제), home
@RequestMapping(value = "memberDelete")
public String memberDelete() {
return "member/memberDeleteForm";
}
// index메소드, modfiyCheck(패스워드 입력), modifyCheckProc(패스워드 체크), memberModify
@RequestMapping(value = "modifyCheck")
public String modifyCheck() {
return "member/modifyCheckForm";
}
@RequestMapping(value = "memberModify")
public String memberModfiy() {
return "member/memberModifyForm";
}
// http://localhost:8085/pra/index?formpath=home
@RequestMapping(value = "home")
public void home() {
}
// http://localhost:8085/pra/index?formpath=login
@RequestMapping(value = "login")
public String login() {
return "member/loginForm";
}
// http://localhost:8085/pra/index?formpath=member
@RequestMapping(value = "member")
public String member() {
return "member/memberForm";
}
// http://localhost:8085/pra/memberListProc
@RequestMapping(value = "memberList")
public String memberList() {
return "member/memberListForm";
}
// http://localhost:8085/pra/userInfoProc?id=${db.id}
@RequestMapping(value = "userInfo")
public String userInfo() {
return "member/userInfoForm";
}
// http://localhost:8085/pra/index?formpath=board
@RequestMapping(value = "board")
public String board() {
return "board/boardForm";
}
//로그인 된 계정 접근
@Autowired HttpSession session;
public String checkSession(String url) {
String id = (String)session.getAttribute("id");
//만약 로그인이 안되어 있다면
if(id == null)
//게시글 목록으로 보낸다.
return "board/boardForm";
//로그인 되어있다면 url정보를 반환한다.
return url;
}
@RequestMapping(value = "/view")
public String view() {
String url = checkSession("board/viewForm");
return url;
}
@RequestMapping(value = "/write")
public String write() {
String url = checkSession("board/writeForm");
return url;
}
@RequestMapping(value = "modify")
public String modify(Model model, BoardDTO board) {
String url = checkSession("board/modifyForm");
String id = (String)session.getAttribute("id");
if(id.equals(board.getId()) == false)
return "home";
model.addAttribute("board", board); //modifyForm.jsp에서 출력할 데이터
return url;
}
}
HomeController.java(추가된 코드)
@RequestMapping(value = "modify")
public String modify(Model model, BoardDTO board) {
String url = checkSession("board/modifyForm");
String id = (String)session.getAttribute("id");
if(id.equals(board.getId()) == false)
return "home";
model.addAttribute("board", board); //modifyForm.jsp에서 출력할 데이터
return url;
}
viewForm.jsp에서 담아온 정보는 위 코드로 보내지며 DTO에 담아서 modifyForm.jsp로 가도록 해주었다.
modifyForm.jsp(전체)
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:url var="root" value="/" />
<center>
<form action="${root }modifyProc" method="post">
<input type="hidden" name="no" value="${board.no }" />
<table style="width: 650px;">
<tr>
<td style="width: 80px; height: 40px;" align="right">작성자</td>
<td style="width: 570px; height: 40px;"><input type=text
name='id' value="${sessionScope.id }" disabled="disabled" /></td>
</tr>
<tr>
<td style="width: 80px; height: 40px;" align="right">제 목</td>
<td style="width: 570px; height: 40px;"><input type=text
name='title' style="width: 500px;" value="${board.title }" /></td>
</tr>
<tr>
<td colspan=2 align="right"><textarea name="content"
style="width: 650px; height: 300px">${board.content }
</textarea></td>
</tr>
<!-- 파일의 수정 기능은 제공하지 않음. 삭제 후 다시 등록하면 됨. -->
<tr>
<td align='center' height=40 colspan=2><input type=submit
value='수정' style="width: 120px;" /> <input type=reset value='취소'
style="width: 120px;" /></td>
</tr>
</table>
</form>
</center>
DTO에 담긴 정보는 여기서 뿌려지게 되며
뿌려진 정보는 그대로 가거나 정보가 수정되어 form태그에 의해 modifyProc이라는 value값이 있는 곳으로 가게 된다.
BoardController.java(전체)
package com.care.pra.board.controller;
import java.io.File;
import java.io.FileInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
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.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.care.pra.board.BoardDTO;
import com.care.pra.board.service.IBoardService;
@Controller
public class BoardController {
//console창에 해당 로그가 찍힌다. 따라서 프로그램의 오류 발생 시 어디서 어떤 이유로 오류가 발생했는지
//알 수 있어 이슈처리가 용이하다.
final static Logger logger = LoggerFactory.getLogger(BoardController.class);
@Autowired IBoardService service;
@RequestMapping(value = "writeProc")
public String writeProc(MultipartHttpServletRequest multi) {
service.writeProc(multi);
return "forward:boardProc";
}
@RequestMapping(value = "boardProc")
public String boardProc(Model model,
@RequestParam(value = "currentPage", required = false, defaultValue = "1")int currentPage,
String search, String select, HttpServletRequest req) {
service.boardProc(model, currentPage, search, select, req);
return "forward:/index?formpath=board";
}
//제이쿼리를 통해 viewProc값을 받게 된다.
@RequestMapping(value = "viewProc")
public String viewProc(@RequestParam(value = "writeNo", required = false) String writeNo, Model model) {
//만약 게시물 번호가 없거나 비어있다면
if(writeNo == null || writeNo == "")
return "forward:/index?formpath=board";
//넘겨받은 게시물의 번호를 정수 자료형으로 변환한다.
int no = Integer.parseInt(writeNo);
service.viewProc(no, model);
service.upHit(no);
return "forward:/index?formpath=view";
}
@RequestMapping(value = "download")
public void download(@RequestParam(value = "file") String fileName, HttpServletResponse res) throws Exception {
if(fileName == "" || "파일 없음".equals(fileName))
return;
res.addHeader("Content-disposition", "attachment; filename="+fileName);
File file = new File(IBoardService.FILE_LOCATION + "\\" + fileName);
FileInputStream input = new FileInputStream(file);
FileCopyUtils.copy(input, res.getOutputStream());
input.close();
}
@RequestMapping(value = "/modifyProc")
public String modifyProc(BoardDTO board, HttpSession session) {
boolean check = service.modifyProc(board);
if(check == false) {
return "forward:index?formpath=modify";
}
//얘를 줄 경우 로그인 정보까지 전부 삭제
// session.invalidate();
return "forward:boardProc";
}
}
BoardController.java(추가된 코드)
@RequestMapping(value = "/modifyProc")
public String modifyProc(BoardDTO board, HttpSession session) {
boolean check = service.modifyProc(board);
if(check == false) {
return "forward:index?formpath=modify";
}
//얘를 줄 경우 로그인 정보까지 전부 삭제
// session.invalidate();
return "forward:boardProc";
}
form태그에 의해 보내진 정보들은 service에서 검증 및 데이터베이스에 저장 후 true나 false를 반환할텐데??
IBoardService.java(전체)
package com.care.pra.board.service;
import javax.servlet.http.HttpServletRequest;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.care.pra.board.BoardDTO;
public interface IBoardService {
String FILE_LOCATION = "C:\\javas\\upload";
// 게시물 작성 및 첨부파일
void writeProc(MultipartHttpServletRequest multi);
// 게시물 상세 보기
void viewProc(int no, Model model);
// 게시물 목록
void boardProc(Model model, int currentPage, String search, String select, HttpServletRequest req);
// 조회 수
void upHit(int no);
//게시글 수정
boolean modifyProc(BoardDTO board);
//게시글 내에 삭제 버튼을 통한 삭제
boolean deleteProc(String pw, String pwOk, String no);
//체크 박스를 이용한 다중 삭제
boolean deletes(String pw, String pwOk, String[] checks);
}
BoardServiceImpl.java(전체)
package com.care.pra.board.service;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.care.pra.board.BoardDTO;
import com.care.pra.board.repository.IBoardDAO;
import com.care.pra.membership.service.PageService;
@Service
public class BoardServiceImpl implements IBoardService{
@Autowired IBoardDAO mapper;
@Autowired HttpSession session;
@Override
public void writeProc(MultipartHttpServletRequest multi) {
String id = (String)session.getAttribute("id");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
MultipartFile file = multi.getFile("fileName");
BoardDTO dto = new BoardDTO();
dto.setId(id);
dto.setTitle(title);
dto.setContent(content);
dto.setHit(0);
SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String writeDate = writeFormat.format(date);
dto.setWriteDate(writeDate);
if(file.getSize() != 0) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss-");
Calendar calen = Calendar.getInstance();
String fileName = sdf.format(calen.getTime()) + file.getOriginalFilename();
dto.setFileName(fileName);
File save = new File(IBoardService.FILE_LOCATION + "\\" + fileName);
System.out.println(file.getOriginalFilename());
try {
file.transferTo(save);
} catch (Exception e) {
e.printStackTrace();
}
}else
dto.setFileName("파일 없음");
mapper.writeProc(dto);
}
@Override
public void viewProc(int no, Model model) {
model.addAttribute("board", mapper.viewProc(no));
}
@Override
public void boardProc(Model model, int currentPage, String search, String select, HttpServletRequest req) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("search", search);
map.put("select", select);
int totalCount = mapper.boardCount(map);
int pageBlock = 3;
int end = currentPage * pageBlock;
int begin = end+1 - pageBlock;
ArrayList<BoardDTO> boardList = mapper.boardProc(begin, end, select, search);
model.addAttribute("boardList", boardList);
String url = req.getContextPath() + "/boardProc?";
if(select != null) {
url+="select="+select+"&";
url+="search="+search+"&";
}
url+="currentPage=";
model.addAttribute("page", PageService.getNavi(currentPage, pageBlock, totalCount, url));
}
@Override
public void upHit(int no) {
mapper.upHit(no);
}
@Override
public boolean modifyProc(BoardDTO board) {
int result = mapper.modifyProc(board);
if(result == 0)
return false;
return true;
}
@Override
public boolean deleteProc(String pw, String pwOk, String no) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean deletes(String pw, String pwOk, String[] checks) {
// TODO Auto-generated method stub
return false;
}
}
BoardServiceImpl.java(추가된 코드)
@Override
public boolean modifyProc(BoardDTO board) {
int result = mapper.modifyProc(board);
if(result == 0)
return false;
return true;
}
BoardController에서 보낸 값(BoardDTO)을 성공적으로 수정했다면 1을
뭔가 문제가 있다면 0의 값을 준다.
IBoardDAO.java(전체)
package com.care.pra.board.repository;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.care.pra.board.BoardDTO;
@Repository
public interface IBoardDAO {
void writeProc(BoardDTO dto);
ArrayList<BoardDTO> boardProc(@Param("b") int begin, @Param("e")int end, @Param("sel")String sel, @Param("search") String search);
public int boardCount(HashMap<String, Object> map);
BoardDTO viewProc(int no);
void upHit(int no);
int modifyProc(BoardDTO board);
}
boardMapper.xml(전체)
<?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">
<mapper namespace="com.care.pra.board.repository.IBoardDAO">
<insert id="writeProc" parameterType="com.care.pra.board.BoardDTO">
<selectKey keyProperty="no" resultType="int" order="BEFORE">
SELECT nvl(max(no), 0)+1 FROM quiz_board
</selectKey>
INSERT INTO quiz_board VALUES(#{no}, #{id}, #{title}, #{content}, #{fileName}, #{writeDate}, #{hit} )
</insert>
<select id="boardProc" resultType="com.care.pra.board.BoardDTO">
SELECT B.* FROM(
SELECT rownum rn, A.* FROM(
SELECT * FROM quiz_board
<choose>
<when test="sel == 'id'">WHERE id LIKE '%'||#{search}||'%'</when>
<when test="sel == 'title'">WHERE title LIKE '%'||#{search}||'%'</when>
</choose>
ORDER BY no DESC
)A
)B WHERE rn BETWEEN #{b} and #{e}
</select>
<select id="boardCount" resultType="int" parameterType="HashMap">
SELECT count(*) FROM quiz_board
<choose>
<when test="sel == 'id'">WHERE id LIKE '%'||#{search}||'%'</when>
<when test="sel == 'title'">WHERE title LIKE '%'||#{search}||'%'</when>
</choose>
</select>
<select id="viewProc" resultType="com.care.pra.board.BoardDTO" parameterType="int">
SELECT * FROM quiz_board WHERE no=#{no}
</select>
<update id="upHit" parameterType="int" >
UPDATE quiz_board SET hit=hit+1 WHERE no=#{no}
</update>
<update id="modifyProc" parameterType="com.care.pra.board.BoardDTO" >
UPDATE quiz_board SET title=#{title}, content=#{content} WHERE no=#{no}
</update>
</mapper>
3. 결론
수정할 때 비밀번호 체크가 있고 없고 차이가 이렇게 대단하구나...........;;;;
'3층 1구역 - 개발의 장 > Spring' 카테고리의 다른 글
spring - 회원제 게시판 구현하기 - 게시판(6) [페이징, 검색] (2022-11-07) (0) | 2022.11.08 |
---|---|
spring - 회원제 게시판 구현하기 - 게시판(5) [조회수 증가] (2022-11-07) (0) | 2022.11.08 |
spring - 회원제 게시판 구현하기 - 게시판(4) [다운로드] (2022-11-07) (0) | 2022.11.07 |
spring - 회원제 게시판 구현하기 - 게시판(3) [게시글 보기] (2022-11-07) (0) | 2022.11.07 |
spring - 회원제 게시판 구현하기 - 게시판(2) [목록 보기] (2022-11-07) (0) | 2022.11.07 |