1. 게시판 로그인, 로그아웃, 마이페이지
- 로그인 시 헤더부분 login 에서 logout과 mypage로 나오게 설정.
* 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" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-idth, initial-scale=1">
<title>Welcome to MyWorld</title>
<!-- Bootstrap Core CSS -->
<link href="${pageContext.request.contextPath }/css/bootstrap.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="${pageContext.request.contextPath }/css/business-casual.css" rel="stylesheet">
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Josefin+Slab:100,300,400,600,700,100italic,300italic,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<!-- jQuery -->
<script src="${pageContext.request.contextPath }/js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="${pageContext.request.contextPath }/js/bootstrap.min.js"></script>
<script>
$('.carousel').carousel({
interval: 2000 //changes the speed
})
</script>
<style>
.abc {
position: sticky;
top: 0px;
width: 100%;
z-index: 10;
}
</style>
</head>
<body>
<!-- header -->
<div class="brand">My Web</div>
<div class="address-bar">Welcome to MyWorld</div>
<nav class="navbar navbar-default abc" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/hong">My First Web</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>
<a href="${pageContext.request.contextPath}/index.main">HOME</a>
</li>
<li>
<a href="${pageContext.request.contextPath}/member/member.main">Member</a>
</li>
<li>
<a href="${pageContext.request.contextPath}/board/board_list.board">BOARD</a>
</li>
<c:choose>
<c:when test="${sessionScope.user_id == null }">
<li>
<a href="${pageContext.request.contextPath}/user/user_login.user">LOGIN</a>
</li>
<li>
<a href="${pageContext.request.contextPath}/user/user_join.user" style="color:red">JOIN</a>
</li>
</c:when>
<c:otherwise>
<li>
<a href="${pageContext.request.contextPath}/user/user_logout.user">LOGOUT</a>
</li>
<li>
<a href="${pageContext.request.contextPath}/user/user_mypage.user" style="color:red">MYPAGE</a>
</li>
</c:otherwise>
</c:choose>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
- 로그인을 하면 세션에 정보가 저장됨
- 저장된 정보가 있다면 헤더에 logout과 mypage
2. mypage 화면에 로그아웃, 정보수정, 회원탈퇴 기능을 추가
- 회원 데이터를 가지고 나오는 작업의 순서
1) service와 dao에 getInfo()메서드를 선언
2) service에서는 세션에서 아이디를 얻는다
3) dao에서는 id를 전달받아 회원 데이터를 조회하여 vo에 저장
4) controller에서는 조회한 vo를 저장하고 화면으로 가지고 나감
5) 화면에서는 input태그에 값을 출력
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file = "../include/header.jsp" %>
<section>
<div align = "center">
${sessionScope.user_id }
<b>(${sessionScope.user_name })</b>님 환영합니다
<div>
<a href = "user/user_logout.user">[로그아웃]</a>
<a href = "user_modify.user">[정보수정]</a>
<a href = "user_delete.user">[회원탈퇴]</a>
</div>
</div>
</section>
<%@ include file = "../include/footer.jsp" %>
1) 로그아웃 시에는 usercontroller에서 세션 정보를 삭제하고 메인으로 이동
case "/user/user_logout.user": //로그아웃
HttpSession session = request.getSession();
session.invalidate(); //세션 무효화
//response.sendRedirect("/JSPWeb/index.main"); //메인으로
response.sendRedirect(path + "/index.main");
break;
2) 회원정보 수정 할 때
- dao에서 getInfo 메서드를 사용하여 vo2 객체를 생성한다.
- vo2 객체를 vo로 설정하거나, vo2.getID로 각 변수의 키값을 따로 저장하는 방법을 사용할 수 있음.
case "/user/user_modify.user": //정보 수정 화면
/*회원 데이터를 가지고 나오는 작업.
* service와 dao에 getInfo() 메서드를 선언합니다.
* service에서는 세션에서 아이디를 얻습니다.
* dao에서는 id를 전달 받아 회원 데이터를 조회해서 vo에 저장합니다.
* controller에서는 조회한 vo를 저장하고 화면으로 가지고 나갑니다.
* 화면에서는 input태그에 값을 출력해주세요.
*/
UserVO vo2 = service.getInfo(request, response);
request.setAttribute("vo", vo2); //vo라는 키로 vo를 담고, 값 vo2 = 화면에서 vo를 사용할 수 있게 됩니다.
request.getRequestDispatcher("user_modify.jsp").forward(request, response);
break;
* DAO의 getInfo 메서드
- DAO에도 getInfo 라는 메서드를 선언하여 데이터베이스 즉 SQL에 들어있는 데이터를 불러온다. SQL문 같은 경우에는 아래와 같이 선언하고 pstmt.setString(1,id)값을 통해서 설정해준다.
select * from users where id =?;
이 과정을 통해서 필요한 값들을 vo에 값을 넣어준다.
public UserVO getInfo(String id) {
UserVO vo = null;
String sql = "select * from users where id = ?";
try {
conn = DriverManager.getConnection(URL, UID, UPW);
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
//rs 역할: next를 만나면 다음 행을 검사하고, 다음 행이 있으면 true를 반환(전진과 유사)
rs = pstmt.executeQuery();
if(rs.next()) {
//패스워드는 보여지면 안되니까 안가져옴
String id2 = rs.getString("id");
String name = rs.getString("name");
String email = rs.getString("email");
String gender = rs.getString("gender");
vo = new UserVO(id2, null, name ,email, gender);
}
} catch (Exception e) {
e.printStackTrace();
}
return vo;
* userserviceimpl에서 getinfo 메서드
- 기존에 있던 service interface에 getInfo 메서드를 선언하고 Interface는 메뉴판이라고 생각하기.
- 오버라이딩을 통해서 메서드의 내용을 넣어준다. 이 경우에는 기존의 로그인을 하면서 session에 담아줬던 key값 user_id를 통해서 정보를 불러올 것이다.
@Override
public UserVO getInfo(HttpServletRequest request, HttpServletResponse response) {
//세션에서 user_id 값을 얻음
HttpSession session = request.getSession();
//로그인을 했을 당시에 controller에 user_id로 저장했음(세션에 저장된 키는 중요함)
String id = (String)session.getAttribute("user_id");
//dao 객체 생성해서 호출하고
UserDAO dao = UserDAO.getInstance();
UserVO vo = dao.getInfo(id); //DAO에서 반환되서 돌아오는 vo
return vo;
}
최종적으로 controller에서 UserService의 getInfo메서드를 호출하여 객체를 request에 담아준다.
* usermodify.jsp
-form을 입력할 시 updateForm으로 데이터를 전달함.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="../include/header.jsp"%>
<section>
<div align="center">
<h3>회원 정보 수정 연습</h3>
<form action="updateForm.user" method="post">
<table>
<tr>
<td>아이디</td>
<td><input type="text" name="id" value="${vo.id}"
placeholder="4~8글자 영문자 숫자" pattern="\w{4,8}" required readonly></td>
</tr>
<tr>
<td>비밀번호</td>
<td><input type="password" name="pw"
placeholder="4~8글자 영문자 숫자" pattern="\w{4,8}" required="required"></td>
</tr>
<tr>
<td>이름</td>
<td><input type="text" name="name" value="${vo.name }"
pattern="[가-힣]{3,}"></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="email" name="email" value="${vo.email }" readonly></td>
</tr>
<tr>
<td>성별</td>
<td>
<input type="radio" name="gender" value="f" ${vo.gender == 'f' ? 'checked' : '' }>여자
<input type="radio" name="gender" value="m" ${vo.gender == 'm' ? 'checked' : '' }>남자
</td>
</tr>
</table>
<input type="submit" value="정보수정">
<!--
JS로 기능을 붙임
onclick = "location.href ='경로'
-->
<input type="button" value="마이페이지"
onclick="location.herf = 'user_mypage.user' ">
</form>
</div>
</section>
<%@ include file="../include/footer.jsp"%>
* UserController
case "/user/updateForm.user" :
/*
* *****회원정보를 업데이트 하는 작업*****
* service와 dao에 update() 메서드를 생성
* service의 필요한 파라미터 값을 받습니다. (pw, name, gender), 조건절에 id
* dao에서 데이터를 전달받아서 업데이트를 실행
* 업데이트 이후에는 컨트롤러를 태워서 mypage로 리다이렉트
*/
int result2 = service.update(request, response);
if(result2 == 1) { //업데이트 성공
//response.sendRedirect("user_mypage.user");
//out 객체를 이용해서 화면에 스크립트를 작성해서 보냄
response.setContentType("text/html; charset = utf-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('정보가 수정되었습니다');");
out.println("location.href='user_mypage.user'; ");
out.println("</script>");
} else { //업데이트 실패
//modify화면으로 포워드 하면(주소가 남지 않기 때문에 포워드는 어울리지 않음)
//문제 발생하기 때문에 컨트롤러에 태워서 리다이렉트
response.sendRedirect("user_modify.user");
}
break;
* UserDAO
- DAO의 업데이트 메서드로 sql에서 아이디를 기준으로 데이터를 찾아서 pw, name, gender 수정이 가능함.
//회원정보 업데이트(수정)
public int update(String id, String pw, String name, String gender) {
int result = 0;
String sql = "update users set pw = ?, name = ?, gender = ? where id = ?";
try {
conn = DriverManager.getConnection(URL, UID, UPW);
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, pw);
pstmt.setString(2, name);
pstmt.setString(3, gender);
pstmt.setString(4, id);
//rs 역할: next를 만나면 다음 행을 검사하고, 다음 행이 있으면 true를 반환(전진과 유사)
result = pstmt.executeUpdate(); //성공시 1, 실패 0
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(conn, pstmt, rs);
}
return result;
}
* service의 업데이트 메서드
@Override
public int update(HttpServletRequest request, HttpServletResponse response) {
//파란색은 태그의 네임값(modify.jsp name = "name") 이런식으로 태그 값이 들어가야함
String id = request.getParameter("id");
String pw = request.getParameter("pw");
String name = request.getParameter("name");
String gender = request.getParameter("gender");
//DAO객체 생성
UserDAO dao = UserDAO.getInstance();
int result = dao.update(id, pw, name, gender);
//업데이트 성공시 세션 변경
if(result == 1) {
HttpSession session = request.getSession();
session.setAttribute("user_name", name);
}
return result;
3) 회원 탈퇴
* usercontroller에서의 회원 탈퇴
case "/user/user_delete.user":
int result3 = service.delete(request, response);
if(result3 == 1) {
response.sendRedirect(path + "/index.main"); //메인화면
} else {
response.sendRedirect("user_mypage.user"); //마이페이지
}
break;
default:
break;
* UserDAO의 delete 메서드
public int delete(String id) {
int result = 0;
String sql = "delete from users where id = ?";
try {
conn = DriverManager.getConnection(URL, UID, UPW);
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
result = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(conn, pstmt, rs);
}
return result;
}
* UserServiceImpl에서 오버라이딩 된 메서드
@Override
public int delete(HttpServletRequest request, HttpServletResponse response) {
//id가 필요
HttpSession session = request.getSession();
String id = (String)session.getAttribute("user_id");
//DAO 객체 생성
UserDAO dao = UserDAO.getInstance();
int result = dao.delete(id);
if(result == 1) { //삭제 성공
session.invalidate();
}
return result;
}
* 기본 개념을 숙지해야 적재적소에 사용이 가능합니다.
request(다음 페이지까지 유효하다, 쓸 수 있다)
폼데이터 - getParameter(" ")
저장 - setAttribute(키, 값)
사용 - getAttribute(키)
response
sendRedirect()
addCookie()
session
setAttribute
getAttribute
removeAttribute
invalidate
application
setAttribute
getAttribute
removeAttribute
invalidate
* 계속 이해가 힘들었던 부분은 그림으로 이해하고 만들어둔 클래스를 보면서 이해해볼 것.
3. board
그림 보며 참고할 것 1. board div 빼고 파일 나누기 2. boardController 생성 3. boardController에 URL을 나누고, 화면을 띄우는 프로그램 코드 클라이언트: board_write.jsp 파일에서는 글을 작성할 수 있도록 화면으로 보여짐 (모든 jsp 파일) |
1) board~jsp 파일을 div 빼고 다 지우고 파일 나누기(header, footer로 보내줍니다)
클라이언트: board_write.jsp 파일에서는 글을 작성할 수 있도록 화면으로 보여짐(모든 jsp 파일)
jsp 파일에서 <form action="registForm.board" method="post"> 문장을 통해
작성된 글을 boardController로 보냄(*board = 컨트롤러로 보낸다는 뜻)
* board_write.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file = "../include/header.jsp" %>
<div align="center" class="div_center">
<h3>게시판 글 작성 페이지</h3>
<hr>
<form action="registForm.board" method="post">
<table border="1" width="500">
<tr>
<td>작성자</td>
<td>
<input type="text" name="writer" size="10" required>
</td>
</tr>
<tr>
<td>글 제목</td>
<td>
<input type="text" name="title" required>
</td>
</tr>
<tr>
<td>글 내용</td>
<td>
<textarea rows="10" style="width: 95%;" name="content"></textarea>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="작성 완료">
<input type="button" value="목록" onclick="location.href='board_list.board' ">
</td>
</tr>
</table>
</form>
</div>
<%@ include file = "../include/footer.jsp" %>
2) boardController 생성
- boardController에 URL을 나누고, 화면을 띄우는 프로그램 코드
* boardController
- boardController: else if( command.equals("/board/registForm.board")) 라는 문장에서 같으면 service 클래스의 등록을 요청하고 응답하겠다는 뜻.
package com.example.controller;
import java.io.IOException;
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 com.example.board.service.BoardService;
import com.example.board.service.BoardServiceImpl;
@WebServlet("*.board")
public class BoardController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
protected void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//한글처리
request.setCharacterEncoding("utf-8");
//요청 분기
String uri = request.getRequestURI();
String path = request.getContextPath();
String command = uri.substring(path.length() );
System.out.println("요청 경로:" + command);
BoardService service = new BoardServiceImpl();
if( command.equals("/board/board_write.board")) { //등록 화면
request.getRequestDispatcher("board_write.jsp").forward(request, response);
} else if( command.equals("/board/board_list.board")) { //목록화면
//조회 메서드
request.getRequestDispatcher("board_list.jsp").forward(request, response);
} else if( command.equals("/board/board_content.board")) { //상세 내용 화면
request.getRequestDispatcher("board_content.jsp").forward(request, response);
} else if( command.equals("/board/board_modify.board")) { //수정 화면
request.getRequestDispatcher("board_modify.jsp").forward(request, response);
} else if( command.equals("/board/registForm.board")) {//글 등록
//서비스의 regist 메서드 실행
//.board 컨트롤러에서 태워서 요청을 잡아 다시 연결을 시킴(insert 작업 거치고 나면 목록 화면으로 나오고 데이터를 가지고 목록화면으로 나가야 하니까)
service.regist(request, response);
response.sendRedirect("board_list.board");
/*
* 1. service의 regist 메서드로 연결
* 2. service에서 등록에 필요한 파라미터를 받습니다.
* 3. dao의 void regist 메서드를 생성하고 insert 작업
* 4. insert이후에 컨트롤러에서 리스트로 리다이렉트
*/
}
}
}
* boardservice
- 인터페이스 service: 요청하고 응답받는 메서드
- 사용 방법을 정의한 타입(메서드 명세서)라고 생각할 것(다형성을 구현하는 매우 중요한 역할을 함)
package com.example.board.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface BoardService {
public void regist(HttpServletRequest request, HttpServletResponse response); //등록
}
* boardserviceimpl
- ServiceImpl: implement는 service의 메서드를 보기 편하게 묶어둠(즉, 이 클래스에는 무슨 메서드가 있는지 보여주기 편하기 위함임)
- jsp에 있는 </input type="text" name="writer" size="10" required> 이 문장에서 name = "writer"이라는 키워드를 impl에서 String writer = request.getParameter("writer"); = jsp 파일에 있는 writer이라는 키값을 요청해서 String writer에 저장하겠다는 뜻.
- 다 하고 나서 변수를 선언함
- boardDAO 클래스에서 객체 하나만 사용하겠다.
- BoardDAO dao = BoardDAO.getInstance();
//dao객체에 등록한다.
dao.regist(writer, title, content);
그리고 그림을 보면 DAO로 이동(DB랑 연결됨)
package com.example.board.service;
import java.sql.Timestamp;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.example.board.model.BoardDAO;
//메서드를 보기 편하게 묶어둠(이 클래스에는 무슨 메서드가 있는지 보여주기 편하기 위함)
public class BoardServiceImpl implements BoardService {
@Override
public void regist(HttpServletRequest request, HttpServletResponse response) {
//int bno = request.getParameter("bno");
String writer = request.getParameter("writer");
String title = request.getParameter("title");
String content = request.getParameter("content");
//변수 선언: 하나의 객체만 들어가겠다.
//boardDAO 클래스에서 객체 하나만 사용하겠다.
BoardDAO dao = BoardDAO.getInstance();
//dao객체에 등록한다. DAO 메서드 호출
dao.regist(writer, title, content);
}
}
* boardDAO
package com.example.board.model;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.example.user.model.UserDAO;
import com.example.util.JDBCUtil;
public class BoardDAO {
//UserDAO는 불필요하게 여러개 만들어질 필요가 없기 때문에
//한개의 객체만 만들어지도록 Singleton 형식으로 설계합니다.
//1. 나 자신의 객체를 생성해서 1개로 제한합니다.
private static BoardDAO instance = new BoardDAO();
//2. 직접 객체를 생성할 수 없도록 생성자에 private
private BoardDAO() {
//드라이버 클래스 로드
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
System.out.println("드라이버 클래스 로드 에러");
}
}
//3. 외부에서 객체 생성을 요구할 때 getter 메서드를 통해 1번의 객체를 반환
public static BoardDAO getInstance() {
return instance;
}
//4. 필요한 데이터 베이스 변수 선언
public String URL = "jdbc:oracle:thin:@localhost:1521:xe";
public String UID = "jsp";
public String UPW = "jsp";
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
//5. 메서드
public void regist(String Writer, String Title, String Content) {
String sql = "insert into board(bno, writer, title, content) values (board_seq.NEXTVAL, ?, ?, ?)";
try {
conn = DriverManager.getConnection(URL, UID, UPW);
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, Writer);
pstmt.setString(2, Title);
pstmt.setString(3, Content);
pstmt.executeUpdate();
} catch (Exception e) {
} finally {
JDBCUtil.close(conn, pstmt, rs);
}
}
}
그리고 다시 controller의 요청 분기의 순서대로 계속해서 실행함
service.regist(request, response); 이게 끝나면
response.sendRedirect("board_list.board"); 로 보내진다.
여기서도
else if( command.equals("/board/board_list.board")) 얘랑 같으면 { //목록화면
request.getRequestDispatcher("board_list.jsp").forward(request, response); 얘로 보내지겠다라는 뜻.