-
appServlet => servlet-context.xml 내용추가
-
pom.xml 내용추가
-
src/main/resources => messages 폴더 => validation.properties 파일
-
servlet-context.xml 내용추가
-
BoardController 내용추가
-
resources/css => style.css 내용추가
-
src/main/resources => config => jdbc.properties
-
root-context.xml 내용추가
-
kr.spring.board.dao =>BoardDAO (클래스가 아닌 인터페이스)
-
kr.spring.board.dao => BoardDAOImpl(클래스)
-
데이터 베이스 연동
-
BoardDAOImpl
-
kr.spring.board.service => BoardService (인터페이스)
-
kr.spring.board.service =>BoardServiceImpl
-
BoardController 내용추가
-
-
BoardDAOImpl
-
BoardServiceImpl
-
kr.spring.util => PagingUtil.java (이전 프로젝트에서 가져옴)
-
BoardController 내용추가
-
views/selectList.jsp 내용추가
-
BoardDAOImpl 내용추가
-
BoardServiceImpl 내용추가
-
BoardController 내용추가
-
views => selectDetail.jsp
-
수정폼 만들기
-
BoardController 내용추가
-
views => updateForm.jsp
-
수정
-
BoardDAOImpl 내용추가
-
BoardServiceImpl 내용추가
-
BoardController 내용추가
-
삭제
-
BoardDAOImpl 내용추가
-
BoardServiceImpl 내용추가
-
BoardController 내용추가
-
view=>deleteForm.jsp
-
BoardController 내용추가
버전 일부 수정


appServlet => servlet-context.xml 내용추가
<!-- 정적 파일을 요청할 때 /resources/** 패턴의 모든 요청을
location에 지정한 경로 /resources/에 있는 파일에 매핑 -->
<resources location="/resources/" mapping="/resources/**"/>


BoardVO 내용추가
package kr.spring.board.vo;
import java.sql.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
/*
* @NotNull : null만 허용하지 않음
* @NotBlank : null, ""(빈문자열)," "(공백)을 모두 허용하지않음
* @NotEmpty : null, ""(빈문자열)을 허용하지 않음
*/
public class BoardVO {
private int num;
@NotBlank
private String writer;
@NotBlank
private String title;
@NotBlank
private String passwd;
@NotEmpty
private String content;
private Date reg_date;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
@Override
public String toString() {
return "BoardVO [num=" + num + ", writer=" + writer + ", title=" + title + ", passwd=" + passwd + ", content="
+ content + ", reg_date=" + reg_date + "]";
}
}
pom.xml 내용추가
VO에 @Blank 같은 것들이 작동이 되지않는 부분을 dependency로 해결
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
src/main/resources => messages 폴더 => validation.properties 파일
NotBlank.writer=작성자는 필수 항목
NotBlank.title=제목은 필수 항목
NotBlank.passwd=비밀번호는 필수 항목
NotEmpty.content=내용은 필수 항목
invalidPassword=비밀번호 불일치
servlet-context.xml 내용추가
<!-- 리소스 번들 지정 -->
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basenames">
<beans:list>
<beans:value>messages.validation</beans:value>
</beans:list>
</beans:property>
</beans:bean>
BoardController 내용추가
package kr.spring.board.controller;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
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.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import kr.spring.board.vo.BoardVO;
@Controller
public class BoardController {
//로그 처리 (로그 대상 지정)
private static final Logger log = LoggerFactory.getLogger(BoardController.class);
/*
* 로그 레벨
* FATAL : 가장 심각한 오류
* ERROR : 일반적인 오류
* WARN : 주의를 요하는 경우(경고, 에러는 아님)
* INFO : 런타임시 관심있는 경우
* DEBUG : 시스템 흐름과 관련된 상세 상태
* TRACE : 가장 상세한 정보
*/
//유효성 체크를 위한 폼 초기화
@ModelAttribute
public BoardVO initCommand() {
return new BoardVO();
}
//폼 호출
@GetMapping("/insert.do")
public String form() {
return "insertForm";
}
//전송된 데이터 처리
@PostMapping("/insert.do")
public String submit(@Valid BoardVO vo, BindingResult result) {
log.debug("<<BoardVO>> : "+vo);
//유효성 체크 결과 오류가 있으면 폼을 호출
if(result.hasErrors()) { //출력을 했을 떄 출력이 되지않은 것들을 확인하기 위해서 (즉 바로위에서 디버그하고 남은것들을 보여줌)
return form();
}
return "redirect:/list.do";
}
@RequestMapping("/list.do")
public ModelAndView process() {
ModelAndView mav = new ModelAndView();
mav.setViewName("selectList"); //중간 경로가 없음.
return mav;
}
}
log4j.xml 에 이 내용이 있어야지 디버그 모드가 적용되기 때문에 없으면 필히 넣어야됨.
kr.spring의 하위레벨은 디버그 모드이다. 라는 내용
<!-- Application Loggers -->
<logger name="kr.spring">
<level value="debug" />
</logger>

DEBUG: kr.spring.board.controller.BoardController - <<BoardVO>> : BoardVO [num=0, writer=, title=, passwd=, content=, reg_date=null]
resources/css => style.css 내용추가
.error-color{
color:red;
}
src/main/resources => config => jdbc.properties
jdbc.driverClassName=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe
jdbc.username=user01
jdbc.password=1234
이 파일을 root-context.xml에 연결되도록한다.
root-context.xml 내용추가
<context>태그가 인식되도록
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
beans xmlns를 수정한다
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 빈 자동 스캔 -servlet-context.xml에서 Controller를 자동 스캔 설정해서 아래 설정에서는 Controller 자동 스캔 제외 시키기-->
<context:component-scan base-package="kr.spring.board">
<!-- org.springframework.stereotype.Controller를 자동스캔에서 빼겠다라는 뜻 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<context:property-placeholder location="classpath:config/jdbc.properties"/>
<!-- 커넥션풀을 이용한 DataSource 설정 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/> <!-- ${}안에 값이 키값이고 호출할 때 이 값을 사용 -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 최대 커넥션 개수 -->
<property name="maxActive" value="50"/>
<!-- 접속이 없을 경우 최대 유지 커넥션 개수 -->
<property name="maxIdle" value="30"/>
<!-- 접속이 없을 경우 최소 유지 커넥션 개수 -->
<property name="minIdle" value="20"/>
<!-- 최대 대기시간(초) : 초과시 연결 실패 오류 발생하게함-->
<property name="maxWait" value="5"/><!-- 5초동안 연결시 에러발생 -->
</bean>
<!-- JdbcTemplate 객체 생성 -->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- JDBC 기반 트랜잭션 관리자 설정 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
<!-- 어노테이션 방식으로 처리할 때 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!-- 이 태그를 쓰면 어노테이션 방식으로 처리할 수 있다. -->
</beans>
kr.spring.board.dao =>BoardDAO (클래스가 아닌 인터페이스)
package kr.spring.board.dao;
import java.util.List;
import kr.spring.board.vo.BoardVO;
public interface BoardDAO {
public void insertBoard(BoardVO board);
public int getBoardCount();
public List<BoardVO> getBoardList(int startRow,int endRow);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
kr.spring.board.dao => BoardDAOImpl(클래스)
package kr.spring.board.dao;
import java.util.List;
import kr.spring.board.vo.BoardVO;
public class BoardDAOImpl implements BoardDAO{
@Override
public void insertBoard(BoardVO board) {
// TODO Auto-generated method stub
}
@Override
public int getBoardCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
// TODO Auto-generated method stub
return null;
}
@Override
public BoardVO getBoard(int num) {
// TODO Auto-generated method stub
return null;
}
@Override
public void updateBoard(BoardVO board) {
// TODO Auto-generated method stub
}
@Override
public void deleteBoard(int num) {
// TODO Auto-generated method stub
}
}
데이터 베이스 연동
BoardDAOImpl
@Repository //@DAO라고 생각하면 이해가 쉽다. Repository는 저장소라는 뜻으로, 데이터베이스 역시 저장소임.
public class BoardDAOImpl implements BoardDAO{
//SQL문을 정의하는 것
private static final String INSERT_SQL = "INSERT INTO aboard(num,writer,title,passwd,content,reg_date) VALUES(aboard_seq.nextval,?,?,?,?,SYSDATE)";
@Autowired // 연동은 주입을 받아서 처리해야됨으로 주입한다.
private JdbcTemplate jdbcTemplate;
@Override
public void insertBoard(BoardVO board) {
//INSERT를하든 DELETE를 하든 전부 .update 라고씀
//INSERT_SQL뒤에 오는 값들은 ?값들
jdbcTemplate.update(INSERT_SQL,new Object[] {board.getWriter(),board.getTitle(),board.getPasswd(),board.getContent()});
}
.
.
.
(생략)
kr.spring.board.service => BoardService (인터페이스)
BoardDAO와 같은 내용
package kr.spring.board.service;
import java.util.List;
import kr.spring.board.vo.BoardVO;
public interface BoardService {
public void insertBoard(BoardVO board);
public int getBoardCount();
public List<BoardVO> getBoardList(int startRow,int endRow);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
kr.spring.board.service =>BoardServiceImpl
package kr.spring.board.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import kr.spring.board.dao.BoardDAO;
import kr.spring.board.vo.BoardVO;
@Service //@Component와 같다고 생각하면됨
@Transactional //하위 메소드의 자동으로 transcation을 적용시킬 때
public class BoardServiceImpl implements BoardService{
@Autowired
private BoardDAO boardDAO;
@Override
public void insertBoard(BoardVO board) {
boardDAO.insertBoard(board);
}
@Override
public int getBoardCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
// TODO Auto-generated method stub
return null;
}
@Override
public BoardVO getBoard(int num) {
// TODO Auto-generated method stub
return null;
}
@Override
public void updateBoard(BoardVO board) {
// TODO Auto-generated method stub
}
@Override
public void deleteBoard(int num) {
// TODO Auto-generated method stub
}
}
BoardController 내용추가
@Autowired
private BoardService boardService;
//글 등록
boardService.insertBoard(vo);


BoardDAOImpl
페이지처리
private static final String SELECT_COUNT_SQL = "SELECT COUNT(*) FROM aboard";
@Override
public int getBoardCount() {
return jdbcTemplate.queryForObject(SELECT_COUNT_SQL, Integer.class);
}
목록작업
private static final String SELECT_LIST_SQL =
"SELECT * FROM (SELECT a.*, rownum rnum FROM("
+ "SELECT * FROM aboard ORDER BY reg_date DESC)a) "
+ "WHERE rnum>=? AND rnum<=?";
//하나의 레코드의 데이터를 자바빈에 매핑(목록처리를 할 때 사용)
private RowMapper<BoardVO> rowMapper = new RowMapper<BoardVO>() {
public BoardVO mapRow(ResultSet rs, int rowNum) throws SQLException{
BoardVO board = new BoardVO();
board.setNum(rs.getInt("num"));
board.setWriter(rs.getString("writer"));
board.setTitle(rs.getString("title"));
board.setPasswd(rs.getString("passwd"));
board.setContent(rs.getString("content"));
board.setReg_date(rs.getDate("reg_date"));
return board;
}
};
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
List<BoardVO> list = jdbcTemplate.query(SELECT_LIST_SQL,new Object[] {startRow,endRow},rowMapper);
return list;
}
BoardServiceImpl
페이지처리와 목록처리를 전달
@Override
public int getBoardCount() {
return boardDAO.getBoardCount();
}
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
return boardDAO.getBoardList(startRow, endRow);
}
kr.spring.util => PagingUtil.java (이전 프로젝트에서 가져옴)
페이지 처리를 위해서 가져옴
BoardServiceImpl에서 작성이 완료되면
BoardController 로 전달된다.
BoardController 내용추가
@RequestMapping("/list.do")
public ModelAndView process(@RequestParam(value="pageNum",defaultValue="1")int currentPage) {
int count = boardService.getBoardCount();
log.debug("<<count>> : "+count);
//페이지 처리
PagingUtil page = new PagingUtil(currentPage,count,20,10,"list.do");
//목록 호출
List<BoardVO> list = null;
if(count > 0 ) {
list = boardService.getBoardList(page.getStartRow(),page.getEndRow());
}
ModelAndView mav = new ModelAndView();
mav.setViewName("selectList"); //중간 경로가 없음.
mav.addObject("count",count);
mav.addObject("list",list);
mav.addObject("page",page.getPage());
return mav;
}
@RequestParam(value="pageNum",defaultValue="1")intcurrentPage 를 추가
이 코드 설명
- 파라미터가 있는 경우:
- 요청 URL: http://example.com/list.do?pageNum=3
- 결과: currentPage = 3
- 파라미터가 없는 경우:
- 요청 URL: http://example.com/list.do
- 결과: currentPage = 1 (기본값)
즉 currentPage 값에 pageNum 값이 들어간다.
views/selectList.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}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>게시판 목록</h2>
<div class="align-right">
<input type="button" value="글쓰기" onclick="location.href='insert.do'">
</div>
<c:if test="${count ==0}">
<div class="result-display">표시할 내용이 없습니다.</div>
</c:if>
<c:if test="${count >0}">
<table>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
</tr>
<c:forEach var="board" items="${list}">
<tr>
<td>${board.num}</td>
<td><a href="detail.do?num=${board.num}">${board.title}</a></td>
<td>${board.writer}</td>
<td>${board.reg_date}</td>
</tr>
</c:forEach>
</table>
<div class="align-center">${page}</div>
</c:if>
</div>
</body>
</html>

DEBUG: kr.spring.board.controller.BoardController - <<count>> : 1
WARN : org.springframework.web.servlet.PageNotFound - No mapping for GET /JDBC/detail.do
BoardDAOImpl 내용추가
detail 내용 추가
private static final String SELECT_DETAIL_SQL = "SELECT * FROM aboard WHERE num=?";
@Override
public BoardVO getBoard(int num) {
return jdbcTemplate.queryForObject(SELECT_DETAIL_SQL,new Object[] {num},rowMapper);
}
BoardServiceImpl 내용추가
@Override
public BoardVO getBoard(int num) {
return boardDAO.getBoard(num);
}
BoardController 내용추가
//글상세
@RequestMapping("/detail.do")
public ModelAndView detail(int num) {
log.debug("<<num>> : "+num);
BoardVO board = boardService.getBoard(num);
//뷰이름 , 속성명 , 속성값
return new ModelAndView("selectDetail","board",board);
}
}
views => selectDetail.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}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>${board.title}</h2>
<p>
글번호 : ${board.num}<br>
작성자 : ${board.writer}<br>
작성일 : ${board.reg_date}<br>
</p>
<hr width="90%" size="1" noshade="noshade">
<p>
${board.content}
</p>
<div class="align-center">
<input type="button" value="수정" onclick="location.href='update.do?num=${board.num}'">
<input type="button" value="삭제" onclick="location.href='delete.do?num=${board.num}'">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</div>
</body>
</html>

수정폼 만들기
BoardController 내용추가
//수정 폼
@GetMapping("/update.do")
public String formUpdate(int num,Model model) { //ModelAndView는 반환을 해줘야하지만 Model은 반환을 할 필요가없고 전달만 하면 된다.
model.addAttribute("boardVO",boardService.getBoard(num));
return "updateForm";
views => updateForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글수정</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page_main">
<h2>글수정</h2>
<form:form action="update.do" modelAttribute="boardVO">
<form:hidden path="num"/>
<ul>
<li>
<form:label path="writer">작성자</form:label>
<form:input path="writer"/>
<form:errors path="writer" cssClass="error-color"/>
</li>
<li>
<form:label path="title">제목</form:label>
<form:input path="title"/>
<form:errors path="title" cssClass="error-color"/>
</li>
<li>
<form:label path="passwd">비밀번호</form:label>
<form:password path="passwd"/>
<form:errors path="passwd" cssClass="error-color"/>
</li>
<li>
<form:label path="content">내용</form:label>
<form:textarea path="content"/>
<form:errors path="content" cssClass="error-color"/>
</li>
</ul>
<div class="align-center">
<form:button>수정</form:button>
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form:form>
</div>
</body>
</html>
BoardController 의 model.addAttribute("boardVO",boardService.getBoard(num));
여기에있는 boardVO와
updateForm.jsp 의 <form:form action="update.do" modelAttribute="boardVO">
여기에 있는 boardVO가 일치해야 결과가 올바르게 나온다.
추가로 <form:hidden path="num"/> 을 쓰지않으면 num값이 전달되지않아 수정이 되질않음

수정
BoardDAOImpl 내용추가
private static final String UPDATE_SQL = "UPDATE aboard SET writer=?,title=?,content=? WHERE num=?";
@Override
public void updateBoard(BoardVO board) {
jdbcTemplate.update(UPDATE_SQL,new Object[] {board.getWriter(),board.getTitle(),board.getContent(),board.getNum()});
}
BoardServiceImpl 내용추가
@Override
public void updateBoard(BoardVO board) {
boardDAO.updateBoard(board);
}
BoardController 내용추가
@PostMapping("/update.do") //이걸 명시하지않으면 Post로 전달하지못해서 에러가난다.
//전송된 데이터 처리
public String submitUpdate(@Valid BoardVO vo, BindingResult result ) {
log.debug("<<BoardVO>> : " +vo);
//유효성 체크 결과 오류가 있으면 폼을 호출
if(result.hasErrors()) {
return "updateForm"; //formUpdate 메서드를 리턴하지 않은이유는 num값과 model값을 같이 보내야되고 그게 코드가 더 길어지기 때문에 쓰지않음
}
//DB에 저장된 비밀번호 구하기(비밀번호 일치여부 확인을 위해)
BoardVO db_board = boardService.getBoard(vo.getNum());
//비밀번호 일치 여부 체크
//비밀번호가 일치하지 않을 떄
if(!db_board.getPasswd().equals(vo.getPasswd())) {
// 필드 에러코드
result.rejectValue("passwd","invalidPassword");
return "updateForm";
}
//비밀번호가 일치할 때
//글수정
boardService.updateBoard(vo);
return "redirect:/list.do";
}



삭제
BoardDAOImpl 내용추가
private static final String DELETE_SQL = "DELETE FROM aboard WHERE num=?";
@Override
public void deleteBoard(int num) {
jdbcTemplate.update(DELETE_SQL,new Object[] {num});
}
BoardServiceImpl 내용추가
@Override
public void deleteBoard(int num) {
boardDAO.deleteBoard(num);
}
BoardController 내용추가
//삭제 폼 호출
@GetMapping("/delete.do")
public String formDelete(BoardVO vo) {
return "deleteForm";
}
view=>deleteForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>글 삭제</h2>
<form:form action="delete.do" modelAttribute="boardVO">
<form:hidden path="num"/>
<ul>
<li>
<form:label path="passwd">비밀번호</form:label>
<form:password path="passwd"/>
<form:errors path="passwd" cssClass="error-color"/>
<li>
</ul>
<div class="align-center">
<input type="submit" value="삭제">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form:form>
</div>
</body>
</html>

BoardController 내용추가
//전송된 데이터 처리
@PostMapping("/delete.do")
public String submitDelete(@Valid BoardVO vo, BindingResult result) {
log.debug("<<BoardVO>> : "+ vo);
//BoardVO에는 비밀번호 말고도 title같은 것들이 @NotBlank로 쓰여져있는데 비밀번호만 쓰게하려함(이 방법을 안쓰면 VO를 따로 만들어야되는 번거로움이생김)
//비밀번호만 유효성 체크 결과 오류가 있으면 폼 호출
if(result.hasFieldErrors("passwd")) {//hasFieldErrors(): 괄호안에 값만 에러가 있는지 체크하는 함수
return "deleteForm";
}
//DB에 저장된 비밀번호 구하기
BoardVO db_board = boardService.getBoard(vo.getNum());
//비밀번호 일치 여부 체크
//비밀번호가 틀렸을 시
if(!db_board.getPasswd().equals(vo.getPasswd())) {
result.rejectValue("passwd","invalidPassword");
return "deleteForm";
}
boardService.deleteBoard(vo.getNum());
return "redirect:/list.do";
}



'쌍용교육(JAVA) > Spring' 카테고리의 다른 글
쌍용교육 -JSP수업 84일차 - ch11_SpringMybatisAnnot(1) (0) | 2024.06.21 |
---|---|
쌍용교육 -JSP수업 83일차 - ch10_SpringMybatis(1) (0) | 2024.06.21 |
쌍용교육 -JSP수업 81일차 - ch09_SpringJDBC(1) (0) | 2024.06.19 |
쌍용교육 -JSP수업 81일차 - ch08_SpringMVC(3) (0) | 2024.06.19 |
쌍용교육 -JSP수업 80일차 - ch08_SpringMVC(2) (0) | 2024.06.18 |
버전 일부 수정


appServlet => servlet-context.xml 내용추가
<!-- 정적 파일을 요청할 때 /resources/** 패턴의 모든 요청을
location에 지정한 경로 /resources/에 있는 파일에 매핑 -->
<resources location="/resources/" mapping="/resources/**"/>


BoardVO 내용추가
package kr.spring.board.vo;
import java.sql.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
/*
* @NotNull : null만 허용하지 않음
* @NotBlank : null, ""(빈문자열)," "(공백)을 모두 허용하지않음
* @NotEmpty : null, ""(빈문자열)을 허용하지 않음
*/
public class BoardVO {
private int num;
@NotBlank
private String writer;
@NotBlank
private String title;
@NotBlank
private String passwd;
@NotEmpty
private String content;
private Date reg_date;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
@Override
public String toString() {
return "BoardVO [num=" + num + ", writer=" + writer + ", title=" + title + ", passwd=" + passwd + ", content="
+ content + ", reg_date=" + reg_date + "]";
}
}
pom.xml 내용추가
VO에 @Blank 같은 것들이 작동이 되지않는 부분을 dependency로 해결
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
src/main/resources => messages 폴더 => validation.properties 파일
NotBlank.writer=작성자는 필수 항목
NotBlank.title=제목은 필수 항목
NotBlank.passwd=비밀번호는 필수 항목
NotEmpty.content=내용은 필수 항목
invalidPassword=비밀번호 불일치
servlet-context.xml 내용추가
<!-- 리소스 번들 지정 -->
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basenames">
<beans:list>
<beans:value>messages.validation</beans:value>
</beans:list>
</beans:property>
</beans:bean>
BoardController 내용추가
package kr.spring.board.controller;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
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.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import kr.spring.board.vo.BoardVO;
@Controller
public class BoardController {
//로그 처리 (로그 대상 지정)
private static final Logger log = LoggerFactory.getLogger(BoardController.class);
/*
* 로그 레벨
* FATAL : 가장 심각한 오류
* ERROR : 일반적인 오류
* WARN : 주의를 요하는 경우(경고, 에러는 아님)
* INFO : 런타임시 관심있는 경우
* DEBUG : 시스템 흐름과 관련된 상세 상태
* TRACE : 가장 상세한 정보
*/
//유효성 체크를 위한 폼 초기화
@ModelAttribute
public BoardVO initCommand() {
return new BoardVO();
}
//폼 호출
@GetMapping("/insert.do")
public String form() {
return "insertForm";
}
//전송된 데이터 처리
@PostMapping("/insert.do")
public String submit(@Valid BoardVO vo, BindingResult result) {
log.debug("<<BoardVO>> : "+vo);
//유효성 체크 결과 오류가 있으면 폼을 호출
if(result.hasErrors()) { //출력을 했을 떄 출력이 되지않은 것들을 확인하기 위해서 (즉 바로위에서 디버그하고 남은것들을 보여줌)
return form();
}
return "redirect:/list.do";
}
@RequestMapping("/list.do")
public ModelAndView process() {
ModelAndView mav = new ModelAndView();
mav.setViewName("selectList"); //중간 경로가 없음.
return mav;
}
}
log4j.xml 에 이 내용이 있어야지 디버그 모드가 적용되기 때문에 없으면 필히 넣어야됨.
kr.spring의 하위레벨은 디버그 모드이다. 라는 내용
<!-- Application Loggers -->
<logger name="kr.spring">
<level value="debug" />
</logger>

DEBUG: kr.spring.board.controller.BoardController - <<BoardVO>> : BoardVO [num=0, writer=, title=, passwd=, content=, reg_date=null]
resources/css => style.css 내용추가
.error-color{
color:red;
}
src/main/resources => config => jdbc.properties
jdbc.driverClassName=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe
jdbc.username=user01
jdbc.password=1234
이 파일을 root-context.xml에 연결되도록한다.
root-context.xml 내용추가
<context>태그가 인식되도록
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
beans xmlns를 수정한다
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 빈 자동 스캔 -servlet-context.xml에서 Controller를 자동 스캔 설정해서 아래 설정에서는 Controller 자동 스캔 제외 시키기-->
<context:component-scan base-package="kr.spring.board">
<!-- org.springframework.stereotype.Controller를 자동스캔에서 빼겠다라는 뜻 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<context:property-placeholder location="classpath:config/jdbc.properties"/>
<!-- 커넥션풀을 이용한 DataSource 설정 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/> <!-- ${}안에 값이 키값이고 호출할 때 이 값을 사용 -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 최대 커넥션 개수 -->
<property name="maxActive" value="50"/>
<!-- 접속이 없을 경우 최대 유지 커넥션 개수 -->
<property name="maxIdle" value="30"/>
<!-- 접속이 없을 경우 최소 유지 커넥션 개수 -->
<property name="minIdle" value="20"/>
<!-- 최대 대기시간(초) : 초과시 연결 실패 오류 발생하게함-->
<property name="maxWait" value="5"/><!-- 5초동안 연결시 에러발생 -->
</bean>
<!-- JdbcTemplate 객체 생성 -->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- JDBC 기반 트랜잭션 관리자 설정 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
<!-- 어노테이션 방식으로 처리할 때 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!-- 이 태그를 쓰면 어노테이션 방식으로 처리할 수 있다. -->
</beans>
kr.spring.board.dao =>BoardDAO (클래스가 아닌 인터페이스)
package kr.spring.board.dao;
import java.util.List;
import kr.spring.board.vo.BoardVO;
public interface BoardDAO {
public void insertBoard(BoardVO board);
public int getBoardCount();
public List<BoardVO> getBoardList(int startRow,int endRow);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
kr.spring.board.dao => BoardDAOImpl(클래스)
package kr.spring.board.dao;
import java.util.List;
import kr.spring.board.vo.BoardVO;
public class BoardDAOImpl implements BoardDAO{
@Override
public void insertBoard(BoardVO board) {
// TODO Auto-generated method stub
}
@Override
public int getBoardCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
// TODO Auto-generated method stub
return null;
}
@Override
public BoardVO getBoard(int num) {
// TODO Auto-generated method stub
return null;
}
@Override
public void updateBoard(BoardVO board) {
// TODO Auto-generated method stub
}
@Override
public void deleteBoard(int num) {
// TODO Auto-generated method stub
}
}
데이터 베이스 연동
BoardDAOImpl
@Repository //@DAO라고 생각하면 이해가 쉽다. Repository는 저장소라는 뜻으로, 데이터베이스 역시 저장소임.
public class BoardDAOImpl implements BoardDAO{
//SQL문을 정의하는 것
private static final String INSERT_SQL = "INSERT INTO aboard(num,writer,title,passwd,content,reg_date) VALUES(aboard_seq.nextval,?,?,?,?,SYSDATE)";
@Autowired // 연동은 주입을 받아서 처리해야됨으로 주입한다.
private JdbcTemplate jdbcTemplate;
@Override
public void insertBoard(BoardVO board) {
//INSERT를하든 DELETE를 하든 전부 .update 라고씀
//INSERT_SQL뒤에 오는 값들은 ?값들
jdbcTemplate.update(INSERT_SQL,new Object[] {board.getWriter(),board.getTitle(),board.getPasswd(),board.getContent()});
}
.
.
.
(생략)
kr.spring.board.service => BoardService (인터페이스)
BoardDAO와 같은 내용
package kr.spring.board.service;
import java.util.List;
import kr.spring.board.vo.BoardVO;
public interface BoardService {
public void insertBoard(BoardVO board);
public int getBoardCount();
public List<BoardVO> getBoardList(int startRow,int endRow);
public BoardVO getBoard(int num);
public void updateBoard(BoardVO board);
public void deleteBoard(int num);
}
kr.spring.board.service =>BoardServiceImpl
package kr.spring.board.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import kr.spring.board.dao.BoardDAO;
import kr.spring.board.vo.BoardVO;
@Service //@Component와 같다고 생각하면됨
@Transactional //하위 메소드의 자동으로 transcation을 적용시킬 때
public class BoardServiceImpl implements BoardService{
@Autowired
private BoardDAO boardDAO;
@Override
public void insertBoard(BoardVO board) {
boardDAO.insertBoard(board);
}
@Override
public int getBoardCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
// TODO Auto-generated method stub
return null;
}
@Override
public BoardVO getBoard(int num) {
// TODO Auto-generated method stub
return null;
}
@Override
public void updateBoard(BoardVO board) {
// TODO Auto-generated method stub
}
@Override
public void deleteBoard(int num) {
// TODO Auto-generated method stub
}
}
BoardController 내용추가
@Autowired
private BoardService boardService;
//글 등록
boardService.insertBoard(vo);


BoardDAOImpl
페이지처리
private static final String SELECT_COUNT_SQL = "SELECT COUNT(*) FROM aboard";
@Override
public int getBoardCount() {
return jdbcTemplate.queryForObject(SELECT_COUNT_SQL, Integer.class);
}
목록작업
private static final String SELECT_LIST_SQL =
"SELECT * FROM (SELECT a.*, rownum rnum FROM("
+ "SELECT * FROM aboard ORDER BY reg_date DESC)a) "
+ "WHERE rnum>=? AND rnum<=?";
//하나의 레코드의 데이터를 자바빈에 매핑(목록처리를 할 때 사용)
private RowMapper<BoardVO> rowMapper = new RowMapper<BoardVO>() {
public BoardVO mapRow(ResultSet rs, int rowNum) throws SQLException{
BoardVO board = new BoardVO();
board.setNum(rs.getInt("num"));
board.setWriter(rs.getString("writer"));
board.setTitle(rs.getString("title"));
board.setPasswd(rs.getString("passwd"));
board.setContent(rs.getString("content"));
board.setReg_date(rs.getDate("reg_date"));
return board;
}
};
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
List<BoardVO> list = jdbcTemplate.query(SELECT_LIST_SQL,new Object[] {startRow,endRow},rowMapper);
return list;
}
BoardServiceImpl
페이지처리와 목록처리를 전달
@Override
public int getBoardCount() {
return boardDAO.getBoardCount();
}
@Override
public List<BoardVO> getBoardList(int startRow, int endRow) {
return boardDAO.getBoardList(startRow, endRow);
}
kr.spring.util => PagingUtil.java (이전 프로젝트에서 가져옴)
페이지 처리를 위해서 가져옴
BoardServiceImpl에서 작성이 완료되면
BoardController 로 전달된다.
BoardController 내용추가
@RequestMapping("/list.do")
public ModelAndView process(@RequestParam(value="pageNum",defaultValue="1")int currentPage) {
int count = boardService.getBoardCount();
log.debug("<<count>> : "+count);
//페이지 처리
PagingUtil page = new PagingUtil(currentPage,count,20,10,"list.do");
//목록 호출
List<BoardVO> list = null;
if(count > 0 ) {
list = boardService.getBoardList(page.getStartRow(),page.getEndRow());
}
ModelAndView mav = new ModelAndView();
mav.setViewName("selectList"); //중간 경로가 없음.
mav.addObject("count",count);
mav.addObject("list",list);
mav.addObject("page",page.getPage());
return mav;
}
@RequestParam(value="pageNum",defaultValue="1")intcurrentPage 를 추가
이 코드 설명
- 파라미터가 있는 경우:
- 요청 URL: http://example.com/list.do?pageNum=3
- 결과: currentPage = 3
- 파라미터가 없는 경우:
- 요청 URL: http://example.com/list.do
- 결과: currentPage = 1 (기본값)
즉 currentPage 값에 pageNum 값이 들어간다.
views/selectList.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}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>게시판 목록</h2>
<div class="align-right">
<input type="button" value="글쓰기" onclick="location.href='insert.do'">
</div>
<c:if test="${count ==0}">
<div class="result-display">표시할 내용이 없습니다.</div>
</c:if>
<c:if test="${count >0}">
<table>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
</tr>
<c:forEach var="board" items="${list}">
<tr>
<td>${board.num}</td>
<td><a href="detail.do?num=${board.num}">${board.title}</a></td>
<td>${board.writer}</td>
<td>${board.reg_date}</td>
</tr>
</c:forEach>
</table>
<div class="align-center">${page}</div>
</c:if>
</div>
</body>
</html>

DEBUG: kr.spring.board.controller.BoardController - <<count>> : 1
WARN : org.springframework.web.servlet.PageNotFound - No mapping for GET /JDBC/detail.do
BoardDAOImpl 내용추가
detail 내용 추가
private static final String SELECT_DETAIL_SQL = "SELECT * FROM aboard WHERE num=?";
@Override
public BoardVO getBoard(int num) {
return jdbcTemplate.queryForObject(SELECT_DETAIL_SQL,new Object[] {num},rowMapper);
}
BoardServiceImpl 내용추가
@Override
public BoardVO getBoard(int num) {
return boardDAO.getBoard(num);
}
BoardController 내용추가
//글상세
@RequestMapping("/detail.do")
public ModelAndView detail(int num) {
log.debug("<<num>> : "+num);
BoardVO board = boardService.getBoard(num);
//뷰이름 , 속성명 , 속성값
return new ModelAndView("selectDetail","board",board);
}
}
views => selectDetail.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}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>${board.title}</h2>
<p>
글번호 : ${board.num}<br>
작성자 : ${board.writer}<br>
작성일 : ${board.reg_date}<br>
</p>
<hr width="90%" size="1" noshade="noshade">
<p>
${board.content}
</p>
<div class="align-center">
<input type="button" value="수정" onclick="location.href='update.do?num=${board.num}'">
<input type="button" value="삭제" onclick="location.href='delete.do?num=${board.num}'">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</div>
</body>
</html>

수정폼 만들기
BoardController 내용추가
//수정 폼
@GetMapping("/update.do")
public String formUpdate(int num,Model model) { //ModelAndView는 반환을 해줘야하지만 Model은 반환을 할 필요가없고 전달만 하면 된다.
model.addAttribute("boardVO",boardService.getBoard(num));
return "updateForm";
views => updateForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글수정</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page_main">
<h2>글수정</h2>
<form:form action="update.do" modelAttribute="boardVO">
<form:hidden path="num"/>
<ul>
<li>
<form:label path="writer">작성자</form:label>
<form:input path="writer"/>
<form:errors path="writer" cssClass="error-color"/>
</li>
<li>
<form:label path="title">제목</form:label>
<form:input path="title"/>
<form:errors path="title" cssClass="error-color"/>
</li>
<li>
<form:label path="passwd">비밀번호</form:label>
<form:password path="passwd"/>
<form:errors path="passwd" cssClass="error-color"/>
</li>
<li>
<form:label path="content">내용</form:label>
<form:textarea path="content"/>
<form:errors path="content" cssClass="error-color"/>
</li>
</ul>
<div class="align-center">
<form:button>수정</form:button>
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form:form>
</div>
</body>
</html>
BoardController 의 model.addAttribute("boardVO",boardService.getBoard(num));
여기에있는 boardVO와
updateForm.jsp 의 <form:form action="update.do" modelAttribute="boardVO">
여기에 있는 boardVO가 일치해야 결과가 올바르게 나온다.
추가로 <form:hidden path="num"/> 을 쓰지않으면 num값이 전달되지않아 수정이 되질않음

수정
BoardDAOImpl 내용추가
private static final String UPDATE_SQL = "UPDATE aboard SET writer=?,title=?,content=? WHERE num=?";
@Override
public void updateBoard(BoardVO board) {
jdbcTemplate.update(UPDATE_SQL,new Object[] {board.getWriter(),board.getTitle(),board.getContent(),board.getNum()});
}
BoardServiceImpl 내용추가
@Override
public void updateBoard(BoardVO board) {
boardDAO.updateBoard(board);
}
BoardController 내용추가
@PostMapping("/update.do") //이걸 명시하지않으면 Post로 전달하지못해서 에러가난다.
//전송된 데이터 처리
public String submitUpdate(@Valid BoardVO vo, BindingResult result ) {
log.debug("<<BoardVO>> : " +vo);
//유효성 체크 결과 오류가 있으면 폼을 호출
if(result.hasErrors()) {
return "updateForm"; //formUpdate 메서드를 리턴하지 않은이유는 num값과 model값을 같이 보내야되고 그게 코드가 더 길어지기 때문에 쓰지않음
}
//DB에 저장된 비밀번호 구하기(비밀번호 일치여부 확인을 위해)
BoardVO db_board = boardService.getBoard(vo.getNum());
//비밀번호 일치 여부 체크
//비밀번호가 일치하지 않을 떄
if(!db_board.getPasswd().equals(vo.getPasswd())) {
// 필드 에러코드
result.rejectValue("passwd","invalidPassword");
return "updateForm";
}
//비밀번호가 일치할 때
//글수정
boardService.updateBoard(vo);
return "redirect:/list.do";
}



삭제
BoardDAOImpl 내용추가
private static final String DELETE_SQL = "DELETE FROM aboard WHERE num=?";
@Override
public void deleteBoard(int num) {
jdbcTemplate.update(DELETE_SQL,new Object[] {num});
}
BoardServiceImpl 내용추가
@Override
public void deleteBoard(int num) {
boardDAO.deleteBoard(num);
}
BoardController 내용추가
//삭제 폼 호출
@GetMapping("/delete.do")
public String formDelete(BoardVO vo) {
return "deleteForm";
}
view=>deleteForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/style.css" type="text/css">
</head>
<body>
<div class="page-main">
<h2>글 삭제</h2>
<form:form action="delete.do" modelAttribute="boardVO">
<form:hidden path="num"/>
<ul>
<li>
<form:label path="passwd">비밀번호</form:label>
<form:password path="passwd"/>
<form:errors path="passwd" cssClass="error-color"/>
<li>
</ul>
<div class="align-center">
<input type="submit" value="삭제">
<input type="button" value="목록" onclick="location.href='list.do'">
</div>
</form:form>
</div>
</body>
</html>

BoardController 내용추가
//전송된 데이터 처리
@PostMapping("/delete.do")
public String submitDelete(@Valid BoardVO vo, BindingResult result) {
log.debug("<<BoardVO>> : "+ vo);
//BoardVO에는 비밀번호 말고도 title같은 것들이 @NotBlank로 쓰여져있는데 비밀번호만 쓰게하려함(이 방법을 안쓰면 VO를 따로 만들어야되는 번거로움이생김)
//비밀번호만 유효성 체크 결과 오류가 있으면 폼 호출
if(result.hasFieldErrors("passwd")) {//hasFieldErrors(): 괄호안에 값만 에러가 있는지 체크하는 함수
return "deleteForm";
}
//DB에 저장된 비밀번호 구하기
BoardVO db_board = boardService.getBoard(vo.getNum());
//비밀번호 일치 여부 체크
//비밀번호가 틀렸을 시
if(!db_board.getPasswd().equals(vo.getPasswd())) {
result.rejectValue("passwd","invalidPassword");
return "deleteForm";
}
boardService.deleteBoard(vo.getNum());
return "redirect:/list.do";
}



'쌍용교육(JAVA) > Spring' 카테고리의 다른 글
쌍용교육 -JSP수업 84일차 - ch11_SpringMybatisAnnot(1) (0) | 2024.06.21 |
---|---|
쌍용교육 -JSP수업 83일차 - ch10_SpringMybatis(1) (0) | 2024.06.21 |
쌍용교육 -JSP수업 81일차 - ch09_SpringJDBC(1) (0) | 2024.06.19 |
쌍용교육 -JSP수업 81일차 - ch08_SpringMVC(3) (0) | 2024.06.19 |
쌍용교육 -JSP수업 80일차 - ch08_SpringMVC(2) (0) | 2024.06.18 |