ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 게시판 만들기 - 3. 로그인 하고 세션 유지 & 로그인 상태에 따라 게시판 보기
    JAVA/웹 프로그래밍 - JSP 2020. 11. 24. 18:38

    아래의 내용을 이어서 진행한다.

    designatedroom87.tistory.com/319

     

    게시판 만들기 - 2. 로그인 폼 만들기

    아래의 내용과 이어진다. designatedroom87.tistory.com/318?category=901206 게시판 만들기 - 1. 기본 설정 우선, 아래의 두 파일을 다운 받아서 열어보도록 하자. 아래의 내용을 기반으로 환경 구축을 할 것이

    designatedroom87.tistory.com

     

    index파일을 실행한다. index를 실행하면 FrontController 서블릿이 실행된다.

    FrontController의 어노테이션은 /index이다.
    로그인 폼에서 아이디와 비밀번호를 입력하고 로그인 버튼을 클릭하면

    로그인에 대한 처리를 하도록 한다.

    이에 대한 처리는 폼에서 입력받은 아이디와 비밀번호를 가지고

    DB에 접속해서 아이디를 이용해서 DB에 접근한다.

    그리고 비밀번호가 일치하는지 확인하는 작업을 하면 된다.

     

    WEB-INF/member의 loginForm.jsp에서 폼 입력을 마치고 로그인 버튼이 눌리면

    action=/member/login.do로 넘어간다.

    /member/login.do는 member.controller패키지의 Controller 서블릿으로 이동해서 처리를 한다.

    Controller 서블릿에서도 이에 대한 처리가 필요하다.

    loginForm.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    
    <div class="container">
      <h2>로그인</h2>
      <!-- member.controller 패키지의 Controller 서블릿으로 이동 -->
      <form name=form action=/member/login.do method=post>
        <div class="form-group">
          <label for="id">아이디:</label>
          <input type="text" class="form-control" id="id" name="id" placeholder="아이디를 입력하세요">
        </div>
        <div class="form-group">
          <label for="pwd">패스워드:</label>
          <input type="password" class="form-control" id="password" name="password" placeholder="패스워드를 입력하세요">
        </div>
        <div class="checkbox">
          <label><input type="checkbox" name="remember">아이디/패스워드 저장</label>
        </div>
        <button type="button" onclick="dataCheck()" class="btn btn-default">로그인</button>
       <button type="button" class="btn btn-default" onclick="location.href='/member/joinMember'">회원가입</button>
    </form>
    </div>
    
    <script>
    function dataCheck()
    {
    	if (document.getElementById("id").value ==""){
    		alert("id를 입력하세요.")
    		document.getElementById("id").focus();
    		return;
    	}
    	if (document.getElementById("password").value ==""){
    		alert("password를 입력하세요.")
    		document.getElementById("password").focus();
    		return;
    	}
    	document.form.submit();
    }
    </script>

     

    Controller 서블릿에서 다음과 같은 else if 처리가 필요하다.

    이 부분에서는 폼에서 입력받은 id와 비밀번호,그리고 id의 기억 기능등을 넘겨받는다.

    그리고 가장 중요한 DB에 접속해서 id에 따른 입력한 비밀번호와 DB에 기록된 비밀번호가 일치하는지

    확인을 해야 한다.

    그 부분은 MemberService 클래스에 접속해서 MemberDAO 클래스에 접근해서 알아낸다.

    이에 대한 부분은 함수 loginCheck가 한다. 두 클래스에 모두 이 함수를 정의하고 구현한다.

    Controller.java 내부 

     

    MemberService.java 내부

    MemberDAO.java 내부 

    MemberService.java 파일 전체 내용

    더보기
    package member.service;
    
    import member.dao.MemberDAO;
    import member.model.Member;
    
    public class MemberService {
    	private static MemberService service = new MemberService();
    	public MemberDAO dao = MemberDAO.getInstance();
    	
    	private MemberService() {}
    	
    	public static MemberService getInstance(){return service;}
    
    	public int insertMember(Member member) {
    		return dao.insertMember(member);
    	}
    
    	public int loginCheck(String id, String password) {
    		return dao.loginCheck(id,password);
    	}
    }

     

    MemberDAO.java 전체 내용

    더보기
    package member.dao;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import member.model.Member;
    
    public class MemberDAO {
    	private static MemberDAO dao = new MemberDAO();
    	
    	private MemberDAO() {}
    	public static MemberDAO getInstance() {
    		return dao;
    	}
    	
    	public Connection connect()
    	{
    		Connection conn = null;
    		
    		try {
    		Class.forName("oracle.jdbc.driver.OracleDriver");
    		conn=DriverManager.getConnection(
    		"jdbc:oracle:thin:@localhost:1521:xe","hr","1234");
    
    		if(conn==null) {System.out.println("DB접속에 실패");}
    		System.out.println("DB접속 성공");
    		
    		}catch(Exception e) {}
    		
    		return conn;
    	}
    	
    	public void close(Connection conn, PreparedStatement pstmt, ResultSet rs)
    	{
    		if (rs != null) 
    		{
    			try 
    			{
    				rs.close();
    			}
    			catch (SQLException e) {e.printStackTrace();}
    		}
    		this.close(conn,pstmt);
    	}
    	
    	public void close(Connection conn, PreparedStatement pstmt)
    	{
    		try {
    		pstmt.close();
    		conn.close();
    		}
    		catch (SQLException e) {e.printStackTrace();}
    	}
    	
    	//	DB에 접속해서 테이블에 해당 정보를 입력하기
    	public int insertMember(Member member) {
    		String sql = null;
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		int result = 0;
    		ResultSet rs = null;
    		
    		try 
    		{
    			conn = this.connect();
    			conn.setAutoCommit(false);	//	DB 트랜잭션의 시작
    			
    			//	아이디가 중복이 되는지 여부 확인해서 중복될 경우 0을 리턴해서 처리
    			//	select count(*) from member where id = 'test';
    			sql = "select count(*) from member where id =?";
    			pstmt=conn.prepareStatement(sql);//위의 sql문을 처리하기 위해 객체 생성
    			pstmt.setString(1, member.getId());
    			rs = pstmt.executeQuery();
    			if (rs.next())	result = rs.getInt(1);
    			
    			//	id가 중복이 되면, result에는 1이상의 값이 들어있다. 그러므로 DB에 데이터 저장 불가
    			if (result > 0)	return 0;
    			
    			//	sysdate는 컴퓨터 상의 데이터이다.
    			sql="insert into member values " + "(new_member_idx_seq.nextval," + "?,?,?,?,?,sysdate)";
    			
    			pstmt=conn.prepareStatement(sql);//위의 sql문을 처리하기 위해 객체 생성
    			
    			pstmt.setString(1, member.getId());
    			pstmt.setString(2, member.getPassword());
    			pstmt.setString(3, member.getNickname());
    			pstmt.setString(4, member.getEmail());
    			pstmt.setString(5, member.getTel());
    			
    			result = pstmt.executeUpdate();
    			conn.commit();
    			
    			if (result > 0)	{
    				System.out.println("멤버 입력 성공");
    				conn.commit();
    			}
    			else{
    				System.out.println("멤버 입력 실패");
    				conn.rollback();
    			}
    			this.close(conn, pstmt);
    		}
    		catch(Exception e) 
    		{ 
    			try {
    				conn.rollback();
    			}
    			catch (SQLException e1) {e1.printStackTrace();}
    		}
    		return result;
    	}
    	public int loginCheck(String id, String password) 
    	{
    		String sql = null;
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		int result = 0;
    		ResultSet rs = null;
    		
    		try {
    			conn = this.connect();
    			System.out.println("dao id : " +id);
    			sql = "select password from member where id=?";
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setNString(1, id);
    			rs = pstmt.executeQuery();
    			
    			if (rs.next()) {
    				if (password.equals(rs.getString("password"))) 
    					result = 1;
    				else											
    					result = 0;
    			}
    			this.close(conn, pstmt, rs);
    			return result;
    		}catch(Exception e) {}
    		return 0;
    	}
    }

     

    로그인이 되었는지 확인을 해보자.

    header에서는 로그인이 된 상태냐 아니냐에 따라 로그인 혹은 로그아웃으로 보여져야 한다.

    WEB-INF/common폴더의 header.jsp로 이동해서 이를 처리하자.

    이는 Ctag를 이용해서 구현이 가능하다.

    로그인이 된 경우라면 로그인 된 아이디를 보여준다.

    이와 같은 작업을 하는 이유는 나중에 로그인 상태에 따라 게시판을 보여주거나 보여주지 않을 것이다.

    header.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!--Ctag를 사용하기 위해 추가를 한다. -->
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <div>
    <!--nav 태그에서 메뉴를 만들면 된다.-->
        <nav class="navbar">
            <ul>
                <li><a href="/home">홈</a></li>
                <li><a href="/company">회사소개</a></li>
                <li><a href="/iot">IOT</a></li>
                <li><a href="/board">게시판</a></li>
                
                <!--로그인이 된 경우와 아닌 경우 두 경우로 나뉜다. 세션 id가 비어있으면 로그인으로 출력 -->
                <!--로그인/로그아웃을 선택함에 따라 다시  member.controller 패키지의 Controller 서블릿으로 이동 
                	해서 login 혹은 logout을 처리한다.
                -->
                <c:choose>
                <c:when test="${empty sessionScope.id }">
                <li><a href="/member/login">로그인</a></li>
                </c:when>
                <c:otherwise>
                <li><a href="/member/logout">로그아웃[${sessionScope.id}]</a></li>
                </c:otherwise>
                </c:choose>
            </ul>
        </nav>
    </div>

    위에서는 로그인 되지 않은 상태에서, 로그인을 클릭하면, 로그인 양식 폼으로 이동하고

    반대로 로그인된 상태에서 로그아웃을 클릭하면 세션을 없애서 로그아웃을 하도록 한다.

    그러기 위해서 두 가지 모든 경우에 대한 처리는 모두 member.controller 패키지의 Controller 서블릿에서 한다.

    else if 로 이 두 가지를 처리하도록 하자.

    Controller.java 내부 

     

    Controller.java

    더보기
    package member.controller;
    
    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    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 javax.servlet.http.HttpSession;
    
    import member.model.Member;
    import member.service.MemberService;
    
    //	member로 들어오는 모든 url에 대해서 해당 컨트로럴가 이에 대한 처리를 하겠다는 의미
    @WebServlet("/member/*")
    public class Controller extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
    	public void init(ServletConfig config) 
    			throws ServletException {}
    
    	protected void service(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {
    		
    		//ServletContext application = request.getServletContext();	//	전역 객체
    		
    		//	페이지 페이지 마다 연결 시간 설정 가능. 전역 객체이다.
    		HttpSession session = request.getSession();					 
    		
    		//	1. 페이지를 전송하기 전에 url을 분석하고 분류해서 실행
    		String url = request.getRequestURI();
    		//System.out.println("url : " +url);
    		String contextPath = request.getContextPath();
    		//System.out.println("contextPath : " +contextPath);
    		String path = url.substring(contextPath.length());
    		//System.out.println("path : " +path);
    		String lastPath = url.substring(url.lastIndexOf('/') + 1);	//	마지막 /를 기준으로 분리
    		System.out.println("subPath : " +lastPath);
    		String command = lastPath;
    		
    		if (command.equals("index")) {
    			/*
    			//	2. 분류된 url을 선택하고 전송하는 작업
    			RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/member/index.jsp");
    			
    			//	3. 페이지로 밀어주는 작업
    			dispatcher.forward(request, response);
    			*/
    			request.setAttribute("page", "loginForm.jsp");
    		}
    		else if (command.equals("joinMember")) {
    			request.setAttribute("page", "joinMember.jsp");
    		}
    		else if (command.equals("joinMember.do")) {
    			//	1. DB생성(memberTable.jsp)
    			//	     폼에서 전송할 데이터 처리
    			//	(1). 생성자를 통해 한 번에 담는 방법
    			//	(2). 메소드 set함수를 이용하여 데이터를 저장하는 방법
    			Member member = new Member();
    			member.setId(request.getParameter("id"));
    			member.setPassword(request.getParameter("password"));
    			member.setNickname(request.getParameter("nickname"));
    			member.setEmail(request.getParameter("email"));
    			member.setTel(request.getParameter("tel"));
    			
    			//	2. 서비스 작업, dao작업을 한다.
    			MemberService service = MemberService.getInstance();
    			int result = service.insertMember(member);
    			
    			if (result > 0) request.setAttribute("page", "success.jsp");
    			else 			request.setAttribute("page", "fail.jsp");
    			
    			//	3. data를 객체에 저장
    			//request.setAttribute("page", "joinMember.jsp");
    		}
    		//	로그인 버튼이 클릭 되는 경우
    		else if (command.equals("login.do"))
    		{
    			//	전송된 파일 저장
    			String id = request.getParameter("id");
    			String password = request.getParameter("password");
    			String remember = request.getParameter("remember");
    			System.out.printf("%s %s %s\n",id,password,remember);
    			
    			//	데이터를 모델에 넣고 전송해도 되고, 모델에 넣지 않고 전송해도 된다.
    			
    			//	로그인 체크하는 함수를 호출해서 멤버여부 확인
    			MemberService service = MemberService.getInstance();
    			int result = service.loginCheck(id,password);
    			
    			if (result == 1) {
    				System.out.println("로그인 성공");
    				
    				//	로그인 시에, 세션을 발급한다.
    				session.setAttribute("id",id);
    				
    				request.setAttribute("page", "body.jsp");
    			}
    			else{
    				System.out.println("로그인 실패");
    				session.removeAttribute("id");	//	실패면 세션 해제
    				request.setAttribute("page", "loginForm.jsp");
    			}
    		}
    		else if (command.equals("login"))
    		{
    			request.setAttribute("page", "loginForm.jsp");
    		}
    		else if (command.equals("logout"))
    		{
    			session.invalidate(); // 세션차체를 없애버림
    			request.setAttribute("page", "loginForm.jsp");
    		}
    		else{
    			//request.setAttribute("page", "body.jsp");
    			request.setAttribute("page", "loginForm.jsp");
    		}
    		//	2. 분류된 url을 선택하고 전송하는 작업
    		RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/member/index.jsp");
    				
    		//	3. 페이지로 밀어주는 작업
    		dispatcher.forward(request, response);
    	}
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    }

     

    이번에는 게시판의 틀을 아주 간단하게 만들어보자.

    이 게시판을 만든 이유는 로그인 된 상태에서만 볼 수 있도록 제어를 하기 위해서이다.

    우선 index 파일을 실행해서 로그인이 안된 상태에서 게시판을 선택하면

    로그인을 하도록 권유를 하고 반대로 로그인 된 상태에서 게시판을 선택하면 게시판을 보여준다.

    WEB-INF폴더의 하위로 board라는 폴더를 하나 만든다.

    게시판에서 header와 footer는 공통적인 내용이며, 다만 게시글을 보여주는 부분인 body만 달라진다.

    body에서 로그인 상태에 따라 게시글을 보여주거나 로그인을 권고하는 내용을 보여주도록 하자.

    아래의 세 파일들은 모두 board 폴더 내의 jsp파일이다.

    그리고 당연히 컨트롤러도 있어야 한다.

    src폴더의 하위로 board.controller패키지에 Controller 서블릿을 하나 만든다.

    게시판을 클릭하는 경우는 common/header.jsp파일에서 게시판을 클릭하면 /board 어노테이션으로

    board.controller패키지에 Controller 서블릿으로 이동하게 된다.

    그리고 나서, 로그인 상태이면 게시판을 보여주고 그렇지 않으면 로그인을 하도록 메시지를 보여준다.

    Controller.java

    더보기
    package board.controller;
    
    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    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 javax.servlet.http.HttpSession;
    
    //	member로 들어오는 모든 url에 대해서 해당 컨트로럴가 이에 대한 처리를 하겠다는 의미
    @WebServlet("/board/*")
    public class Controller extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
    	public void init(ServletConfig config) 
    			throws ServletException {}
    
    	protected void service(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {
    		
    		//ServletContext application = request.getServletContext();	//	전역 객체
    		
    		//	페이지 페이지 마다 연결 시간 설정 가능. 전역 객체이다.
    		HttpSession session = request.getSession();					 
    		
    		//	1. 페이지를 전송하기 전에 url을 분석하고 분류해서 실행
    		String url = request.getRequestURI();
    		//System.out.println("url : " +url);
    		String contextPath = request.getContextPath();
    		//System.out.println("contextPath : " +contextPath);
    		String path = url.substring(contextPath.length());
    		//System.out.println("path : " +path);
    		String lastPath = url.substring(url.lastIndexOf('/') + 1);	//	마지막 /를 기준으로 분리
    		System.out.println("subPath : " +lastPath);
    		String command = lastPath;
    		
    		if (command.equals("board")) {
    			
    			if (session.getAttribute("id") != null) {
    				request.setAttribute("page", "body.jsp");
    			}
    			else {
    				request.setAttribute("page", "fail.jsp");
    			}
    		}
    		else if (command.equals("joinMember")) {
    			request.setAttribute("page", "body.jsp");
    		}
    		else if (command.equals("joinMember.do")) {
    			
    			//	1. DB생성(memberTable.jsp)
    			//	     폼에서 전송할 데이터 처리
    			//	(1). 생성자를 통해 한 번에 담는 방법
    			//	(2). 메소드 set함수를 이용하여 데이터를 저장하는 방법
    			
    			//	2. 서비스 작업, dao작업을 한다.
    			//BoardService service = BoardService.getInstance();
    			//int result = service.insertMember(member);
    			
    			//	3. data를 객체에 저장
    			request.setAttribute("page", "body.jsp");
    		}
    		else{
    			if (session.getAttribute("id") != null) {
    				request.setAttribute("page", "body.jsp");
    			}
    			else {
    				request.setAttribute("page", "fail.jsp");
    			}
    		}
    		//	2. 분류된 url을 선택하고 전송하는 작업
    		RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/board/index.jsp");
    				
    		//	3. 페이지로 밀어주는 작업
    		dispatcher.forward(request, response);
    	}
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    }

     

    index.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="/css/style.css" rel="stylesheet">
    <script src="/js/jquery-3.5.1.min.js"></script>
    
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
     
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
      
    <title>Insert title here</title>
    </head>
    
    <body>
    	<jsp:include page="/WEB-INF/common/header.jsp"></jsp:include>
    	<jsp:include page="/WEB-INF/board/${page}"></jsp:include>
    	<jsp:include page="/WEB-INF/common/footer.jsp"></jsp:include>
    </body>
    </html>

    body.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <div>
    <table border=1>
    <tr><td>번호</td><td>제목</td><td>날짜</td><td>조회수</td></tr>
    <tr><td>1</td><td>화이팅</td><td>2020-11-20</td><td>1</td></tr>
    <tr><td>2</td><td>화이팅2</td><td>2020-11-20</td><td>2</td></tr>
    </table>
    </div>

    fail.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <div>
    권한이 없습니다. 로그인 해주세요.
    </div>

     

     

    아래의 내용을 뒤이어 구현해보자.

    designatedroom87.tistory.com/322?category=901206

     

    게시판 만들기 - 4. 게시판 글을 DB에 저장하기

    먼저 만들려고 하는 게시판은 댓글도 가능한 게시판이다. DB를 좀 다뤄야 하고 조금 복잡하다. DB의 테이블에 여러 정보가 있지만, 그 중에서 index, groupid, re_order 라는 세 가지 개념이 중요하다.

    designatedroom87.tistory.com

     

    댓글

Designed by Tistory.