일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- interface
- server
- centos
- nppFTP
- packet-tracer
- 시스코
- war
- java
- 무농약
- centos7
- servlet
- cisco
- eclipse
- configration
- 언어
- 서버
- gcloud.gabia
- 게시판
- comand
- board
- tomcat
- 이클립스
- 한글
- 홈가든
- 패킷트레이서
- CLI
- 설정
- vmware
- JSP
- 설치
- Today
- Total
넓고얕은지식사전
JSP & Servlet 게시판 구현하기(게시글 쓰기) 본문
지난번에 암호변경 기능을 구현 하였다.
https://nullgoyatten.tistory.com/21
이제 본격적으로 게시글을 작성하는 기능을 구현해 보도록 하자.
1.패키지 생성 (패키지명 : article.model)
2. Writer작성(작성자의 정보(아이디 및 이름)를 담는다.)
경로 : article.model > Writer.java
package article.model;
public class Writer {
private String id;
private String name;
public Writer(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
3. Article 작성 (게시글의 정보를 담는다.)
경로 : article.model > Article.java
package article.model;
import java.util.Date;
public class Article {
private Integer number;
private Writer writer;
private String title;
private Date regDate;
private Date modifiedDate;
private int readCount;
public Article(Integer number, Writer writer, String title,
Date regDate, Date modifiedDate, int readCount) {
this.number = number;
this.writer = writer;
this.title = title;
this.regDate = regDate;
this.modifiedDate = modifiedDate;
this.readCount = readCount;
}
public Integer getNumber() {
return number;
}
public Writer getWriter() {
return writer;
}
public String getTitle() {
return title;
}
public Date getRegDate() {
return regDate;
}
public Date getModifiedDate() {
return modifiedDate;
}
public int getReadCount() {
return readCount;
}
}
4. ArticleContent 작성 (게시글의 내용을 담는다.)
경로 : article.model > ArticleContent.java
package article.model;
public class ArticleContent {
private Integer number;
private String content;
public ArticleContent(Integer number, String content) {
this.number = number;
this.content = content;
}
public Integer getNumber() {
return number;
}
public String getContent() {
return content;
}
}
5. 패키지 생성 (패키지명 : article.dao)
6. ArticleDao 작성 (article 테이블에 데이터를 삽입하는 기능 제공)
경로 : article.dao> ArticleDao.java
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.Date;
import article.model.Article;
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());
}
}
7. ArticleContentDao 작성 (article_content 테이블에 데이터를 삽입하는 기능 제공)
경로 : article.dao> ArticleContentDao.java
package article.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
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);
}
}
}
8. 패키지 생성 (패키지명 : article.service)
9. WriteRequest작성 (게시글 쓰기에 필요한 데이터 제공)
경로 : article.service > WriteRequest.java
package article.service;
import java.util.Map;
import article.model.Writer;
public class WriteRequest {
private Writer writer;
private String title;
private String content;
public WriteRequest(Writer writer, String title, String content) {
this.writer = writer;
this.title = title;
this.content = content;
}
public Writer getWriter() {
return writer;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public void validate(Map<String, Boolean> errors) {
if (title == null || title.trim().isEmpty()) {
errors.put("title", Boolean.TRUE);
}
}
}
10. WriteArticleService 작성 (게시글 쓰기 기능 제공)
경로 : article.service > WriteArticleService.java
package article.service;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import article.dao.ArticleContentDao;
import article.dao.ArticleDao;
import article.model.Article;
import article.model.ArticleContent;
import jdbc.JdbcUtil;
import jdbc.connection.ConnectionProvider;
public class WriteArticleService {
private ArticleDao articleDao = new ArticleDao();
private ArticleContentDao contentDao = new ArticleContentDao();
public Integer write(WriteRequest req) {
Connection conn = null;
try {
conn = ConnectionProvider.getConnection();
conn.setAutoCommit(false);
Article article = toArticle(req);
Article savedArticle = articleDao.insert(conn, article);
if (savedArticle == null) {
throw new RuntimeException("fail to insert article");
}
ArticleContent content = new ArticleContent(
savedArticle.getNumber(),
req.getContent());
ArticleContent savedContent = contentDao.insert(conn, content);
if (savedContent == null) {
throw new RuntimeException("fail to insert article_content");
}
conn.commit();
return savedArticle.getNumber();
} catch (SQLException e) {
JdbcUtil.rollback(conn);
throw new RuntimeException(e);
} catch (RuntimeException e) {
JdbcUtil.rollback(conn);
throw e;
} finally {
JdbcUtil.close(conn);
}
}
private Article toArticle(WriteRequest req) {
Date now = new Date();
return new Article(null, req.getWriter(), req.getTitle(), now, now, 0);
}
}
11. 패키지 생성 (패키지명 : article.command)
12. WriteArticleHandler 작성 (게시글 쓰기 기능 제공)
경로 : article.command> WriteArticleHandler.java
package article.command;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import article.model.Writer;
import article.service.WriteArticleService;
import article.service.WriteRequest;
import auth.service.User;
import mvc.command.CommandHandler;
public class WriteArticleHandler implements CommandHandler {
private static final String FORM_VIEW = "/WEB-INF/view/newArticleForm.jsp";
private WriteArticleService writeService = new WriteArticleService();
@Override
public String process(HttpServletRequest req, HttpServletResponse res) {
if (req.getMethod().equalsIgnoreCase("GET")) {
return processForm(req, res);
} else if (req.getMethod().equalsIgnoreCase("POST")) {
return processSubmit(req, res);
} else {
res.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return null;
}
}
private String processForm(HttpServletRequest req, HttpServletResponse res) {
return FORM_VIEW;
}
private String processSubmit(HttpServletRequest req, HttpServletResponse res) {
Map<String, Boolean> errors = new HashMap<>();
req.setAttribute("errors", errors);
User user = (User)req.getSession(false).getAttribute("authUser");
WriteRequest writeReq = createWriteRequest(user, req);
writeReq.validate(errors);
if (!errors.isEmpty()) {
return FORM_VIEW;
}
int newArticleNo = writeService.write(writeReq);
req.setAttribute("newArticleNo", newArticleNo);
return "/WEB-INF/view/newArticleSuccess.jsp";
}
private WriteRequest createWriteRequest(User user, HttpServletRequest req) {
return new WriteRequest(
new Writer(user.getId(), user.getName()),
req.getParameter("title"),
req.getParameter("content"));
}
}
13. commandHandlerURI.properties 수정. WriteArticleHandler가 /article/write.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
14. newArticleForm.jsp 작성
경로 : WebContent > WEB-INF > view > newArticleForm.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 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>
<form action="write.do" method="post">
<p>
제목:<br/><input type="text" name="title" value="${param.title}">
<c:if test="${errors.title}">제목을 입력하세요.</c:if>
</p>
<p>
내용:<br/>
<textarea name="content" rows="5" cols="30">${param.title}</textarea>
</p>
<input type="submit" value="새 글 등록">
</form>
</body>
</html>
15. newArticleSuccess.jsp 작성
경로 : WebContent > WEB-INF > view > newArticleSuccess.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
게시글을 등록했습니다.
<br>
${ctxPath = pageContext.request.contextPath ; ''}
<a href="${ctxPath}/article/list.do">[게시글목록보기]</a>
<a href="${ctxPath}/article/read.do?no=${newArticleNo}">[게시글내용보기]</a>
</body>
</html>
16. web.xml 수정
web.xml(경로 : WebContent > WEB-INF)에 LoginCheckFilter 설정(write.do)을 추가해줘야 한다.
<!-- LoginCheckFilter관련 설정 -->
<filter>
<filter-name>LoginCheckFilter</filter-name>
<filter-class>filter.LoginCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginCheckFilter</filter-name>
<url-pattern>/changePwd.do</url-pattern>
<url-pattern>/article/write.do</url-pattern>
</filter-mapping>
<!-- LoginCheckFilter관련 설정 -->
17. 테스트
로그인이 안되었으면 로그인으로 넘어간다.
아직 게시글 목록과 내용 보기 기능은 구현되지 않았으므로 에러가 뜰것이다.
다음글 : 게시글 목록 조회 구현
https://nullgoyatten.tistory.com/25
'IT > JSP & Servlet' 카테고리의 다른 글
JSP & Servlet 게시판 구현하기(게시글 내용 조회) (0) | 2023.02.06 |
---|---|
JSP & Servlet 게시판 구현하기(게시글 목록 조회) (0) | 2023.02.06 |
JSP & Servlet 게시판 구현하기(암호 변경) (0) | 2023.01.14 |
JSP & Servlet 게시판 구현하기(로그아웃) (0) | 2023.01.13 |
JSP & Servlet 게시판 구현하기(로그인) (0) | 2023.01.12 |