어제 하던걸 이어서, write부터 구현을 시작했다.
servlet 먼저.
package com.KoreaIT.java.jsp_AM.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.KoreaIT.java.jsp_AM.util.DBUtil;
import com.KoreaIT.java.jsp_AM.util.SecSql;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/article/write")
public class ArticleWriteServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.getRequestDispatcher("/jsp/article/write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// DB 연결
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("클래스를 찾을 수 없습니다.");
e.printStackTrace();
}
String url = "jdbc:mysql://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
String user = "root";
String password = "1234";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
String title = request.getParameter("title");
String body = request.getParameter("content");
SecSql sql = SecSql.from("INSERT INTO article");
sql.append("SET regDate = NOW(),");
sql.append("updateDate = NOW(),");
sql.append("title = ?,", title);
sql.append("`body`= ?,", body);
sql.append("memberId = ?", 1); // 작성자 ID는 하드코딩 (예시용, 실제로는 세션에서 가져와야 함)
int id = DBUtil.insert(conn, sql);
response.getWriter().append(String.format(
"<script>alert('%d번 글이 작성되었습니다.'); location.replace('detail?id=%d');</script>", id, id));
} catch (SQLException e) {
System.out.println("SQL 에러: " + e.getMessage());
response.getWriter().append("<script>alert('글 작성에 실패했습니다.'); history.back();</script>");
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
다음은 JSP
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
Map<String, Object> articleRow = (Map<String, Object>) request.getAttribute("articleRow");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시물 작성</title>
</head>
<body>
<h2>게시물 작성</h2>
<!-- 게시물 작성 폼 -->
<form action="write" method="post">
<div>
<label for="title">제목:</label>
<input type="text" id="title" name="title" required>
</div>
<div>
<label for="body">내용:</label>
<textarea id="content" name="content" rows="10" cols="50" required></textarea>
</div>
<div>
<button type="submit">게시물 등록</button>
</div>
</form>
<div>
<a style="color: green" href="list">리스트로 돌아가기</a>
</div>
</body>
</html>
여기서 알아야될 것은 GET과 POST다.
둘 다 서버쪽으로 데이터를 전송하는 것이다.
GET은 서버에 요청을 할 때 히스토리를 남기게 된다. 요청하는 것 자체에 무언가를 남겨서 보내는 것이고(사진을 보면 아이디와 패스워드를 인터넷 주소창 URL 자체에 남겨서 보낸다.), POST는 HTTP 메세지의 Body에 담아서 전송한다.
요약하면 쿼리스트링이 있냐 없냐의 차이다.
GET은 쿼리스트링이 노출되니까 당연 보안에 취약할 것이고 제 3자가 다른 계정에 접근하는 일도 일어날 수가 있다. url의 id만 고치면 되니까. 때문에 보안에 차이가 난다.
다음, write의 기능을 write는 웹페이지에서 받은 데이터를 doWrite에 넘겨주는 역할로, doWrite가 글작성을 담당하게끔 강사님은 코드를 짜시길래 내 코드도 그렇게 구조를 변경했다. 구조를 변경하고 나니까 글 작성 페이지까지는 잘 넘어가는데 글 작성 자체가 갑자기 되지 않았다. 무언가 더 필요한 것 같다.
@WebServlet("/article/write")
public class ArticleWriteServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.getRequestDispatcher("/jsp/article/write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
아래 doPost가 없어서 작동이 되지 않았던 것이고 해당 메서드를 추가하니까 오류는 뜨지 않았지만 게시물 등록 자체가 완벽하게 이루어지지는 않았다.
ArticleDoWriteServlet의 글 작성 쿼리를 작성한 메서드가 doPost였던게 1차적 문제였고, 마찬가지로 doPost 메서드가 없던게 문제가 되었다.
중간에 서버가 맛이 가서 한 두시간을 고치는데 썼다. 이런 저런 방법 다 시도해보다가 도저히 안돼서 tomcat을 삭제하고 다시 까니까 된다. 한 30분 투자해보고 안되면 앞으로는 그냥 다시 까는게 정신건강에 좋을 것 같다.
아무튼 포스팅이 되지 않았던 것은 JSP에서 action을 dowrite로 수정해야됐는데 여전히 write여서 안됐던 것.
그것 까지 수정하고 이제는 게시물 수정을 위해서 다시 코드를 쓰기 시작했다. write와 거의 흡사하기 때문에 해당 클래스들들 복사해서 만들기 시작했다.
만들던 중에 뭔가 실수가 있었는지 모든 게시물이 수정이 되었다.
아 html에
<input type="hidden" value="<%=articleRow.get("id")%>" name="id" />
해당 코드가 없어서 어떤 아이디의 게시물을 수정하는지 알 수 없어서 싹 다 수정한 것 같다. 일단 해당 코드 추가하고, 쿼리문에도 id를 검증만 했지 update쪽에 id를 찾으라는 조건을 달지 않았다. 이런 문제들을 발견했으니 그 문제들까지 다 해결하고 수정을 해보면.
이제야 제대로 작동한다.
코드는 이렇다.
ArticleDoModifyServlet
package com.KoreaIT.java.jsp_AM.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.KoreaIT.java.jsp_AM.util.DBUtil;
import com.KoreaIT.java.jsp_AM.util.SecSql;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/article/domodify")
public class ArticleDoModifyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// DB 연결
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("클래스를 찾을 수 없습니다.");
e.printStackTrace();
}
String url = "jdbc:mysql://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
String user = "root";
String password = "1234";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
int id = Integer.parseInt(request.getParameter("id"));
String title = request.getParameter("title");
String body = request.getParameter("content");
SecSql sql = SecSql.from("UPDATE article");
sql.append("SET regDate = NOW(),");
sql.append("updateDate = NOW(),");
sql.append("title = ?,", title);
sql.append("`body`= ?,", body);
sql.append("memberId = ?", 1); // 작성자 ID는 하드코딩 (예시용, 실제로는 세션에서 가져와야 함)
sql.append("WHERE id = ?;", id);
DBUtil.update(conn, sql);
response.getWriter().append(String.format(
"<script>alert('%d번 글이 수정되었습니다.'); location.replace('detail?id=%d');</script>", id, id));
} catch (SQLException e) {
System.out.println("SQL 에러: " + e.getMessage());
response.getWriter().append("<script>alert('글 수정에 실패했습니다.'); history.back();</script>");
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ArticleModifyServlet
package com.KoreaIT.java.jsp_AM.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.KoreaIT.java.jsp_AM.util.DBUtil;
import com.KoreaIT.java.jsp_AM.util.SecSql;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/article/modify")
public class ArticleModifyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// DB 연결
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("클래스 x");
e.printStackTrace();
}
String url = "jdbc:mysql://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
String user = "root";
String password = "1234";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
int id = Integer.parseInt(request.getParameter("id"));
SecSql sql = SecSql.from("SELECT *");
sql.append("FROM article");
sql.append("WHERE id = ?", id);
Map<String, Object> articleRow = DBUtil.selectRow(conn, sql);
if (articleRow == null) {
}
request.setAttribute("articleRow", articleRow);
request.getRequestDispatcher("/jsp/article/modify.jsp").forward(request, response);
} catch (SQLException e) {
System.out.println("에러 1 : " + e);
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
JSP
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
Map<String, Object> articleRow = (Map<String, Object>) request.getAttribute("articleRow");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시물 작성</title>
</head>
<body>
<h2><%=articleRow.get("id")%>번 글 수정
</h2>
<!-- 게시물 수정 폼 -->
<form action="domodify" method="post">
<input type="hidden" value="<%=articleRow.get("id")%>" name="id" />
<div>
<label for="title">제목:</label> <input type="text" id="title"
name="title" required>
</div>
<div>
날짜 :
<%=articleRow.get("regDate")%>
</div>
<div>
<label for="body">내용:</label>
<textarea id="content" name="content" rows="10" cols="50" required></textarea>
</div>
<div>
<button type="submit">게시물 수정</button>
</div>
</form>
<div>
<a style="color: green" href="list">리스트로 돌아가기</a>
</div>
</body>
</html>
이렇게 썼다. write랑 유사하지만 받아서 전달하는 과정에서 select로 글에 해당하는 아이디로 경로 설정을 해주고 그 데이터를 덮어쓰는 doModify를 실행한다.
'Coding History' 카테고리의 다른 글
국비 지원 IT(웹앱개발) 취업반 강의 46일차 (JSP) (0) | 2024.08.08 |
---|---|
국비 지원 IT(웹앱개발) 취업반 강의 45일차 2 (HTML, CSS, JS) (0) | 2024.08.07 |
국비 지원 IT(웹앱개발) 취업반 강의 44일차 2 (HTML, CSS, JS) (0) | 2024.08.07 |
국비 지원 IT(웹앱개발) 취업반 강의 44일차 1 (HTML, CSS, JS) (0) | 2024.08.06 |
카카오 페이증권 모작 완료. (0) | 2024.08.04 |