[부스트코스 웹] 프로젝트 B. 방명록 만들기

June·2021년 1월 6일
0

부스트코스

목록 보기
15/23

방명록 만들기 자료 링크

아직 JSP와 서블릿에 익숙하지 않고, 구조를 잘 몰라서 해맸다. 시작부터 /webapp/WEB-INF/guestbook/guestbooks.jsp를 실행하려했는데 404에러가 났다. 다른 프로젝트들을 살펴보니 webapp이 아니아닌 WebContent여서 엉뚱한 곳에 문제가 있는건 아닐지 고민하기도 했다.

전체적인 흐름은 제일 처음 사용자가 localhost:8080/guestbooks를 입력하면 (만약 기존에 연습하던 프로젝트에 부르면 localhost:8080/guestbook/guestbooks 에서 실행될 것이다) GuestbookListServlet이 실행된다. 거기서 jsp파일을 부르는 방식이다.

0. guestbooks.jsp 살펴보기

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
    <head>
        <title>방명록</title>
        <style>
            .guestbook {
                padding: 5px 0px 5px 5px;
                margin-bottom: 5px;
                border-bottom: 1px solid #efefef;
                font-size: 12px;
            }
        </style>
    </head>
    <body>

        <div class="guestbooks"></div>
            <c:forEach var="guestbook" items="${list}">
                <div class="guestbook">
                    <div> <label>id : </label> ${guestbook.id}</div>
                    <div> <label>name : </label> ${guestbook.name}</div>
                    <div> <p>${guestbook.content}</p></div>
                    <div> <label>regdate : </label> ${guestbook.regdate}</div>
                </div>
            </c:forEach>
        </div>

        <br><br><br>

        <form method="post" action="guestbooks/write">
            이름 : <input type="text" name="name"><br>
            내용 :
            <textarea name="content" cols="50" rows="5"></textarea><br>
            <input type="submit" value="확인">
        </form>
    </body>
</html>

jstl을 이용해서 list에 있는 아이템을 반복문을 통해 쭉 출력하고 있음을 알 수 있다. 또한 post를 사용해서 이름과 내용을 'guestbooks/write'에 보내고 있다.

1. 테이블 생성

CREATE TABLE `guestbook` (
    `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'guestbook id',
    `content` TEXT NOT NULL COMMENT 'guestbook content',
    `regdate` DATETIME NULL DEFAULT NULL COMMENT '등록일',
    PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

주어진 sql 코드를 이용해서 테이블을 생성한다. 하지만 문제의 오류인지, 의도인지는 모르겠지만 name 컬럼이 빠져있다. 그래서 추가해줘야한다.

ALTER TABLE guestbook ADD COLUMN name varchar(20) NOT NULL;

2. '/guestbooks'(GuestbookListServlet) 완성하기

데이터베이스에서 Guestbook list를 가져오고 그것을 request에 setAttribute로 저장한다. 여기서 RequestDispatcher를 이용해서 지정한 경로에 있는 guestbooks.jsp 파일로 보낸다.

forward() 메소드 : 클라이언트에서 수행 요청을 받는 Servlet에서 다른 Servlet, JSP 또는 HTML파일등으로 수행 권한을 넘겨서 다른 자원의 수행 결과가 대신 클라이언트로 응답하는 기능 지원

package org.edwith.webbe.guestbook.servlet;

import org.edwith.webbe.guestbook.dao.GuestbookDao;
import org.edwith.webbe.guestbook.dto.Guestbook;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/guestbooks")
public class GuestbookListServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 코드를 작성하세요.
    	response.setContentType("text/html; charset = UTF-8;");
    	GuestbookDao guestBookDao = new GuestbookDao();
    	List<Guestbook> list = guestBookDao.getGuestbooks();
    	request.setAttribute("list", list);
    	
    	RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher("/WEB-INF/guestbook/guestbooks.jsp");
    	requestDispatcher.forward(request, response);
    }
}

3. DAO 작성하기

package org.edwith.webbe.guestbook.dao;

import org.edwith.webbe.guestbook.dto.Guestbook;
import org.edwith.webbe.guestbook.util.DBUtil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class GuestbookDao {
	
	private static String dburl = "jdbc:mysql://localhost:3306/connectdb?useUnicode=true&characterEncoding=utf8&useSSL=false";
	private static String dbUser = "connectuser";
	private static String dbPasswd = "connect123!@#";
	
    public List<Guestbook> getGuestbooks(){
    	try {
    		Class.forName("com.mysql.jdbc.Driver");
    	} catch (ClassNotFoundException e) {
    		e.printStackTrace();
    	}
    	
        List<Guestbook> list = new ArrayList<>();
        
        String sql = "SELECT * FROM guestbook ORDER BY regdate";
        try (Connection conn = DBUtil.getConnection(dburl, dbUser, dbPasswd);
        		PreparedStatement ps = conn.prepareStatement(sql)) {
        	try (ResultSet rs = ps.executeQuery()) {
        		while (rs.next()) {
        			Long id = rs.getLong("id");
        			String content = rs.getString("content");
        			Date date = rs.getDate("regdate");
        			String name = rs.getString("name");
        			
        			Guestbook guestBook = new Guestbook(id, name, content, date);
        			list.add(guestBook);
        		}
        	} catch (Exception e) {
        		e.printStackTrace();
        	}
        	
        } catch (Exception ex) {
        	ex.printStackTrace();
        }

        return list;
    }

    public void addGuestbook(Guestbook guestbook){
    	try {
    		Class.forName("com.mysql.jdbc.Driver");
    	} catch (ClassNotFoundException e) {
    		e.printStackTrace();
    	}
        String sql = "INSERT INTO guestbook (id, content, regdate, name) VALUES (id, ?, now(), ?)";
        
        try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbPasswd);
        		PreparedStatement ps = conn.prepareStatement(sql)) {
        	ps.setString(1,  guestbook.getContent());
        	ps.setString(2, guestbook.getName());
        	ps.executeUpdate();
        	ps.close();
        	
        } catch (Exception ex) {
        	ex.printStackTrace();
        }
    }
}

JDBC 실습과 크게 다른 내용은 없다.

3. '/guestbooks/write' 완성하기

guestbooks.jsp에서 post 방식으로 넘어온 이름과 내용을 데이터베이스에 등록해야한다.

package org.edwith.webbe.guestbook.servlet;

import org.edwith.webbe.guestbook.dao.GuestbookDao;
import org.edwith.webbe.guestbook.dto.Guestbook;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/guestbooks/write")
public class GuestbookWriteServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String content = request.getParameter("content");
        
        Guestbook guestbook = new Guestbook(name, content);
        
        GuestbookDao guestbookDao = new GuestbookDao();
        guestbookDao.addGuestbook(guestbook);
        
        response.sendRedirect("http://localhost:8080/guestbook/guestbooks");
    }

}

getParameter를 이용해서 넘어온 데이터들을 받고, dao를 이용해서 데이터베이스에 등록한다. 그리고 다시 '/guestbooks'로 redirect 한다.

기타 문제

MySQL 한글 깨짐 문제.
해결 방법

여러 블로그들이 시키는대로하고, 서비스를 껐다가 켜보고, status를 mysql에서 쳤을 때, 인코딩 문제가 없어보이지만 계속 깨진다. 다음에 시간이 나면 해결하려한다.

0개의 댓글