코딩 개발/Java

게시판 만들기 1 (게시글 리스트 보기, 로그인, 로그아웃)

호소세 2023. 6. 26. 22:58
728x90
반응형

게시판 프로젝트 맛보기 : https://pabeba.tistory.com/173

 

게시판 만들기 (프로젝트 맛보기)

먼저 애플리케이션을 만들기에 앞서 요구사항을 확인해 봅니다. 요구사항 확인 1. 비로그인 상태에서는 게시판의 리스트 정보만 제공합니다. 2. 메인 화면 상단부에는 로그인할 수 있는 폼이 제

pabeba.tistory.com

프로젝트 진행 과정을 보여드렸고 이제는 맛보기에서 말한 방법으로 직접 프로그램을 제작하면서 게시판을 만들어보려고 합니다.

 

데이터베이스나 UML 등은 미리 만들어 놓았으니 이제는 코드를 작성해보려고 합니다. 위의 글을 읽고 오시면 더 이해가 잘 되실 겁니다.

그리고 기본적인 세팅 같은 것은 앞서 작성한 글들에 있으니까 확인해 보시면 더욱 이해가 잘 되실 겁니다.

 

1. 게시판 리스트 정보 확인

회원과 비회원 모두 리스트 정보를 볼 수 있습니다. 또한 게시판의 첫 모습이 게시글들의 리스트이기 때문에 이 기능부터 제작해 보겠습니다.

테이블은 이렇게 제작하였으니

구현의 순서

1. sql 작성을 통해 데이터 CRUD 테스트

2. 테스트 케이스를 작성하여 DAO 메서드 및 함수 실행 진행

3. Controller를 생성하여 request 응답

-> View와 Controller 생성

 

1. SQL 제작

먼저 리스트를 불러올 sql 문을 제작해 볼까요?

SELECT b.no, b.title, m.name, to_char(time_posted,'YYYY.MM.DD') AS time_posted , b.hits
FROM  board b
INNER JOIN community_member m ON b.id=m.id 
ORDER BY b.no DESC

JOIN 문을 이용하여 역순으로 게시글들을 불러오는 문장입니다.

 

2. Test Case 제작

public class TestUnitFindPostList {
	public static void main(String[] args) {
		try {
			ArrayList<PostVO> list = BoardDAO.getInstance().findPostList();
			for(PostVO pvo:list)
				System.out.println(pvo);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
public ArrayList<PostVO> findPostList() throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		ArrayList<PostVO> list=new ArrayList<>();
		try {
			con=dataSource.getConnection();// dbcp 로부터 컨넥션을 빌려온다 
			StringBuilder sql=new StringBuilder();
			sql.append("SELECT b.no, b.title, m.name, to_char(time_posted,'YYYY.MM.DD') AS time_posted , b.hits ");
			sql.append("FROM  board b ");
			sql.append("INNER JOIN community_member m ON b.id=m.id ");
			sql.append("ORDER BY b.no DESC ");
			pstmt=con.prepareStatement(sql.toString());
			rs=pstmt.executeQuery();
			while(rs.next()) {
				PostVO pvo=new PostVO();
				pvo.setNo(rs.getLong("no"));
				pvo.setTitle(rs.getString("title"));
				MemberVO mvo=new MemberVO();
				mvo.setName(rs.getString("name"));
				pvo.setMemberVO(mvo);
				pvo.setTimePosted(rs.getString("time_posted"));
				pvo.setHits(rs.getLong("hits"));
				list.add(pvo);
			}
		}finally {
			closeAll(rs, pstmt, con);//컨넥션을 database connection pool에 반납한다 
		}
		return list;
	}

1. ArrayList를 받아오는 findPostList 메서드를 제작합니다.

2. 위에서 작성한 sql 문을 이용하여 preparedStatement를 만들고 실행합니다.

3. ArrayList에 PostVO를 담아서 보내줍니다.

4. 받은 List의 값이 잘 나오는지 확인하면 테스트는 끝이 납니다.

 

위의 내용이 잘 나오게 된다면 그 이후에는 Controller를 만들면서 http 통신을 직접 해봅니다.

 

3. Controller 제작

public class FindPostListController implements Controller {

	@Override
	public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute("list", BoardDAO.getInstance().findPostList());
		request.setAttribute("url", "board/list.jsp");
		return "layout.jsp";
	}
}

리스트를 보여주는 컨트롤러에 대한 설명을 하겠습니다.

Layout 관련 글 : https://pabeba.tistory.com/174

1. 요청에 list를 담아서 보내줍니다.

2. 요청에 url을 담아서 보내줍니다.

3. layout.jsp로 이동을 하게 해서 board/list.jsp 파일을 실행하게 해 줍니다.

 

아래는 url에 담은 jsp파일입니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>    
		<table class="table table-boarderd table-hover boardlist">
			<thead>
				<tr style="background-color: #ccffee">
					<th>번호</th>
					<th class="title">제목</th>
					<th>작성자</th>
					<th>작성일</th>
					<th>조회</th>
				</tr>
			</thead>
			<tbody>
			<c:forEach items="${list}" var="post">
				<tr>
					<td>${post.no}</td>
					<td>
					<c:choose>
						<c:when test="${sessionScope.mvo==null}">
						${post.title}
						</c:when>
						<c:otherwise>
						<a href="FindPostByNo.do?no=${post.no}">${post.title}</a>
						</c:otherwise>
					</c:choose>					
					</td>
					<td>${post.memberVO.name}</td>
					<td>${post.timePosted}</td>
					<td>${post.hits}</td>
				</tr>
			</c:forEach>	
			</tbody>
		</table>

잘 작성해 보면 이런 식으로 리스트가 나오게 됩니다.

 

다음은 글을 보기 위해서 로그인을 해야 하는데, header에 로그인을 만들면서 로그인을 할 수 있게 만들어 봅니다.

 

2. 로그인

1. SQL 제작

SELECT name FROM community_member WHERE id=? AND password=?

아이디 비밀번호 둘 다 맞아야 값을 가져올 수 있습니다.

 

2. Test Case 제작

public class TestMemberLogin {
	public static void main(String[] args) {
		try {
			String id="java";
			String password="a2";
			MemberVO mvo=MemberDAO.getInstance().login(id,password);
			if(mvo==null)
				System.out.println("로그인 실패");
			else
				System.out.println("로그인 성공:"+mvo);
		}catch (Exception e) {
			e.printStackTrace();
		}		
	}
}
public MemberVO login(String id, String password) throws SQLException {
	Connection con=null;
	PreparedStatement pstmt=null;
	ResultSet rs=null;
	MemberVO mvo=null;
	try {
		con=dataSource.getConnection();
		String sql="SELECT name FROM community_member WHERE id=? AND password=?";
		pstmt=con.prepareStatement(sql);
		pstmt.setString(1, id);
		pstmt.setString(2, password);
		rs=pstmt.executeQuery();
		if(rs.next())
			mvo=new MemberVO(id, password, rs.getString(1));
	}finally {
		closeAll(rs, pstmt, con);
	}
	return mvo;
}

1. MemberDAO에 로그인 메서드를 제작합니다.

2. 테스트해 보고 Controller를 제작합니다.

 

3. Controller 제작

public class LoginController implements Controller {

	@Override
	public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//System.out.println(request.getMethod());
		if(request.getMethod().equals("POST")==false)
			throw new ServletException("POST METHOD 방식만 로그인 가능합니다");
		String id=request.getParameter("id");
		String password=request.getParameter("password");
		MemberVO mvo=MemberDAO.getInstance().login(id, password);
		if(mvo==null) {
			return "redirect:member/login-fail.jsp";
		}else {
			HttpSession session=request.getSession();
			session.setAttribute("mvo", mvo);
			//조회수 증가 방지를 위해 조회한 커뮤니티 게시글번호를 저장할 리스트를 세션에 저장한다
			session.setAttribute("communityBoardNoList", new ArrayList<Long>());
			return "redirect:FindPostList.do";
		}
	}

}

1. Post 요청이 아니면 에러를 발생시킵니다.

2. id, password 값을 받아와 로그인 메서드를 실행합니다.

3. mvo의 값이 없으면 로그인 실패 jsp 파일로 이동하고, 아니면 session에 mvo를 잘 담아서 게시물 리스트 페이지로 이동합니다.

4. 로그인이 잘 되면 header에 홈 글쓰기 사용자의 이름이 나타나게 됩니다.

 

header.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>    
<c:choose>
	<c:when test="${sessionScope.mvo==null}">
	<form action="${pageContext.request.contextPath}/Login.do" method="post">
	<input type="text" name="id" placeholder="아이디" required="required" size="12">
	<input type="password" name="password" placeholder="패스워드" required="required" size="12">
	<button type="submit">로그인</button>
	</form>
	</c:when>
	<c:otherwise>
	<a href="${pageContext.request.contextPath}/FindPostList.do">홈</a>&nbsp;&nbsp;
	<!-- <a href="WritePostFormController.do">글쓰기</a> -->
	<a href="${pageContext.request.contextPath}/WritePostForm.do">글쓰기</a>
	&nbsp;&nbsp;${sessionScope.mvo.name}님 &nbsp;&nbsp;
	<a href="javascript:logout()">로그아웃</a>
	<form method="post" action="${pageContext.request.contextPath}/Logout.do" id="logoutForm"></form>
	<script>
		function logout() {
			if(confirm("로그아웃 하시겠습니까?")){
				document.getElementById("logoutForm").submit();
			}
		}
	</script>
	</c:otherwise>
</c:choose>

세션이 있으면 로그인 폼이 나타나고 세션이 없으면 홈, 글쓰기, 로그아웃 버튼이 생성됩니다.

또한 세션이 생기기 때문에 리스트를 클릭하면 상세페이지로 갈 수 있게 되었습니다. (물론 아직 상세페이지는 만들지 않았지만요.)

 

3. 로그아웃

로그아웃 기능은 따로 데이터베이스에 접근하지 않기 때문에 controller만 제작하면 됩니다.

public class LogoutController implements Controller{
	@Override
	public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if(request.getMethod().equals("POST")==false)
			throw new ServletException("로그아웃 서비스는 POST방식만 가능합니다");
		HttpSession session=request.getSession(false);
		if(session!=null)
			session.invalidate();
		return "redirect:FindPostList.do";
	}
}

1. 로그아웃기능은 세션을 찾아서 세션이 있으면 invalidate 메서드를 이용해서 세션을 없애면 됩니다.

2. 없앤 후에는 다시 게시물 리스트페이지로 이동시킵니다.

 

다음 시간에는 리스트페이지에서 글을 누르면 상세페이지를 볼 수 있게 상세페이지 관련 내용 작성도 해보고 게시물 수정, 삭제도 알아보겠습니다.

 

소감

최근에 프로젝트를 하느라 조금은 바빠서 블로그를 자주 작성하지 못하고 있습니다. 더 좋은 자료를 올려드리고 싶은데 제가 하는 프로젝트는 아직 아기 프로젝트라 지금까지 배운 것을 써먹는 것이라 무엇을 올릴지 고민하다가 지금 프로젝트의 발판인 게시판 만들기를 업로드하게 되었습니다. 잘 봐주시길 바랍니다.

그리고 최근에 말과 관련해서 좋은 글이 있어서 남기고 갑니다.

타인의 나쁜 점을 말한다는 것은 언제나 자기 자신에게 손해를 가지고 온다는 사실을 기억하라.

명심하고 또 명심해야겠습니다. 이렇게 행동하면 적을 만들지 않을 수 있고, 괜한 에너지를 빼앗기지 않아서 좋다고 생각합니다.

저 말을 거꾸로 생각하면 '타인의 좋은 점을 말하고 다니면 언젠가는 자기 자신에게 이익을 가지고 온다'가 될 것입니다.

존중받고 존경받고 싶으면 타인을 존경하고 존중하는 자세를 가져야겠습니다.

반응형