일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 시스코
- 설치
- gcloud.gabia
- centos7
- 서버
- interface
- packet-tracer
- eclipse
- war
- 패킷트레이서
- tomcat
- 설정
- 무농약
- cisco
- configration
- 이클립스
- server
- nppFTP
- servlet
- 게시판
- CLI
- JSP
- java
- 언어
- vmware
- 한글
- centos
- 홈가든
- board
- comand
- Today
- Total
넓고얕은지식사전
JSP & Servlet 게시판 구현하기(게시글 내용 조회) 본문
지난번에 게시글 목록 조회 기능을 구현 하였다.
https://nullgoyatten.tistory.com/25
이번엔 작성된 내용 조회를 구현해 보도록 하자
1. ArticleDao 에 게시글 조회 관련 기능 추가 추가 (특정번호에 해당하는 게시글 데이터 읽기, 조회수 증가 하기)
경로 : article.dao> ArticleDao.java
public Article selectById(Connection conn, int no) throws SQLException {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(
"select * from article where article_no = ?");
pstmt.setInt(1, no);
rs = pstmt.executeQuery();
Article article = null;
if (rs.next()) {
article = convertArticle(rs);
}
return article;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(pstmt);
}
}
public void increaseReadCount(Connection conn, int no) throws SQLException {
try (PreparedStatement pstmt =
conn.prepareStatement(
"update article set read_cnt = read_cnt + 1 "+
"where article_no = ?")) {
pstmt.setInt(1, no);
pstmt.executeUpdate();
}
}
1-1. ArticleDao의 전체 코드
package article.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import article.model.Article;
import article.model.Writer;
import jdbc.JdbcUtil;
public class ArticleDao {
public Article insert(Connection conn, Article article) throws SQLException {
PreparedStatement pstmt = null;
Statement stmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement("insert into article "
+ "(writer_id, writer_name, title, regdate, moddate, read_cnt) "
+ "values (?,?,?,?,?,0)");
pstmt.setString(1, article.getWriter().getId());
pstmt.setString(2, article.getWriter().getName());
pstmt.setString(3, article.getTitle());
pstmt.setTimestamp(4, toTimestamp(article.getRegDate()));
pstmt.setTimestamp(5, toTimestamp(article.getModifiedDate()));
int insertedCount = pstmt.executeUpdate();
if (insertedCount > 0) {
stmt = conn.createStatement();
rs = stmt.executeQuery("select last_insert_id() from article");
if (rs.next()) {
Integer newNo = rs.getInt(1);
return new Article(newNo,
article.getWriter(),
article.getTitle(),
article.getRegDate(),
article.getModifiedDate(),
0);
}
}
return null;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(stmt);
JdbcUtil.close(pstmt);
}
}
private Timestamp toTimestamp(Date date) {
return new Timestamp(date.getTime());
}
public int selectCount(Connection conn) throws SQLException {
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("select count(*) from article");
if (rs.next()) {
return rs.getInt(1);
}
return 0;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(stmt);
}
}
public List<Article> select(Connection conn, int startRow, int size) throws SQLException {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement("select * from article " +
"order by article_no desc limit ?, ?");
pstmt.setInt(1, startRow);
pstmt.setInt(2, size);
rs = pstmt.executeQuery();
List<Article> result = new ArrayList<>();
while (rs.next()) {
result.add(convertArticle(rs));
}
return result;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(pstmt);
}
}
private Article convertArticle(ResultSet rs) throws SQLException {
return new Article(rs.getInt("article_no"),
new Writer(
rs.getString("writer_id"),
rs.getString("writer_name")),
rs.getString("title"),
toDate(rs.getTimestamp("regdate")),
toDate(rs.getTimestamp("moddate")),
rs.getInt("read_cnt"));
}
private Date toDate(Timestamp timestamp) {
return new Date(timestamp.getTime());
}
public Article selectById(Connection conn, int no) throws SQLException {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(
"select * from article where article_no = ?");
pstmt.setInt(1, no);
rs = pstmt.executeQuery();
Article article = null;
if (rs.next()) {
article = convertArticle(rs);
}
return article;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(pstmt);
}
}
public void increaseReadCount(Connection conn, int no) throws SQLException {
try (PreparedStatement pstmt =
conn.prepareStatement(
"update article set read_cnt = read_cnt + 1 "+
"where article_no = ?")) {
pstmt.setInt(1, no);
pstmt.executeUpdate();
}
}
}
2. ArticleContentDao 에 게시글 조회 관련 기능 추가 추가 (특정번호에 해당하는 게시글 내용 읽기)
경로 : article.dao> ArticleContentDao.java
public ArticleContent selectById(Connection conn, int no) throws SQLException {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(
"select * from article_content where article_no = ?");
pstmt.setInt(1, no);
rs = pstmt.executeQuery();
ArticleContent content = null;
if (rs.next()) {
content = new ArticleContent(
rs.getInt("article_no"), rs.getString("content"));
}
return content;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(pstmt);
}
}
2-1. ArticleContentDao의 전체 코드
package article.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import article.model.ArticleContent;
import jdbc.JdbcUtil;
public class ArticleContentDao {
public ArticleContent insert(Connection conn, ArticleContent content)
throws SQLException {
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(
"insert into article_content " +
"(article_no, content) values (?,?)");
pstmt.setLong(1, content.getNumber());
pstmt.setString(2, content.getContent());
int insertedCount = pstmt.executeUpdate();
if (insertedCount > 0) {
return content;
} else {
return null;
}
} finally {
JdbcUtil.close(pstmt);
}
}
public ArticleContent selectById(Connection conn, int no) throws SQLException {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(
"select * from article_content where article_no = ?");
pstmt.setInt(1, no);
rs = pstmt.executeQuery();
ArticleContent content = null;
if (rs.next()) {
content = new ArticleContent(
rs.getInt("article_no"), rs.getString("content"));
}
return content;
} finally {
JdbcUtil.close(rs);
JdbcUtil.close(pstmt);
}
}
}
3. ArticleData 작성(ReadArticleService 클래스에 구현할 getArticle()메서드의 리턴 타입으로 Article객체와 ArticleContent객체를 한 객체에 담기 위한 용도)
경로 : article.service > ArticleData.java
package article.service;
import article.model.Article;
import article.model.ArticleContent;
public class ArticleData {
private Article article;
private ArticleContent content;
public ArticleData(Article article, ArticleContent content) {
this.article = article;
this.content = content;
}
public Article getArticle() {
return article;
}
public String getContent() {
return content.getContent();
}
}
4. ArticleNotFoundException 작성(article테이블에 데이터가 존재하지 않을때 발생)
경로 : article.service > ArticleNotFoundException.java
package article.service;
public class ArticleNotFoundException extends RuntimeException {
}
5. ArticleContentNotFoundException 작성(article테이블에 데이터가 존재하지 않을때 발생)
경로 : article.service > ArticleContentNotFoundException.java
package article.service;
public class ArticleContentNotFoundException extends RuntimeException {
}
6. ReadArticleService 작성(게시글 읽기 기능 제공)
경로 : article.service > ReadArticleService.java
package article.service;
import java.sql.Connection;
import java.sql.SQLException;
import article.dao.ArticleContentDao;
import article.dao.ArticleDao;
import article.model.Article;
import article.model.ArticleContent;
import jdbc.connection.ConnectionProvider;
public class ReadArticleService {
private ArticleDao articleDao = new ArticleDao();
private ArticleContentDao contentDao = new ArticleContentDao();
public ArticleData getArticle(int articleNum, boolean increaseReadCount) {
try (Connection conn = ConnectionProvider.getConnection()){
Article article = articleDao.selectById(conn, articleNum);
if (article == null) {
throw new ArticleNotFoundException();
}
ArticleContent content = contentDao.selectById(conn, articleNum);
if (content == null) {
throw new ArticleContentNotFoundException();
}
if (increaseReadCount) {
articleDao.increaseReadCount(conn, articleNum);
}
return new ArticleData(article, content);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
7. ReadArticleHandler 작성
경로 : article.command > ReadArticleHandler.java
package article.command;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import article.service.ArticleContentNotFoundException;
import article.service.ArticleData;
import article.service.ArticleNotFoundException;
import article.service.ReadArticleService;
import mvc.command.CommandHandler;
public class ReadArticleHandler implements CommandHandler {
private ReadArticleService readService = new ReadArticleService();
@Override
public String process(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String noVal = req.getParameter("no");
int articleNum = Integer.parseInt(noVal);
try {
ArticleData articleData = readService.getArticle(articleNum, true);
req.setAttribute("articleData", articleData);
return "/WEB-INF/view/readArticle.jsp";
} catch (ArticleNotFoundException | ArticleContentNotFoundException e) {
req.getServletContext().log("no article", e);
res.sendError(HttpServletResponse.SC_NOT_FOUND);
return null;
}
}
}
8. commandHandlerURI.properties 수정. ReadArticleHandler가 /article/read.do 요청을 처리하도록 매핑 설정에 추가한다.
/join.do=member.command.JoinHandler
/login.do=auth.command.LoginHandler
/logout.do=auth.command.LogoutHandler
/changePwd.do=member.command.ChangePasswordHandler
/article/write.do=article.command.WriteArticleHandler
/article/list.do=article.command.ListArticleHandler
/article/read.do=article.command.ReadArticleHandler
9. jsp에서 내용 출력을 위한 커스텀 태그(pre.tag) 구현 (줄바꿈 등 최대한 입력내용을 그대로 보여주기 위한 조치.)
경로 : WebContent > WEB-INF > tags > pre.tag
<%@ tag body-content="empty" pageEncoding="utf-8" %>
<%@ tag trimDirectiveWhitespaces="true" %>
<%@ attribute name="value" type="java.lang.String" required="true"%>
<%
value = value.replace("&", "&");
value = value.replace("<", "<");
value = value.replace(" ", " ");
value = value.replace("\n", "\n<br>");
%>
<%= value %>
10. readArticle.jsp 구현
경로 : WebContent > WEB-INF > view > readArticle.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="u" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글 읽기</title>
</head>
<body>
<table border="1" width="100%">
<tr>
<td>번호</td>
<td>${articleData.article.number}</td>
</tr>
<tr>
<td>작성자</td>
<td>${articleData.article.writer.name}</td>
</tr>
<tr>
<td>제목</td>
<td><c:out value='${articleData.article.title}' /></td>
</tr>
<tr>
<td>내용</td>
<td><u:pre value='${articleData.content}'/></td>
</tr>
<tr>
<td colspan="2">
<c:set var="pageNo" value="${empty param.pageNo ? '1' : param.pageNo}" />
<a href="list.do?pageNo=${pageNo}">[목록]</a>
<c:if test="${authUser.id == articleData.article.writer.id}">
<a href="modify.do?no=${articleData.article.number}">[게시글수정]</a>
<a href="delete.do?no=${articleData.article.number}">[게시글삭제]</a>
</c:if>
</td>
</tr>
</table>
</body>
</html>
11. 테스트
다음 글
게시글 수정 기능 구현
https://nullgoyatten.tistory.com/27
'IT > JSP & Servlet' 카테고리의 다른 글
JSP & Servlet 게시판 구현하기(게시글 삭제) (0) | 2023.02.06 |
---|---|
JSP & Servlet 게시판 구현하기(게시글 내용 수정) (0) | 2023.02.06 |
JSP & Servlet 게시판 구현하기(게시글 목록 조회) (0) | 2023.02.06 |
JSP & Servlet 게시판 구현하기(게시글 쓰기) (0) | 2023.01.14 |
JSP & Servlet 게시판 구현하기(암호 변경) (0) | 2023.01.14 |