본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 65일차 (2023-08-23) 자바 프로그래밍_63. _개인프로젝트 - 마트 관리 시스템 + 64. JSP를 이용하여 MVC 모델1 구조로 변경하기_Board

by prometedor 2023. 8. 23.
## 63. 쿠키와 ServletContext 보관소 활용하기

- 쿠키를 이용하여 로그인 할 때 입력한 전화번호을 보관하기
- 서블릿들이 공통으로 사용하는 객체를 ServletContext 보관소에 보관하기

 

ㄴ BoardFormServlet.java 파일 복사하기

=>

ㄴ 복사한 파일을 같은 위치에 LoginFormServlet 이라는 이름으로 붙여넣기

=>

LoginFormServlet.java

ㄴ board -> auth 로 변경해주기

=>

LoginFormServlet.java

ㄴ 게시글 -> 로그인 으로 변경해주기

=>

webapp > auth > form.html

ㄴ 해당 코드 복사하기

=>

LoginFormServlet.java

ㄴ 복사한 코드 붙여넣기

=>

LoginFormServlet.java

ㄴ out.println 형식으로 변경해주기

=>

LoginFormServlet.java

ㄴ " -> ' 로 변경해주기

=>

HeaderServlet.java

ㄴ /auth/form.html -> /auth/form 으로 변경하기

=>

ㄴ auth 폴더 자체를 삭제

=>

ㄴ LoginFormServlet 은 BoardFormServlet 과 다르게 category 가 필요 없음

=>

ㄴ App 실행

=>

ㄴ 로그인 선택

=>

ㄴ [로그인] 선택

=>

 

쿠키를 이용하여 로그인 할 때 입력한 전화번호을 보관하는 기능 추가하기

LoginFormServlet.java

ㄴ 이메일 저장 체크박스 추가

=>

=>

LoginServlet.java

ㄴ javax.servlet.http 의 Cookie 클래스 import 하기

=>

LoginServlet.java

ㄴ saveEmail 파라미터

=>

LoginServlet.java

ㄴ 넘어온 파라미터 값 중 savePhone 이 있다면 쿠키 생성하여 서블릿에서 클라이언트로 쿠키를 전송하도록 함

=>

LoginServlet.java

ㄴ 쿠키의 유효 시간을 0으로 설정하여 해당 쿠키를 바로 삭제하도록 함

=>

LoginServlet.java

ㄴ 쿠키 저장하는 코드 추가

=>

LoginFormServlet.java

ㄴ 쿠키 하나씩 꺼낼 수 없어 배열에 담아서 가져오도록 함

=>

LoginFormServlet.java

ㄴ println -> printf 로 변경

ㄴ phone 을 value 값으로 설정해주기

=>

ㄴ App 실행

=>

ㄴ 전화번호 저장 체크박스 체크하지 않고 [로그인] 선택하여 로그인하기

=>

ㄴ [로그아웃] 선택

=>

ㄴ 다시 [로그인] 선택 시 전화번호는 저장되어있지 않음을 확인

 

ㄴ 전화번호 저장 체크박스 체크한 후 [로그인] 선택하여 로그인하기

=>

ㄴ [로그아웃] 선택하여 로그아웃 하기

=>

ㄴ [로그인] 선택

=>

ㄴ 로그인 할 때 입력했던 전화번호가 저장되어 있음을 확인

 

 

서블릿들이 공통으로 사용하는 객체를 ServletContext 보관소에 보관하기

ㄴ listener 패키지에 ContextLoaderListener 라는 이름의 새로운 클래스 파일 생성

=>

InitServlet.java

ㄴ 해당 코드 복사하기

=>

ContextLoaderListener.java

=>

ContextLoaderListener.java

ㄴ contextInitialized 메서드 내부에서 ServletContext 객체를 얻고 이 객체를 통해 웹 애플리케이션의 설정 정보나 공유 데이터에 접근할 수 있음

=>

ContextLoaderListener.java

ㄴ 위쪽에서 복사한 코드 붙여넣기

=>

ContextLoaderListener.java

ㄴ InitServlet 대신 해당 객체들을 ContextLoaderListener 에서 생성해주도록 함

=>

ContextLoaderListener.java

=>

ContextLoaderListener.java

ㄴ mybatis-config.xml 의 경로 복사

=>

ContextLoaderListener.java

ㄴ <context-param> 태그의 <param-name> 에 mybatis-config 추가하기

ㄴ <context-param> 태그의 <param-value> 에 복사한 경로 붙여넣기

    => 웹 애플리케이션의 web.xml 파일에 <context-param> 요소를 추가하여 웹 애플리케이션의 초기 설정 정보를 정의하는 역할을 함

=>

ContextLoaderListener.java

ㄴ mybatis-config.xml 설정 파일을 읽어오도록 함

    ㄴ SqlSessionFactoryBuilder의 build 메서드를 호출하여 SqlSessionFactory 인스턴스를 생성함

    ㄴ 생성된 SqlSessionFactory 인스턴스를 SqlSessionFactoryProxy로 감싸서 반환함

=>

ContextLoaderListener.java

ㄴ 리스너 클래스를 서블릿 컨테이너에 등록하기

     => 해당 리스너가 이벤트를 처리하게 되며, 따로 web.xml 파일에 리스너를 등록할 필요가 없어짐

=>

ContextLoaderListener.java

ㄴ 공통 객체 준비가 완료되면 해당 문구 출력하도록 코드 추가

 

LoginServlet.java

ㄴ 서블릿 컨텍스트에서 "memberDao"라는 이름으로 저장된 속성(Attribute) 값을 가져오는 부분

ㄴ getServletContext() 메서드는 서블릿에서 제공하는 메서드로, 서블릿 컨텍스트 객체를 반환함

ㄴ 서블릿 컨텍스트는 웹 애플리케이션 전체에서 공유되는 데이터 저장소이며, 서블릿 간 데이터 공유에 사용됨

=>

ㄴ App 실행 시 공통 객체 준비 완료됨을 확인

=>

=>

ㄴ 로그인을 정상적으로 실행함을 확인

=>

ㄴ InitServlet.java 파일 삭제

=>

ㄴ InitServlet.java 삭제하자마자 수정한 코드를 제외하고 모두 에러 발생

=>

BoardAddServlet.java

=>

BoardAddServlet.java

ㄴ 현재 필요한 객체들 모두 생성해주기

=>

BoardAddServlet.java

ㄴ InitServlet 제거해주기

=>

나머지도 같은 방식으로 수정해주기

 

BoardListServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

ㄴ InitServlet 모두 제거해주기

 

BoardUpdateServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

BoardUpdateServlet.java

ㄴ InitServlet 모두 제거해주기

 

MemberAddServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

MemberAddServlet.java

ㄴ InitServlet 모두 제거해주기

 

MemberDeleteServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

MemberDeleteServlet.java

ㄴ InitServlet 모두 제거해주기

 

MemberDetailServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

MemberDetailServlet.java

ㄴ InitServlet 모두 제거해주기

 

MemberListServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

MemberListServlet.java

ㄴ InitServlet 모두 제거해주기

 

MemberUpdateServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>
MemberUpdateServlet.java

ㄴ InitServlet 모두 제거해주기

 

BoardDeleteServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

BoardDeleteServlet.java

ㄴ InitServlet 모두 제거해주기

 

BoardFileDeleteServlet.java

ㄴ 현재 필요한 객체 생성시키도록 함

=>

BoardFileDeleteServlet.java

ㄴ InitServlet 모두 제거해주기

 

ReportServletRequestListener.java

ㄴ 삭제한 InitServlet 대신 객체를 생성해주도록 함

=>

ㄴ App 실행

=>

 

=>

=>

ㄴ [새 회원] 선택

=>

ㄴ 값 입력 후 [등록] 선택

=>

ㄴ 생성한 회원의 이름 링크 선택

=>

=>

ㄴ 값 변경 후 [변경] 선택

=>

ㄴ 값이 변경됨을 확인

=>

ㄴ [삭제] 선택

=>

ㄴ 삭제가 정상적으로 처리됨을 확인

 

ㄴ [새 글] 선택

=>

ㄴ [등록] 선택

=>

ㄴ 생성한 게시글 제목 링크 선택

=>

ㄴ 첨부파일 링크 선택

=>

=>

ㄴ 첨부파일 > [삭제] 선택

=>

ㄴ 첨부파일이 정상적으로 삭제됨을 확인

=>

ㄴ 값 변경 후 [변경] 선택

=>

ㄴ 변경 값이 리스트에 정상적으로 출력됨을 확인

=>

ㄴ 첨부파일이 존재하는 상태에서 [삭제] 선택

=>

ㄴ 실행 오류 발생

=>

ㄴ 첨부파일을 모두 삭제하고 [삭제] 선택

=>

ㄴ 정상적으로 삭제됨을 확인

 


Auto Import 설정

ㄴ Editor > General > Auto Import 선택 > Optimize imports on the fly 체크박스를 체크 > [OK] 선택

 


64. JSP를 이용하여 MVC 모델1 구조로 변경하기

ㄴ 기존에 있던 webapp > board > form.jsp 삭제

=>

ㄴ 새로운 jsp 파일 생성

=>

webapp > board > form.jsp

ㄴ JSP 페이지의 속성을 설정하는 부분 (꼭 써줘야 함)

=>

webapp > board > form.jsp

ㄴ BoardFormServlet.java 파일의 일부분을 복사하여 붙여넣기

=>

webapp > board > form.jsp

<%@ page
    language="java"
    pageEncoding="UTF-8"
    contentType="text/html;charset=UTF-8"%>
    
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>비트캠프</title>
</head>
<body>

<div style='height: 50px;background-color:#c2e0f0;'>
    <img src='https://www.ncloud.com/public/img/logo-m.png' style='height: 40px'>
    <a href='/member/list'>회원</a>
    <a href='/board/list?category=1'>게시글</a>
    <a href='/board/list?category=2'>공지사항</a>
    <a href='/auth/form'>로그인</a>
</div>

<h1>게시글(JSP)</h1>
<form action='/board/add' method='post' enctype='multipart/form-data'>
    제목 <input type='text' name='title'><br>
    내용 <textarea name='content'></textarea><br>
    파일 <input type='file' name='files' multiple><br>
<input type='hidden' name='category' value='1'>
<button>등록</button>
</form>

<div style='text-align:center;background-color:gray;color:white;padding:10px;'>
    <p style='font-size:90%;margin: 0px;'>비트캠프 + 매직에꼴 + 네이버클라우드@2023</p>
    <address style='font-size: x-small; font-style:italic;'>서울시 강남구 강남대로 94길 20, 삼오빌딩 5층</address>
</div>

</body>
</html>

ㄴ header 와 footer 를 하드코딩하여 붙여넣기

=>

ㄴ url 에서 /board/form 뒤에 .jsp 를 직접 붙여주기

=>

ㄴ 페이지 소스 보기 선택

=>

ㄴ 하드코딩 된 header 와 footer 를 확인

=>

ㄴ url 에서 form 뒤에 .jsp 붙이기

=>

ㄴ JSP 파일이 정상적으로 노출됨을 확인

=>

ㄴ WEB-INF 에 새로운 header.jsp 파일 생성

=>

header.jsp

ㄴ jsp 설정코드와 webapp > board > form.jsp 의 헤더 부분의 코드를 잘라내서 붙여넣기

=>

ㄴ header.jsp 를 복사하여 footer.jsp 라는 파일 생성하기

=>

footer.java

ㄴ webapp > board > form.jsp 의 헤더 부분의 코드를 잘라내서 붙여넣기

=>

https://docs.oracle.com/cd/E13226_01/workshop/docs81/pdf/files/workshop/JSPTagsReference.pdf

ㄴ 여기서 용어는 jsp 는 namespace 라고 하고 include 는 element 라고 함

=>

webapp > board > form.jsp

ㄴ <jsp:include page="../header.jsp"></jsp:include> 은 <jsp:include page="../header.jsp"/> 로 간단하게 할 수 있음

=>

webapp > board > form.jsp

ㄴ footer 도 header 와 동일하게 적용해주기

=>

webapp > board > form.jsp

ㄴ jsp:include Action Tag를 이용한 것임을 확인하기 위해 적어줌

=>

ㄴ jsp:include Action Tag를 이용한 것임을 확인

=>

ㄴ 페이지 소스 보기 선택

=>

ㄴ header.jsp 와 footer.jsp 의 내용이 포함되어 출력됨을 확인

 

MemberListServlet.java

ㄴ 해당 이미지 링크 복사하기

=>

header.jsp

=>

HeaderServlet.java

ㄴ 해당 코드 복사

=>

header.jsp

ㄴ 복사한 코드 붙여넣은 후 expression element 태그를 이용하여 묶어주기

 

HeaderServlet.java

ㄴ 해당 import 복사

=>

Servlet.jsp

ㄴ import 를 jsp 형식으로 해주기

 

 

https://javaee.github.io/javaee-spec/javadocs/

 

Java(TM) EE 8 Specification APIs

 

javaee.github.io

 

ㄴ java.servlet.jsp > JspWriter

    => jsp 는 JspWriter 를 사용함

 

 

header.jsp

ㄴ println 으로 구조를 변경

ㄴ String.format() 사용하기

=>

header.jsp

<%@ page
    language="java"
    pageEncoding="UTF-8"
    contentType="text/html;charset=UTF-8"%>
<%@ page import ="bitcamp.report.vo.Member"%>

<div style='height: 50px;background-color:#c2e0f0;'>
    <img src='https://www.ncloud.com/public/img/logo-m.png' style='height: 40px'>
    <a href='/member/list'>회원</a>
    <a href='/board/list?category=1'>게시글</a>
    <a href='/board/list?category=2'>공지사항</a>
<%
    Member loginUser = (Member) request.getSession().getAttribute("loginUser");
    if (loginUser == null) {
      out.println("<a href='/auth/form'>로그인</a>");
    } else {
      if (loginUser.getPhoto() == null) {
        out.println("<img style='height:40px' src='/images/avatar.png'>");
      } else {
        out.println(String.format(
        "<img src='http://urnfabxxeceu19010753.cdn.ntruss.com/member/%s?type=f&w=30&h=40&faceopt=true&ttype=jpg'>",
                                      loginUser.getPhoto()));
      }
      out.println(String.format("%s <a href='/auth/logout'>로그아웃</a>", loginUser.getName()));
    }
%>
</div>

=>

form.jsp

ㄴ Scriptlet 사용함을 나타내주기 위해 추가

=>

ㄴ 정상적으로 출력됨을 확인

 

 

ㄴ BoardFormServlet.java 파일 삭제하기 (jsp 파일로 변경했기 때문)

 

 

BoardListServelet.java

ㄴ /board/form -> /board/form.jsp 로 변경하기 (이제 새 글 링크에서 jsp 파일로 이동 가능하도록 함)

=>

ㄴ [새 글] 선택

=>

ㄴ 새 글 /board/form.jsp 로 이동됨을 확인

 

 

 

ㄴ webapp/board/form.jsp 파일 복사

=>

ㄴ list.jsp 라는 이름으로 같은 위치에 붙여넣기

=>

form.jsp 와 같은 방식으로 나머지 XxxServlet.java 파일도 모두 Xxx.jsp 로 변경해주기

=>

list.jsp

ㄴ 한 줄에 import 문을 2개 작성할 수 있음

=>

list.jsp

ㄴ servlet 관련 import 는 알아서 해주므로 제거

=>

list.jsp

ㄴ <%! ... %>는 JSP 페이지 내에서 선언적인 코드 블록을 나타냄 (declaration element : 필드와 메서드 선언)

=>

list.jsp

ㄴ 해당 코드는 위쪽의 jsp 설정인 directive element 에서 설정해주므로 제거

=>

list.jsp

ㄴ jsp 에서는 JspWriter 를 사용하므로 제거

=>

list.jsp

ㄴ 아래쪽 코드 대신 위쪽의 <jsp:include> 태그를 사용하여 JSP 페이지에서 다른 JSP 페이지를 포함하거나 삽입하도록 함

=>

list.jsp

ㄴ 표현식 태그 이용하기

=>

list.jsp

ㄴ 자바 코드는 <% %> (스크립트릿)으로 묶어주기

=>

list.jsp

<%@ page
    language="java"
    pageEncoding="UTF-8"
    contentType="text/html;charset=UTF-8"%> <%-- directive element --%>

<%@ page import="java.io.IOException"%>
<%@ page import="java.text.SimpleDateFormat"%>
<%@ page import="java.util.List"%>
<%@ page import="bitcamp.report.dao.BoardDao"%>
<%@ page import="bitcamp.report.vo.Board"%>

<%!
  // declaration element
  SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
%>

<%
    // scriptlet (scripting element)
    int category = Integer.parseInt(request.getParameter("category"));
%>

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>게시글</title>
</head>
<body>

<jsp:include page="../header.jsp"/>

<h1>게시글 목록</h1>
<div style='margin:5px;'>
<a href='/board/form.jsp?category=<%=category%>'>새 글</a>
</div>
<table border='1'>
<thead>
<tr><th>번호</th> <th>제목</th> <th>작성자</th> <th>조회수</th> <th>등록일</th></tr>
</thead>

<%
    BoardDao boardDao = (BoardDao) this.getServletContext().getAttribute("boardDao");

    List<Board> list = boardDao.findAll(category);

    out.println("<tbody>");
    for (Board board : list) {
      out.printf(
          "<tr>"
          + " <td>%d</td>"
          + " <td><a href='/board/detail?category=%d&no=%d'>%s</a></td>"
          + " <td>%s</td>"
          + " <td>%d</td>"
          + " <td>%s</td></tr>\n",
          board.getNo(), board.getCategory(), board.getNo(),
          (board.getTitle().length() > 0 ? board.getTitle() : "제목없음"), board.getWriter().getName(),
          board.getViewCount(), dateFormatter.format(board.getCreatedDate()));
    }
%>
</tbody>
</table>
<a href='/'>메인</a>

<jsp:include page="../footer.jsp"/>

</body>
</html>

 

header.jsp

ㄴ /board/list -> /board/list.jsp 로 변경하기

=>

ㄴ BoardListServlet.java 파일은 삭제해주기

=>

ㄴ 깔끔하게 App Restart

=>

ㄴ [게시글] 선택

=>

=>

ㄴ header.jsp 파일 복사

=>

ㄴ 복사한 파일을 같은 위치에 index 라는 이름으로 붙여넣기

=>

index.jsp

<%@ page
    language="java"
    pageEncoding="UTF-8"
    contentType="text/html;charset=UTF-8"%>
<%@ page import ="bitcamp.report.vo.Member"%>

<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>비트캠프</title>
</head>
<body>

<jsp:include page="header.jsp"/>

<h1>MyApp11</h1>
<p>개인 프로젝트 입니다</p>

<jsp:include page="footer.jsp"/>

</body>
</html>

ㄴ HomeServlet.java 내용 복사하여 수정하기

=>

ㄴ HomeServlet.java 파일 삭제

 

webapp > WEB-INF > web.xml

ㄴ <welcome-file> 태그에 index.jsp 를 맨 위로 올려주도록 함

 

index.jsp

<%@ page
    language="java"
    pageEncoding="UTF-8"
    contentType="text/html;charset=UTF-8"%>
<%@ page import ="bitcamp.report.vo.Member"%>

<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>비트캠프</title>
</head>
<body>

<jsp:include page="header.jsp"/>

<h1>MyApp(JSP)</h1>
<p>개인 프로젝트 입니다</p>

<jsp:include page="footer.jsp"/>

</body>
</html>

=>

App Restart

=>

ㄴ [게시글] 선택

=>

ㄴ printf 는 사용할 수 없음을 확인

=>

list.jsp

ㄴ println 과 String.format() 을 이용

=>

 

list.jsp

ㄴ 자바코드를 최대한 없애기