본문 바로가기
다양한 기술들/레거시 Web 실습

[01] 메뉴바와 로그인

by 예스p 2023. 1. 4.

기초설계

기본 세팅을 마쳤다면,

Web 어플리케이션의 기반을 다지자.

그리고 로그인 기능 만들기


 

<< 이번포스팅에서 구현할 요청 >>

기능 url요청 요청시 전달값   응답페이지 또는 url재요청
  /web     index.jsp
로그인요청 /login.me userId=?&userPwd=? 실패시 views/common/errorPage.jsp
성공시 /web  url재요청=> index.jsp
로그아웃요청 /logout.me     /web  url재요청=> index.jsp

 


메뉴바 만들기

어느 페이지에서건 공통적으로 보이게 되는 메뉴바를 설계한다.


STEP1) index.jsp

  • 생성위치 : src\main\webapp 
  • 기본 홈 화면이라고 보면 된다.
  • 공통적으로 사용할 menubar.jsp를 따로 만든 후 include지시어로 body태그 안에 넣는다.
<%@ include file="views/common/menubar.jsp"%>

 

 

STEP2) menubar.jsp

  • 생성위치 : src\main\webapp\views\common
  • 메뉴바에 포함될 기능 : 
    - 로그인(로그아웃, 마이페이지)
    - Home, 공지사항, 일반게시판, 사진게시판 이동버튼
  • 최상단부 (<html>태그 시작 전)
    - 스크립틀릿으로 자바 변수들을 정의해두는 자리이다.
    - String contextPath :  
    >> 자바세팅시 설정해둔 contextRoot(contextPath)를 동적으로가져와서 담아둘 객체이다. 이와같이 동적으로 가져올 시, contextPath값이 바뀌더라도 코드를 수정하지 않아도 된다.
    >> menubar에 선언해둠으로써 메뉴바를 포함하는 jsp 페이지들은 해당 변수를 자유롭게 사용 가능하다.
    - Member loginUser  : 
    >> 로그인 전 / 로그인 후 / 로그아웃 세가지 상황을 제어한다.
    >> 로그인 전 menubar.jsp 로딩시, session에 loginUser라는 키값이 없기때문에
       Member loginUser에는 null이 담긴다.
    >> 로그인 성공시, session에 로그인에 성공한 회원의 정보를 담은 Member객체를 담을것이기 때문에
       Member loginUser에도 데이터가 잘 옮겨담아진다.
    >> 로그아웃시, session에 담긴 loginUser 값을 삭제할것이기 때문에 
       menubar.jsp가 로딩되면 다시 null이 담아진다.
    **session은 jsp 내장객체로, jsp페이지 상에서 위와같이 생성과정 없이 바로 쓸 수 있다.
    반면 서블릿에서 session을 부르고자 한다면 객체를 생성해야한다.(request.getSession()) 
<%
    String contextPath = request.getContextPath();
    Member loginUser = (Member)session.getAttribute("loginUser");
%>

 

  • 헤드부 
    - 제이쿼리 및 부트스트랩을 연동시키는 <script>태그와 <link>태그를 넣는다
    >> 메뉴바를 포함하는 페이지들은 제이쿼리와 부트스트랩을 바로 쓸수있다.
    - 해당 jsp는 모든 화면에 공통으로 적용될 것이므로 다른 화면에 쓰일 스타일도 미리 저장해둘 수 있다.
    - 메뉴바 스타일 중 주목할만한 것들을 아래 코드에 기재해두었다.
.login-area>* {float:right}
// ↑ 로그인 요소들을 오른쪽으로 몰아넣는다.
.menu { //div요소들의 클래스이다.
    display:table-cell;
    // ↑ div로 위에서 아래로로 나열된 메뉴들을 가로로 정렬되게 만든다.
    width:150px;
    height:50px;
}
.menu a { 
    // ↓ a태그가 상위요소인 div영역을 꽉차게 만들기
    display:block;
    width:100%;
    height:100%;
    //↓ div영역의 height값과 동일하게 넣는다
    line-height:50px;
}

 

  • 바디부 
    - 로그인을 위한 form태그의 액션값을 /login.me, 
      로그아웃을 위한 a태그의 href값을 /logout.me로 준다. 
    - form의 action 속성이나 a태그의 href속성을 작성할때, url을 결정하는 context path는 언제든지 바뀔 수 있다. 
    때문에 request.getContextPath() 메소드를 통해 동적으로 반응하도록 자바코드 출력식을 넣는다. 
    (혹은 상단에 미리 정의해둔 변수 contextPath를 사용)
<div class="login-area">
<% if(loginUser == null) { %>
    <!-- case1. 로그인 전 -->
    <form action="<%= request.getContextPath() %>/login.me" method="post">
        <table>
            <tr>
                <th>아이디</th>
                <td><input type="text" name="userId" required></td>
            </tr>
            <tr>
                <th>비밀번호</th>
                <td><input type="password" name="userPwd" required></td> 
            </tr>
            <tr>
                <th colspan="2">
                <button type="submit">로그인</button>
                <button type="button">회원가입</button>
            </th>
            </tr>
        </table>
    </form>
<% }else{ %>
    <!-- case2. 로그인 후 -->
    <div>
        <b><%= loginUser.getUserName()%>님</b>의 방문을 환영합니다 <br><br>
        <div align="center">
            <a href="">마이페이지</a>
            <a href="<%=request.getContextPath()%>/logout.me">로그아웃</a>
        </div>
    </div>
<% } %>
</div>
<br clear="both"><br>
<!--↑.login-area를 float시켰으므로 해당 태그를 넣어준다-->
<div class="nav-area" align="center">
    <div class="menu"><a href="">HOME</a></div>
    <div class="menu"><a href="">공지사항</a></div>
    <div class="menu"><a href="">일반게시판</a></div>
    <div class="menu"><a href="">사진게시판</a></div>
</div>

 


에러페이지

각종 에러상황에 쓰일 에러페이지를 만들어둔다.


STEP1) errorPage.jsp

  • 생성위치 : src\main\webapp\views\common
  • 상단에는 메뉴바가 보이고, 하단에는 에러 메세지가 뜨는 페이지를 만들어보자
    이때 핵심 태그는 바디부에 아래와 같은 2줄의 코드 뿐이다.
<%@ include file="menubar.jsp" %>
<h1><%=request.getAttribute("errorMsg") %></h1>

 


로그인

로그인 기능을 처리해보자


STEP1) LoginController.java

  • 생성위치 : java/com/br/member/controller
    서블릿/ 매핑값 login.me
  • 로그인버튼 눌렀을 때 데이터를 처리하여 응답하는 서블릿.
  • jsp 내장 객체에 데이터 담기
    - 응답할 페이지에 전달할 값이 있을 경우 아래 4가지 객체 중 선택하여 전달한다.
    1. application :
       여기에 담긴 데이터는 해당 웹 어플리케이션 전역에서 쓸 수 있음(자바, 서블릿, jsp 등)
    2. session :
       직접 지우기 전까지 또는 세션이 만료(서버가 멈추거나 브라우저 종료)되기 전까지 모든 jsp, 서블릿에서 꺼내 쓸 수 있음.
    3. request :
       현재 이 request 객체를 포워딩한 응답 jsp에서만 꺼내 쓸 수 있음(일회성)
       매개변수로 선언되어있어서 바로 setAttribute 메소드로 사용가능
    4. page
       해당 jsp에서 담고 해당 jsp에서만 꺼내 쓸 수 있음.
  • 내장 객체에 담긴 데이터들 조작하기
    - 내장객체.setAttribute("", 밸류) : 데이터를 담는 메소드
    - 내장객체.getAttribute("") : 데이터를 꺼내오는 메소드(Object타입 반환으로 강제형변환 필요)
    - 내장객체.removeAttribute("") : 데이터를 지우는 메소드
  • 포워딩과 url재요청
    1. 포워딩 방식 (forward)
      - 파일(html, jsp등)의 위치를 매개변수로 입력한 RequestDispacher 객체를 만든 후 forward메소드를 사용해서 request와 response를 담아보낸다.
      - 입력된 jsp가 화면에 보여질 뿐 url은 변경되지 않는다.
    2. url 재요청 방식 (redirect)
      - response객체에 sendRedirect("url") 메소드를 사용해서 재요청한다.
      -원하는 페이지를 응답하는 url이 존재할 경우 사용할 수 있다.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1) 요청시 전달값 뽑기 & 데이터가공처리(파싱..) => 변수 또는 객체에 기록
    String userId = request.getParameter("userId");
    String userPwd = request.getParameter("userPwd");
    // 2) 요청처리 (db에 sql문 실행)
    //    > Service > Dao > sql문 실행
    Member loginUser = new MemberService().loginMember(userId, userPwd);
		
    // 3) 처리된 결과를 담아 사용자가 보게 될 응답뷰(jsp) 지정
    if(loginUser == null ) {
        //조회결과 없음 == 로그인 실패  => 에러페이지(views/common/errorPage.jsp) 응답
        //에러문구는 포워딩된 페이지에서만 필요하다! > request에 담아도 됨
        request.setAttribute("errorMsg", "로그인에 실패했습니다");
        RequestDispatcher view = request.getRequestDispatcher("views/common/errorPage.jsp");
        view.forward(request, response);
    }else {
        //조회결과 있음 == 로그인 성공  => 메인페이지(index.jsp) 응답
        //로그인 정보는 여기저기서 필요하다! > session에 담는다
        //서블릿에서 session에 접근하고자 한다면 세션객체 얻어와야됨
        HttpSession session = request.getSession();
        session.setAttribute("loginUser", loginUser); 
			
        //1.포워딩 방식 (forward)
        //RequestDispatcher view = request.getRequestDispatcher("index.jsp");
        //view.forward(request, response);
 						
        //2.url재요청 방식 (redirect)
        response.sendRedirect(request.getContextPath()); 
        // /web이 돌아와 절대경로방식으로 포트번호 바로 뒤에 붙음
        // == localhost:8887/web
        // 이때 넘어간 데이터는 menubar 최상단에 session을 활용하여 데이터 꺼내기
    }
}

 

 

STEP2) MemberService.java

  • 생성위치 : com/br/member/model/service
  • 로그인 요청을 처리할 loginMember(userId, userPwd) 메소드를 만든다
public Member loginMember(String userId, String userPwd) {
    Connection conn = getConnection();
    Member m = new MemberDao().loginMember(conn, userId, userPwd);
    close(conn);
    return m;
}

 

 

STEP3) member-mapper.xml

  • properties 파일로 생성하기 위한 구문을 추가한다.
  • 로그인 요청을 처리할 sql문을 entry에 저장한다.
  • entry태그의 키값은 메소드명으로 통일한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties> // properties로 활용하기 위해서 해당 구문이 있어야한다.
    <entry key="loginMember">
        SELECT 
               USER_NO
             , USER_ID
             .....
             , STATUS
          FROM MEMBER
         WHERE USER_ID =  ?
           AND USER_PWD = ?
           AND STATUS = 'Y'
    </entry>
</properties>

 

 

STEP4) MemberDao.java

  • 생성위치 : com/br/member/model/dao
  • 필드로 Properties prop을 선언하고, 기본 생성자 내부에서 Properties객체를 만든다
    (Dao 객체를 생성할때마다 자동으로 객체를 만든다)
  • 로그인 요청을 처리할 loginMember(conn, userId, userPwd) 메소드를 만든다
//멤버변수로 선언해서 어떤 메소드든 활용할 수 있게 한다.
private Properties prop = new Properties();
//기본생성자에 Properties객체를 만드는 구문을 쓴다.	
public MemberDao() {
    String filePath = MemberDao.class.getResource("/db/sql/member-mapper.xml").getPath();
    try {
        prop.loadFromXML(new FileInputStream(filePath));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
	
public Member loginMember(Connection conn, String userId, String userPwd) {
    // select문 => ResultSet객체 (한행) => Member객체
    Member m = null;
    PreparedStatement pstmt = null;
    ResultSet rset = null;
    String sql = prop.getProperty("loginMember");
    try {
        pstmt = conn.prepareStatement(sql); // 미완성된 sql문
        pstmt.setString(1, userId);
        pstmt.setString(2, userPwd);
        rset = pstmt.executeQuery(); // 한 행 | 0행
        if(rset.next()) {
            m = new Member(rset.getInt("USER_NO"),
                           rset.getString("user_id"),
                           .....);
        }
	} catch (SQLException e) {
        e.printStackTrace();
    } finally {
        close(rset);
        close(pstmt);
    }
    return m;
}

 

 


로그아웃

로그아웃 기능을 처리해보자


STEP1) LogoutController.java

  • 생성위치 : java/com/br/member/controller
    서블릿/ 매핑값 logout.me
  • 로그아웃 버튼을 눌렀을 때 요청을 처리한다.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1) 로그아웃 요청 처리 => session을 만료 시켜준다.(==세션 무효화, 세션 비우기)
    HttpSession session = request.getSession();
    //세션을 만들면 아까 사용하던 세션을 가져오게 된다.
    session.invalidate();
    //데이터 지우는 메소드

    // 2) 응답페이지 => index페이지
    response.sendRedirect(request.getContextPath());
}

 

 

 

 

 

 

 

 

 

 

 

 

'다양한 기술들 > 레거시 Web 실습' 카테고리의 다른 글

[05] 모달을 사용한 비밀번호변경  (0) 2023.01.06
[04] 회원정보변경  (0) 2023.01.06
[03] 마이페이지  (0) 2023.01.05
[02] 회원가입 기능  (0) 2023.01.05
[00] 프로젝트 세팅, JDBC 연결 준비  (0) 2023.01.04

댓글