티스토리 뷰

728x90
이번에는 로그인과 로그아웃을 만들어보자

로그인을 하는 양식을 보여주는 페이지가 있어야 되고..

내용을 입력 후에 버튼을 누르면 입력된 내용이 맞는지 체크해주는 페이지로 넘겨주도록 만들꺼다

[login.jsp]

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>

<!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=EUC-KR">

<title>로그인</title>

<script language="JavaScript">

function login() {

document.frm.submit();

}

function cancel() {

document.frm.reset();

}


function backToList() {

location.href="/MVC_BBS/list.do?pageNumber=${pageNumber}";

}

</script>

</head>

<body>

<form action="/MVC_BBS/login_confirm.do" method="post" name="frm">

ID : <input type="text" name="id" /><br /><br />

PW : <input type="password" name="password" /><br /><br />

<input type="button" value="로그인" onClick="login()" />

<input type="button" value="취소" onClick="cancel()" />

<input type="button" value="리스트 보기" onClick="backToList()" />

<input type="hidden" value="${articleNumber}" name="articleNumber" />

<input type="hidden" value="${pageNumber}" name="pageNumber" />

<input type="hidden" value="${state}" name="state" />

</form>

</body>

</html>



일단 FORM에 로그인, 취소, 리스트 3개의 메뉴가 있고 각각 자바스크립트를 이용해서 해당 페이지로 이동된다

pageNumber와 articleNumber는 항상 가지고 다니며, 추가로 state 값이 있는데 이건 어느페이지에서 로그인으로 왔는지 체크할 목적으로 만들어 놓은 것이다
리스트에서 로그인을 한 것인지, 글을 쓰려고 하다가 로그인으로 넘어온 것인지, 댓글을 쓰다가 넘어온 것인지 state값을 받아놨다가 로그인 후에 원래 있었던 페이지로 돌려주기 위해서이다

디자인을 했으니 이제 LoginImpl.java를 만든다

package MVC;


import javax.servlet.http.*;


public class LoginImpl implements BbsInterface {


@Override

public String handling(HttpServletRequest request, HttpServletResponse response) {

String articleNumber = request.getParameter("articleNumber");

request.setAttribute("articleNumber", articleNumber);

String pageNumber = request.getParameter("pageNumber");

request.setAttribute("pageNumber", pageNumber);

String state = (String)request.getAttribute("state");

if(state == null) {

state = (String)request.getParameter("state");

}

request.setAttribute("state", state);

System.out.println("login state : " + state);

return "login.jsp";

}


}


디자인을 먼저 만드는 것이 눈에 잘 들어와서 먼저 만든 후에 클래스를 만들고 있지만 항상 이동 순서는 클래스 -> JSP 이다
LoginImpl은 특별히 하는 일은 없다
pageNumber, articleNumber, state를 받아서 login.jsp로 넘겨주기만 한다

String state = (String)request.getAttribute("state");

if(state == null) {

state = (String)request.getParameter("state");

}

이 부분은 jsp 페이지에서 값이 넘어올때는 getParameter로 받아야 하지만 클래스에서 넘어올때는 getAttribute로 해줘야 하기에 두가지 경우는 다 써놓은 것이다(내가 잘못알고 있을수도 있지만 어쨌든 값을 제대로 못읽어오는 경우가 있다)

그럼 이제 로그인 페이지에서 "로그인" 버튼을 눌렀을때 이동할 LoginConfirmImpl.java 를 만들어 준다

[LoginConfirmImpl.java]

package MVC;


import javax.servlet.http.*;


public class LoginConfirmImpl implements BbsInterface {


@Override

public String handling(HttpServletRequest request, HttpServletResponse response) {

String id = request.getParameter("id");

String password = request.getParameter("password");

String articleNumber = request.getParameter("articleNumber");

String pageNumber = request.getParameter("pageNumber");

String state = request.getParameter("state");

request.setAttribute("articleNumber", articleNumber);

request.setAttribute("pageNumber", pageNumber);

request.setAttribute("state", state);

System.out.println("confirm state : " + state);

MvcProcessor mvcProcessor = MvcProcessor.getInstance();

int check = mvcProcessor.checkLogin(id, password);

request.setAttribute("check", check);


    // MvcProcessor의 checkLogin으로 부터 1 또는 2 를 리턴받으면 비밀번호가 틀렸거나 존재하지 않는 회원

if(check == 1 || check == 2) { 

return "login.rfid";

} else {

HttpSession session = request.getSession();

session.setAttribute("id", id);

return state;

}

}


}



LoginConfirmImpl 에서는 login.jsp에서 입력한 아이디와 비밀번호를
MvcProcessor의 checkLogin()을 이용해서 DB 데이터를 확인한다

회원이고 비밀번호가 맞다면 0, 비밀번호가 틀리면 1, 존재하지 않는 회원이면 2를 반환한다
1, 2가 반환되면 다시 login.do로 이동시킨다

회원이고 비밀번호가 맞다면 login으로 오기전에 있었던 페이지(state)로 이동시킨다


여기까지 하면 로그인이 완성되었다

이제 로그아웃..
[LogoutImpl.java]

package MVC;


import javax.servlet.http.*;


public class LogoutImpl implements BbsInterface {


@Override

public String handling(HttpServletRequest request, HttpServletResponse response) {

request.setAttribute("pageNumber", request.getParameter("pageNumber"));

HttpSession session = request.getSession();

session.invalidate();

return "list.do";

}


}



로그아웃을 한 다음에 바로 리스트 페이지로 넘겨줄꺼라서 JSP는 필요없다..
 
이제 글쓰기를 만들꺼다

글쓰기 버튼을 누르면 WriteFormImpl.java 를 거쳐서 로그인이 되어 있는지 확인한 후 내용을 입력할 수 있도록
write_form.jsp 페이지로 이동시킨다

[WriteFormImpl.java] 

package MVC;


import javax.servlet.http.*;


public class WriteFormImpl implements BbsInterface {


@Override

public String handling(HttpServletRequest request, HttpServletResponse response) {

String pageNumber = request.getParameter("pageNumber");

request.setAttribute("pageNumber", pageNumber);

String state = "write_form.do";

request.setAttribute("state", state);

HttpSession session = request.getSession();

if(session.getAttribute("id") == null) {

return "login.do";

}

request.setAttribute("id", session.getAttribute("id"));

return "write_form.jsp";

}


}


[write_form.jsp]

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>


<!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=EUC-KR">

<title>글 쓰기</title>

<script language="JavaScript">

function doWrite() {

document.frm.submit();

}

function doWriteCancel() {

document.frm.reset();

}

function backToList() {

location.href="/MVC_BBS/list.do?pageNumber=${pageNumber}";

}

</script>

</head>

<body>

<form name="frm" method="post" enctype="multipart/form-data" action="/MVC_BBS/write.do">

<table border="1" width="300">

<tr>

<td>글쓴이</td>

<td>${id}</td>

</tr>

<tr>

<td>제목</td>

<td><input type="text" name="title"></td>

</tr>

<tr>

<td colspan="2" align="center">본문</td>

</tr>

<tr>

<td colspan="2"><pre><textarea name="content" cols="50" rows="10"></textarea></pre></td>

</tr>

<tr>

<td width="100">비밀번호</td>

<td><input type="password" name="password"></td>

</tr>

<tr>

<td width="100">파일첨부</td>

<td><input type="file" name="fileName"></td>

</tr>

<tr>

<td colspan="2" align="center" height="30">

<input type="button" value="글쓰기" onClick="doWrite()" />

<input type="button" value="글쓰기 취소" onClick="doWriteCancel()" />

<input type="button" value="리스트 보기" onClick="backToList()" />

</td>

</tr>

</table>

</form>

</body>

</html>


모양은 이렇다



이제 글쓰기..
[WriteImpl.java]

package MVC;


import java.io.IOException;


import javax.servlet.http.*;


import com.oreilly.servlet.MultipartRequest;

import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;


public class WriteImpl implements BbsInterface {


@Override

public String handling(HttpServletRequest request, HttpServletResponse response) {

String realFolder = "D:/Java/WorkSpace/MVC_BBS/WebContent/UpLoad"; // 웹 어플리케이션의 절대 경로

// 파일이 업로드되는 폴더를 지정한다

String encType = "euc-kr"; // 인코딩 타입

int maxSize = 20 * 1024 * 1024; // 최대 파일 크기 20MB

BoardBean boardBean = new BoardBean();


try {

MultipartRequest multi = null;

// 전송을 담당할 콤포넌트를 생성하고 파일을 전송한다.

// 전송할 파일명을 가지고 있는 객체, 서버상의 절대경로, 최대 업로드 파일 크기, 인코딩 타입

multi = new MultipartRequest(request, realFolder, maxSize, encType, new DefaultFileRenamePolicy());


boardBean.setId((String)request.getSession().getAttribute("id"));

System.out.println(boardBean.getId());

boardBean.setTitle(multi.getParameter("title"));

System.out.println(boardBean.getTitle());

boardBean.setContent(multi.getParameter("content"));

System.out.println(boardBean.getContent());

boardBean.setPassword(multi.getParameter("password"));

System.out.println(boardBean.getPassword());

boardBean.setFileName(multi.getOriginalFileName("fileName"));

System.out.println(boardBean.getFileName());

} catch(IOException ioe) {

System.out.println(ioe);

} catch(Exception ex) {

System.out.println(ex);

}


MvcProcessor mvcProcessor = MvcProcessor.getInstance();

mvcProcessor.setArticle(boardBean);


return "list.do";

}

}


이렇게 만들어 주면 결과는 아래와 같다


글 읽기, 삭제, 수정도 이런식으로 만들어 주면 된다
패턴이 똑같으니까 여기까지만 이해해도 구현하는데는 전혀 문제가 없다
(파일 다운로드에서 한글과 띄워쓰기 문제는 약간 손을 좀 봐줘야 되겠지만 ㅎㅎ)

그런데 댓글의 경우는 약간 처리해줘야 될 부분이 있다
depth와 같은 변수를 줘서 자신의 위치가 어디인지 체크해줘야 된다
메인 글에 댓글을 달았다면 depth는 1, 그 댓글에 댓글을 달았으면 2
이런식으로 값을 확인하고 수정을 해줘야 된다

그리고 댓글을 달면 먼저 달려있던 댓글들을 한칸씩 밑으로 내려줘야 하는 부분도 신경써줘야 된다

MvcProcessor에서 이런 작업들을 해주는데 소스는 아래 부분이다

setReplyNumberChange()

public void setReplyNumberChange(int articleStartNumber, int articleEndNumber) {

String query1 = "SELECT * FROM article_model2 WHERE article_number BETWEEN ? AND ? ORDER BY article_number ASC";

String query2 = "UPDATE article_model2 SET article_number=? WHERE article_number=?";

try {

connection = this.getConnection();

pstmt = connection.prepareStatement(query1);

pstmt.setInt(1, articleStartNumber);

pstmt.setInt(2, articleEndNumber);

rs = pstmt.executeQuery();

pstmt = connection.prepareStatement(query2);


while(rs.next()) {

pstmt.setInt(1, rs.getInt("article_number")-1);

pstmt.setInt(2, rs.getInt("article_number"));

pstmt.executeUpdate();

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} finally {

if(rs != null) {

try {

rs.close();

} catch(Exception e) {}

}

if(pstmt != null) {

try {

pstmt.close();

} catch(Exception e) {}

}

if(connection != null) {

try {

connection.close();

} catch(Exception e) {}

}

}

}


먼저 달려있던 댓글들의 번호를 1씩 빼주는 기능을 한다

현재 글이 2000번이면 1001번부터 1999번까지 댓글을 가지고 작업을 해야 하므로
articleStartNumber는 1001, articleEndNumber는 1999가 된다
(약간만 생각해보면 금방 알아낼 수 있으므로 설명은 생략)

다음 setReply()

public void setReply(BoardBean boardBean) {

String query = "INSERT INTO article_model2 values (?, ?, ?, ?, ?, 0, ?, SYSDATE, ?)";

try {

connection = this.getConnection();


pstmt = connection.prepareStatement(query);

pstmt.setInt(1, boardBean.getArticleNumber());

pstmt.setString(2, boardBean.getId());

pstmt.setString(3, boardBean.getTitle());

pstmt.setString(4, boardBean.getContent());

pstmt.setString(5, boardBean.getPassword());

pstmt.setInt(6, boardBean.getDepth()+1);

pstmt.executeUpdate();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} finally {

if(rs != null) {

try {

rs.close();

} catch(Exception e) {}

}

if(pstmt != null) {

try {

pstmt.close();

} catch(Exception e) {}

}

if(connection != null) {

try {

connection.close();

} catch(Exception e) {}

}

}

}



먼저 달려있던 댓글들을 다 밀어냈으니까 그 자리에 자기를 넣어주기만 하면 된다

원래는 읽기, 수정, 삭제, 파일 다운로드까지 자세하게 쓸려고 했는데 시간이 부족해서 쓰기 까지만 정리해놔야겠다 OTL

'프로그래밍 > JSP' 카테고리의 다른 글

[JSP] EL 함수  (0) 2011.07.29
[JSP] EL(Expression Language)  (0) 2011.07.29
[JSP] JSTL 명령어 2  (0) 2011.07.29
[JSP] JSTL 명령어 1  (0) 2011.07.29
[JSP] MVC 게시판 만들기 1  (6) 2011.07.22