'회원관리 웹 어플리케이션' 포스팅 에서 이어지는 포스팅으로 아래 기능이 추가되었다.
1. layout.jsp를 두 경우로 나눔
1)login-layout.jsp - 로그인 시 보여지는 view
2)layout.jsp-로그인을 안 했을 때 보여지는 view
2. login-layout.jsp 상태에서 회원정보 수정
- VO 정보와 session의 VO 정보 둘 다 수정
[ 프로그램 진행 원리 및 개요 ]
웹 페이지에서 동적으로 이동되는 부분(메인 화면)만 새로 업데이트하여 보여주기 위하여,
전체적인 layout을 잡아두고, 메인 화면에 기능에 따른 새로운 view(jsp)를 할당하여 동작하도록 한다.
1. layout 화면을 로그인/비로그인으로 나누어 제공
기능 2 : 로그인 상태에서 회워정보 수정 기능
[ 구현 코드 ]
Model
/MemberVO.java
package org.kosta.model;
public class MemberVO {
private String id;
private String password;
private String name;
private String address;
public MemberVO() {
super();
}
public MemberVO(String id, String password) {
super();
this.id = id;
this.password = password;
}
public MemberVO(String id, String password, String name, String address) {
super();
this.id = id;
this.password = password;
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "MemberVO [id=" + id + ", password=" + password + ", name=" + name + ", address=" + address + "]";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/MemberDAO.java
package org.kosta.model;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
/*
* Database Connection Pool 객체를 생성해 공유하는 클래스
* DBCP -> 시스템 성능 향상을 위해 DB 컨넥션을 생성, 소멸시키지 않고
* 미리 생성한 컨넥션을 빌려주고 반납하도록 한다.
* javax.sql.DataSource Interface 타입으로 dbcp를 관리한다
* 이유는 WAS 가 변경되면 DBCP도 변경될 수 있으므로 추상화된 인터페이스 타입으로
* 관리하는 것이 유지보수에 유리하다
*/
public class DataSourceManager {
private static DataSourceManager instance=new DataSourceManager();
private DataSource dataSource;
private DataSourceManager() {
// was tomcat에서 제공하는 dbcp를 생성해서 사용한다
BasicDataSource dbcp=new BasicDataSource();
dbcp.setDriverClassName("oracle.jdbc.OracleDriver");
dbcp.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:xe");
dbcp.setUsername("scott");
dbcp.setPassword("tiger");
dbcp.setInitialSize(3);//처음 로드될 때 생성해 놓을 컨넥션 수
dbcp.setMaxTotal(10);//최대 컨넥션 수 : 기본은 8
this.dataSource=dbcp;
}
public static DataSourceManager getInstance() {
return instance;
}
public DataSource getDataSource() {
return dataSource;
}
}
View
[ template ]
/index.jsp
index를 실행하면 <jsp:forward> 방식으로 home.jsp로 간다
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:forward page="front">
<jsp:param value="home" name="command"/>
</jsp:forward>
/home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
[ CSS ]
/myhome.css
@charset "UTF-8";
.header {
/*문자 정렬 왼쪽*/
text-align: left;
height: 70px;
}
.main {
text-align: center;
height: 500px;
}
.footer {
text-align: center;
height: 10px;
}
-- 기능 1: id로 회원 정보 찾기
/findbyid-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%-- findbyid-form.jsp
ㅣ
FindMemberByIdController
ㅣ
findbyid-fail.jsp에서는 alert후 home으로 이동
(해당 파일로 forward)
findbyid-ok.jsp에서는 layout이 적용되어야 함
--%>
<form action="front">
<input type="hidden" name="command" value="findMemberById">
아이디 <input type="text" name="id" required="required">
<input type="submit" value="검색">
</form>
/findbyid-ok.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
검색 결과 <br>
아이디 : ${param.id}<br>
이름 : ${requestScope.vo.name}<br>
주소 : ${requestScope.vo.address}<br>
/findbyid-fail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript">
alert("${param.id} 에 해당하는 회원정보가 없습니다!")
location.href = "front?command=home"
</script>
-- 기능 2 : 회원 가입 기능
/register-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
command-reigster -- RegisterController -- MemberDAO : register
ㅣ
ㅣredirect
ㅣ
RegisterResultController
ㅣ forward
ㅣ : forward일때만 layout으로 갈 수 있음
member/register-result.jsp
(레이아웃이 적용되어야 함)
--%>
<form action="${pageContext.request.contextPath}/front" method="post">
<input type="hidden" name="command" value="register">
아이디 <input type="text" name="id" required="required"><br>
패스워드 <input type="password" name="password" required="required"><br>
이름 <input type="text" name="name" required="required"><br>
주소 <input type="text" name="address" required="required"><br><br>
<input type="submit" value="회원가입">
</form>
/register-result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
${requestScope.vo.name}님 회원가입이 완료되었습니다.
-- 기능 3 : 로그인 + 로그아웃 기능 (로그인 실패 페이지만 필요)
/login-fail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript">
alert("로그인 실패!");
location.href = "front?command=home"
</script>
-- 기능 4 : 회원 정보 수정 기능
sessionScope를 쓸 때에는 JSP 선언부에 session="false"가 있으면 안된다 !
/update-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<form action="${pageContext.request.contextPath}/front" method="post">
<input type="hidden" name="command" value="updateMember">
아이디 <input type="text" name="id" value="${sessionScope.mvo.id}" readonly="readonly"><br>
패스워드 <input type="password" name="password" value="${sessionScope.mvo.password}" required="required"><br>
이름 <input type="text" name="name" value="${sessionScope.mvo.name}" required="required"><br>
주소 <input type="text" name="address" value="${sessionScope.mvo.address}" required="required"><br><br>
<input type="submit" value="수정하기">
</form>
/update-result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<strong>회원정보 수정 완료!</strong><br><br>
아이디 : ${sessionScope.uvo.id}<br>
이름 : ${sessionScope.uvo.name}<br>
주소 : ${sessionScope.uvo.address}<br>
Controller
/Controller.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Controller {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
/ HandlerMapping.java
package org.kosta.controller;
public class HandlerMapping {
private static HandlerMapping instance=new HandlerMapping();
private HandlerMapping() {}
public static HandlerMapping getInstance() {
return instance;
}
public Controller create(String command) {
Controller controller=null;
if(command.contentEquals("home"))
controller=new HomeController();
else if(command.contentEquals("findMemberByIdForm"))
controller=new FindMemberByIdFormController();
else if(command.contentEquals("findMemberById"))
controller=new FindMemberByIdController();
else if(command.contentEquals("registerForm"))
controller=new RegisterFormController();
else if(command.contentEquals("register"))
controller=new RegisterController();
else if(command.contentEquals("register-result"))
controller=new RegisterResultController();
else if(command.contentEquals("login"))
controller=new LoginController();
else if(command.contentEquals("logout"))
controller=new LogoutController();
else if(command.contentEquals("updateMemberForm"))
controller=new UpdateMemberFormController();
else if(command.contentEquals("updateMember"))
controller=new UpdateMemberController();
else if(command.contentEquals("updateMember-result"))
controller=new UpdateMemberResultController();
return controller;
}
}
/DispatcherServlet.java
handleRequest method 작동 방식
1. 에러(예외) 발생 시, 콘솔에 메세지 발생 경로 출력 후, error.jsp로 redirect 방식으로 view로 이동한다.
2. 클라이언트가 전송한 command 정보를 받는다.
3. HandlerMapping 을 이용해 개별 컨트롤러 객체를 컨트롤러 인터페이스 타입으로 반환받는다.
4. 개별 컨트롤러를 실행한다.
5. 실행 후 반환된 String url 정보를 이용해,
forward 방식 or redirect 방식으로 view로 이동해 응답하게 한다.
+ 각 단계에서 어디서 에러가 났는지 알 수 있도록 단계 별로 console에 print 되도록 해준다
package org.kosta.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;
/**
* Servlet implementation class DispatcherServlet
*/
@WebServlet("/front")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.handleRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
this.handleRequest(request, response);
}
/* 1. 에러 발생시 error.jsp로 redirect 한다
* 2. client가 보낸 command를 받는다
* 3. command를 이용해 HandlerMapping의 create를 호출 , 컨트롤러를 반환받는다
* 4. 컨트롤러를 실행한다
* 5. 컨트롤러가 실행 한 후 반환하는 String 정보를 이용해
* forward 또는 redirect 방식으로 응답하도록 view로 이동시킨다.
*/
protected void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String command=request.getParameter("command");
// System.out.println("command:"+command);
Controller controller=HandlerMapping.getInstance().create(command);
// System.out.println("controller:"+controller);
String url=controller.execute(request, response);
// System.out.println("url:"+url);
if(url.startsWith("redirect:"))
response.sendRedirect(url.substring(9));
else
request.getRequestDispatcher(url).forward(request, response);
}catch (Exception e) {
e.printStackTrace(); // 예외 메세지와 발생 경로를 모두 콘솔에 출력한다
response.sendRedirect("error.jsp");
}
}
}
--- 기능 0 : index.jsp에서 실행하면, 로그인 여부 판단에 따라 서로 다른 layout으로 이동하는 Controller
(request.setAttribute를 통해 url에 home.jsp를 할당하여, home 정보를 메인화면에 할당)
/HomeController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class HomeController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
/*
* 로그인 사용자와 로그인하지 않은 사용자를 구분하여 home 화면을 다르게 제공한다.
*/
String url = null;
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("mvo") != null)
// 로그인 사용자
url = "/template/login-layout.jsp";
else // 로그인 하지 않은 사용자
url = "/template/layout.jsp";
// 웹 디자인 레이아웃이 적용된 화면으로 응답하기 위해
// template/layout.jsp에 있는 아래 코드 부분에 화면 정보를 할당한 후
// <c:import url="${requestScope.url}">
// layout.jsp로 forward 한다
request.setAttribute("url", "/home.jsp");
return url;
}
}
--- 기능 1 : 아이디로 회원정보 조회 Controller
forward 방식의 경우 Form -> layout view로 이동 순으로 진행한다.
/FindMemberByIdFormController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FindMemberByIdFormController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setAttribute("url", "/member/findbyid-form.jsp");
// 레이아웃 적용
return "/template/login-layout.jsp";
}
}
/FindMemberByIdController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;
public class FindMemberByIdController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String id = request.getParameter("id");
MemberVO vo = MemberDAO.getInstance().findMemberById(id);
if (vo != null) {
request.setAttribute("vo", vo);
request.setAttribute("url", "/member/findbyid-ok.jsp");
} else {
//레이아웃 적용이 필요 없으므로
//바로 findbyid-fail.jsp로 감(javascript 실행만 필요)
return "/member/findbyid-fail.jsp";
}
return "/template/login-layout.jsp";
}
}
--- 기능 2 : 회원가입 기능 Controller
redirect 방식의 경우 form 에서 바로 view로 이동하게되면 회원가입이 여러번 진행되어 오류가 발생할 수 있으므로,
form에서 view에 앞서 controller로 이동시켜야한다.
그러므로, form -> 동작 -> layout view로 이동한다.
/RegisterFormController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegisterFormController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
//layout이 적용된 회원가입폼 화면이 응답하게 한다
request.setAttribute("url", "/member/register-form.jsp");
return "/template/layout.jsp";
}
}
/RegisterController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;
public class RegisterController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
/* < forwarding 방식 >
* System.out.println("회원 가입 처리");
* request.setAttribute("url","/member/register-result.jsp");
* return "/template/layout.jsp";
*
* forwarding 방식은 회원가입에는 적절하지 않다.
* 그 이유는 forward 방식으로 응답하면 사용자가 재동작시킬 경우
* 다시 가입을 시도하기 때문이다!
*
* 그렇기 때문에 회원가입과 같은 DB에 INSERT, UPDATE, DELETE하는
* 경우에는 redirect 방식이 적합하다.
*/
String id = request.getParameter("id");
String password = request.getParameter("password");
String name = request.getParameter("name");
String address = request.getParameter("address");
MemberVO vo = new MemberVO(id, password, name, address);
MemberDAO.getInstance().register(vo);
//RegisterResultController로 보내기 위해
//command에 register-result를 적어준다.
// + id를 넘겨주기 위해 쿼리스트링 방식으로 id를 넘겨준다
return "redirect:front?command=register-result&id="+id;
}
}
/RegisterResultController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;
public class RegisterResultController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
//RegisterController에서 보낸 id를 getParameter로 받아올수 있다
String id = request.getParameter("id");
//이 id를 이용해 DAO에 있는 method를 통해 정보를 받아준다
MemberVO vo = MemberDAO.getInstance().findMemberById(id);
request.setAttribute("vo", vo);
request.setAttribute("url", "/member/register-result.jsp");
return "/template/layout.jsp";
}
}
--- 기능 3 : 로그인 + 로그아웃 기능 Controller
/LoginController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;
public class LoginController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String id = request.getParameter("id");
String password = request.getParameter("password");
MemberVO vo = new MemberVO(id, password);
MemberVO mvo = MemberDAO.getInstance().login(vo);
if (mvo == null) {
return "/member/login-fail.jsp";
} else {
HttpSession session = request.getSession();
session.setAttribute("mvo", mvo);
request.setAttribute("url", "/member/login-ok.jsp");
return "/template/login-layout.jsp";
}
}
}
/LogoutController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LogoutController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
HttpSession session = request.getSession(false);
//로그인 정보가 있을때
if (session != null)
session.invalidate(); //로그아웃
return "front?command=home";
}
}
-- 기능 4 : 회원정보 수정 Controller
/UpdateMemberFormController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UpdateMemberFormController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//login-layout의 메인화면 부분에 update-form.jsp을 보냄
request.setAttribute("url", "/member/update-form.jsp");
return "/template/login-layout.jsp";
}
}
/UpdateMemberController.java
session정보의 vo객체와 DAO를 통해 받아온 기존에 존재하던 vo객체 둘 다 수정해준다.
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.kosta.model.MemberDAO;
import org.kosta.model.MemberVO;
public class UpdateMemberController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String id = request.getParameter("id");
String password = request.getParameter("password");
String name = request.getParameter("name");
String address = request.getParameter("address");
MemberVO uvo = new MemberVO(id, password, name, address);
//MemberVO 정보 수정
MemberDAO.getInstance().updateMember(uvo);
//session의 MemberVO 정보 수정
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("mvo") != null) {
//session에 회원정보 업데이트
session.setAttribute("uvo", uvo);
return "redirect:front?command=updateMember-result";
} else {
return "redirect:front?command=home";
}
}
}
/UpdateMemberResultController.java
package org.kosta.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UpdateMemberResultController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
request.setAttribute("url", "/member/update-result.jsp");
return "/template/login-layout.jsp";
}
}
[ 브라우저 화면 ]
> Home (home.jsp)
> 1. 회원 검색 폼
> 1-1. 회원 검색 : 존재하는 아이디 검색했을 때, (findbyid-ok.jsp)
> 1-2. 회원 검색 :존재하지 않는 아이디 검색했을 때, (findbyid-fail.jsp)
> 2-1. 회원 가입 폼
>2-2. 회원 가입 성공 결과
> 3-1. 로그인 성공 시,
> 3-2. 로그인 실패 시 -> index.jsp
> 4-1. 회원 정보 수정 폼
> 4-2. 회원 정보 수정 후
'Java Web Programming > 4. JSP' 카테고리의 다른 글
[JSP] 장바구니 웹 어플리케이션 (세션 이용) (0) | 2020.09.23 |
---|---|
[JSP] 회원관리 웹 어플리케이션 3 (layout-한가지로, home에 기본 main화면 제공) + (로그인, 로그아웃, 회원가입, (2) | 2020.09.22 |
[JSP] 회원 관리 웹 어플리케이션 (EL/JSTL 적용, 웹 프로그램 경로, BootStrap + Model2 설계) (0) | 2020.09.18 |
[JSP] EL / JSTL 표현식 한 방에 정리 ! (문법과 사용방법) (3) | 2020.09.16 |
[JSP] Semi-Project | Model2 MVC 기반 고객관리 웹어플리케이션 (회원가입, 로그인) (0) | 2020.09.16 |