[MVC 2-1] 회원가입 및 로그인(Model-2)

임승현·2023년 1월 17일
0

MVC

목록 보기
2/27

🌈STEP_1 DAO 클래스 생성

※ DTO는 Model-1 사용
※ 기존 DAO에서 catch 제거 (throws를 써서 에러 떠넘기기)

📃UserinfoModelTwoDAO.java

package xyz.itwill.dao;
//
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//
import xyz.itwill.dto.UserinfoDTO;
//
public class UserinfoModelTwoDAO extends JdbcDAO {
	private static UserinfoModelTwoDAO _dao;
	//
	private UserinfoModelTwoDAO() {
		// TODO Auto-generated constructor stub
	}
	//
	static {
		_dao=new UserinfoModelTwoDAO();		
	}
	//
	public static UserinfoModelTwoDAO getDAO() {
		return _dao;
	}
	//
	public int insertUserinfo(UserinfoDTO userinfo) throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		try {
			con=getConnection();
			//
			String sql="insert into userinfo values(?,?,?,?,?)";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, userinfo.getUserid());
			pstmt.setString(2, userinfo.getPassword());
			pstmt.setString(3, userinfo.getName());
			pstmt.setString(4, userinfo.getEmail());
			pstmt.setInt(5, userinfo.getStatus());
			//
			rows=pstmt.executeUpdate();
		} finally {
			close(con, pstmt);
		}
		return rows;
	}
	//
	public int updateUserinfo(UserinfoDTO userinfo) throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		try {
			con=getConnection();
			//
			String sql="update userinfo set password=?,name=?,email=?,status=? where userid=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, userinfo.getPassword());
			pstmt.setString(2, userinfo.getName());
			pstmt.setString(3, userinfo.getEmail());
			pstmt.setInt(4, userinfo.getStatus());
			pstmt.setString(5, userinfo.getUserid());
			//
			rows=pstmt.executeUpdate();
		} finally {
			close(con, pstmt);
		}
		return rows;
	}
	//
	public int deleteUserinfo(String userid) throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		try {
			con=getConnection();
			//
			String sql="delete from userinfo where userid=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, userid);
			//
			rows=pstmt.executeUpdate();
		} finally {
			close(con, pstmt);
		}
		return rows;
	}
	//
	public UserinfoDTO selectUserinfo(String userid) throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		UserinfoDTO userinfo=null;
		try {
			con=getConnection();
			//
			String sql="select * from userinfo where userid=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, userid);
			//
			rs=pstmt.executeQuery();
			//
			if(rs.next()) {
				userinfo=new UserinfoDTO();
				userinfo.setUserid(rs.getString("userid"));
				userinfo.setPassword(rs.getString("password"));
				userinfo.setName(rs.getString("name"));
				userinfo.setEmail(rs.getString("email"));
				userinfo.setStatus(rs.getInt("status"));
			}
		} finally {
			close(con, pstmt, rs);
		}
		return userinfo;
	}
	//
	public List<UserinfoDTO> selectUserinfoList() throws SQLException {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		List<UserinfoDTO> userinfoList=new ArrayList<>();
		try {
			con=getConnection();
			//
			String sql="select * from userinfo order by userid";
			pstmt=con.prepareStatement(sql);
			//
			rs=pstmt.executeQuery();
			//
			while(rs.next()) {
				UserinfoDTO userinfo=new UserinfoDTO();
				userinfo.setUserid(rs.getString("userid"));
				userinfo.setPassword(rs.getString("password"));
				userinfo.setName(rs.getString("name"));
				userinfo.setEmail(rs.getString("email"));
				userinfo.setStatus(rs.getInt("status"));
				userinfoList.add(userinfo);
			}
		} finally {
			close(con, pstmt, rs);
		}
		return userinfoList;
	}
}

🌈STEP_2 Service 클래스 생성

※ xyz.itwill.service 패키지 생성
※ UserinfoService.java 생성

📌Service 클래스

: 모델(Model) 클래스의 요청 처리 메소드에게 데이터베이스 관련 처리 기능을 제공하기 위한 클래스 - 단위 프로그램(모듈 프로그램) : 컴퍼넌트(Component)
→ 다수의 DAO 클래스의 메소드를 호출하여 필요한 기능을 제공하기 위한 메소드 작성 - 모듈화
→ 데이터베이스 관련 기능 구현시 발생되는 모든 문제에 대한 인위적 예외 발생

📃UserinfoService

package xyz.itwill.service;
//
import java.sql.SQLException;
import java.util.List;
//
import xyz.itwill.dao.UserinfoModelTwoDAO;
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.exception.AuthFailException;
import xyz.itwill.exception.ExistsUserinfoException;
import xyz.itwill.exception.UserinfoNotFoundException;
//
//Service 클래스 : 모델(Model) 클래스의 요청 처리 메소드에게 데이터베이스 관련 처리 기능을 제공하기 위한 클래스 - 단위 프로그램(모듈 프로그램) : 컴퍼넌트(Component)
//→ 다수의 DAO 클래스의 메소드를 호출하여 필요한 기능을 제공하기 위한 메소드 작성 - 모듈화
//→ 데이터베이스 관련 기능 구현시 발생되는 모든 문제에 대한 인위적 예외 발생
public class UserinfoService {
	private static UserinfoService _servide;
	//
	public UserinfoService() {
		// TODO Auto-generated constructor stub
	}
	//
	static {
		_servide=new UserinfoService();
	}
	//
	public static UserinfoService getService() {
		return _servide;
	}
	//
	//회원정보를 전달받아 USERINFO 테이블에 삽입하는 메소드
	//→ 전달받은 회원정보의 아이디가 USERINFO 테이블에 저장된 기존 회원정보의 아이디와 중복될 경우 인위적 예외 발생
	public void addUserinfo(UserinfoDTO userinfo) throws SQLException, ExistsUserinfoException {
		if(UserinfoModelTwoDAO.getDAO().selectUserinfo(userinfo.getUserid())!=null) {//아이디가 중복될 경우
			//인위적 예외 발생 → 예외 클래스를 잡는 패키지 생성 xyz.itwill.exception → ExistsUserinfoException.java 생성
			//예외가 발생될 경우 아래에 작성된 명령 미실행
			throw new ExistsUserinfoException("이미 사용중인 아이디를 등록 하였습니다.");//에러는 떠넘기기
		}
		UserinfoModelTwoDAO.getDAO().insertUserinfo(userinfo);//SQLException 에러는 Model이 처리할거
	}
	//
	//회원정보를 전달받아 USERINFO 테이블에 저장된 회원정보를 변경하는 메소드
	//→ 전달받은 회원정보가 USERINFO 테이블에 없는 경우 인위적 예외 발생
	public void modifyUserinfo(UserinfoDTO userinfo) throws SQLException, UserinfoNotFoundException {
		if(UserinfoModelTwoDAO.getDAO().selectUserinfo(userinfo.getUserid())==null) {//검색된 회원이 없다면 
			//인위적 예외 발생 → 예외 클래스를 잡는 패키지 xyz.itwill.exception → UserinfoNotFoundException.java 생성
			throw new UserinfoNotFoundException("회원정보가 존재하지 않습니다.");//에러는 떠넘기기
		}
		UserinfoModelTwoDAO.getDAO().updateUserinfo(userinfo);//SQL SQLException 떠넘기기
	}
	//
	//아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 삭제하는 메소드
	//→ 전달받은 아이디의 회원정보가 USERINFO 테이블에 없는 경우 인위적 예외 발생
	public void removeUserinfo(String userid) throws SQLException ,UserinfoNotFoundException {
		if(UserinfoModelTwoDAO.getDAO().selectUserinfo(userid)==null) {
			throw new UserinfoNotFoundException("회원정보가 존재하지 않습니다.");//에러는 떠넘기기
		}
		UserinfoModelTwoDAO.getDAO().deleteUserinfo(userid);
	}
	//
	//아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 검색하여 반환하는 메소드
	//→ 전달받은 아이디의 회원정보가 USERINFO 테이블에 없는 경우 인위적 예외 발생
	public UserinfoDTO getUserinfo(String userid) throws SQLException ,UserinfoNotFoundException {
		if(UserinfoModelTwoDAO.getDAO().selectUserinfo(userid)==null) {
			throw new UserinfoNotFoundException("회원정보가 존재하지 않습니다.");//에러는 떠넘기기
		}
		return UserinfoModelTwoDAO.getDAO().selectUserinfo(userid);
	}
	//
	//USERINFO 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드
	public List<UserinfoDTO> getUserinfoList() throws SQLException {
		return UserinfoModelTwoDAO.getDAO().selectUserinfoList();
	}
	//
	//아이디와 비밀번호를 전달받아 인증 처리하는 메소드
	//→ 인증 실패시 인위적 예외 발생 - 예외가 발생되지 않은 경우 인증 성공
	public void auth(String userid, String password) throws SQLException ,AuthFailException {
		UserinfoDTO userinfo=UserinfoModelTwoDAO.getDAO().selectUserinfo(userid);
		if(userinfo==null) {//아이디 인증 실패 → 예외 클래스를 잡는 패키지 생성 xyz.itwill.exception → AuthFailException.java 생성
			throw new AuthFailException("입력된 아이디가 존재하지 않습니다.");
		}
		if(!userinfo.getPassword().equals(password)) {//비밀번호 인증 실패
			throw new AuthFailException("입력된 아이디가 잘못 되었거나 비밀번호가 맞지 않습니다.");
		}
	}
}

※ xyz.itwill.exception 패키지 생성

📢회원정보(아이디)가 중복될 경우 발생될 예외를 표현하기 위한 클래스

→ 예외 클래스는 반드시 Exception 클래스를 상속받아 작성

📃ExistsUserinfoException.java

package xyz.itwill.exception;
//
//회원정보(아이디)가 중복될 경우 발생될 예외를 표현하기 위한 클래스
//→ 예외 클래스는 반드시 Exception 클래스를 상속받아 작성
public class ExistsUserinfoException extends Exception {//serialVersionUID 만들어서 에러 제거
	private static final long serialVersionUID = 1L;
	//
	public ExistsUserinfoException() {
		// TODO Auto-generated constructor stub
	}
	//
	public ExistsUserinfoException(String message) {
		super(message);
	}
}

📢회원정보를 찾을 수 없을 경우 발생될 예외를 표현하기 위한 클래스

📃UserinfoNotFoundException.java

package xyz.itwill.exception;
//
//회원정보를 찾을 수 없을 경우 발생될 예외를 표현하기 위한 클래스
public class UserinfoNotFoundException extends Exception {
	private static final long serialVersionUID = 1L;
	//
	public UserinfoNotFoundException() {
		// TODO Auto-generated constructor stub
	}
	//
	public UserinfoNotFoundException(String message) {
		super(message);
	}
}

📢인증에 실패한 경우 발생될 예외를 표현하기 위한 클래스

📃AuthFailException.java

package xyz.itwill.exception;
//
//인증에 실패한 경우 발생될 예외를 표현하기 위한 클래스
public class AuthFailException extends Exception {
	private static final long serialVersionUID = 1L;
	//
	public AuthFailException() {
		// TODO Auto-generated constructor stub
	}
	//
	public AuthFailException(String message) {
		super(message);
	}
}

🌈STEP_3 Controller 생성

※ xyz.itwill.mvc 패키지 생성
※ ControllerServlet.java 생성

📌컨트롤러(Controller - Servlet)

: 클라이언트의 모든 요청을 받아 모델(Model - Class)의 요청 처리 메소드를 호출하여 요청을 처리하고 처리 결과를 뷰(View - JSP)로 전달받아 응답되도록 제어하는 웹프로그램

📃ControllerServlet.java

package xyz.itwill.mvc;
//
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
//
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//컨트롤러(Controller - Servlet) : 클라이언트의 모든 요청을 모델(Model - Class)의 요청 처리 메소드를
//호출하여 요청을 처리하고 처리결과를 뷰(View - JSP)로 전달하여 응답되도록 제어하는 웹프로그램
//
//1.클라이언트의 모든  요청을 받을 수 있도록 서블릿을 설정하여 단일 진입점의 기능 구현
// → Front Controller Pattern
//@WebServlet("URL") : 서블릿 클래스를 웹프로그램(서블릿)으로 등록하고 요청 URL 주소를 매핑하는 어노테이션
//→ 매핑 설정될 URL 주소에 패턴문자(* : 전체 또는 ? : 문자 하나)를 사용하여 URL 패턴 등록 가능  
//→ @WebServlet("*.do") : 클라이언트가 [XXX.do] 형식의 URL 주소로 요청한 경우 서블릿 실행
//→ @WebServlet 어노테이션 대신 [web.xml] 파일에서 서블릿 클래스를 웹프로그램(서블릿)으로
//등록하고 URL 주소 매핑 처리
public class ControllerServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	//
	//요청정보(Key - String)와 모델 객체(Value - Action)를 하나의 요소(Entry)로 묶어 여러개 저장할 Map 객체의 필드
	//→ Map 객체를 이용하여 요청정보(Key)로 모델 객체(Value)를 빠르게 제공받기 위해 사용
	private Map<String, Action> actionMap;//필드 생성
	//
	//클라이언트 최초 요청에 의해 서블릿 객체가 생성된 후 가장 먼저 자동으로 1번만 호출되는 메소드
	//→ 서블릿 객체의 초기화 작업을 위해 오버라이드 선언
	@Override
	public void init(ServletConfig config) throws ServletException {
		//System.out.println("ControllerServlet 클래스의 init() 메소드 호출");
		//
		actionMap=new HashMap<String, Action>();
		//
		/*
		//properties 파일 생성해서 저장
		//Map 객체에 엔트리(Entry - Key : 요청정보, Value : 모델 객체) 추가
		actionMap.put("/loginForm.do", new LoginFormModel());
		actionMap.put("/login.do", new LoginModel());
		actionMap.put("/logout.do", new LogoutModel());
		actionMap.put("/writeForm.do", new WriteFormModel());
		actionMap.put("/write.do", new WriteModel());
		actionMap.put("/list.do", new ListModel());
		actionMap.put("/view.do", new ViewModel());
		actionMap.put("/modifyForm.do", new ModifyFormModel());
		actionMap.put("/modify.do", new ModifyModel());
		actionMap.put("/remove.do", new RemoveModel());
		actionMap.put("/error.do", new ErrorModel());
		*/
		//
		//Properties 파일에 요청정보와 모델 클래스를 저장하고 파일을 읽어 Map 객체의 엔트리 추가
		//→ 유지보수의 효율성 증가 - 컨트롤러를 변경하지 않고 Properties 파일만 변경하여 요청정보와 모델 객체 변경 가능
		//Properties 파일(XXX.properties) : 프로그램 실행에 필요한 값을 제공하기 위한 텍스트 파일
		//
		//Properties 파일의 정보를 저장하기 위한 Properties 객체 생성
		Properties properties=new Properties();
		//
		//ServletConfig.getInitParameter(String name) : [web.xml] 파일에서 init-param 엘리먼트로 제공되는 값을 읽어와 반환하는 메소드		
		String configFile=config.getInitParameter("configFile");
		//System.out.println("configFile = "+configFile);
		//
		//Properties 파일의 시스템 경로를 반환받아 저장
		//String configFilePath=config.getServletContext().getRealPath("/WEB-INF/model.propeties");
		String configFilePath=config.getServletContext().getRealPath(configFile);
		//System.out.println("configFilePath = "+configFilePath);
		//
		try {
			//Properties 파일에 대한 입력스트림을 생성하여 저장
			FileInputStream in=new FileInputStream(configFilePath);
			//
			//입력스트림을 사용하여 Properties 파일의 내용을 읽어 Properties 객체에 엔트리로 저장
			properties.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
		//
		//Properties 객체의 모든 키(Key)를 반환받아 반복 처리
		//Properties.keySet() : Properties 객체에 저장된 모든 엔트리의 키(Key)를 Set 객체로 반환하는 메소드
		for(Object key:properties.keySet()) {//Set 객체로부터 요소를 하나씩 제공받아 반복 처리
			//Properties 객체에 저장된 엔트리의 키(Key) - 요청정보
			String actionCommand=(String)key;
			//
			//Properties 객체에 저장된 엔트리의 값(Value) - 모델 클래스
			String actionClass=(String)properties.get(key);
			//
			try {
				//모델 클래스를 이용하여 모델 객체 생성 - 리플렉션 기능 사용
				//리플렉션(Reflection) : 프로그램 실행시 클래스(Clazz)를 읽어 객체를 생성하고 객체의 필드 또는 메소드에 접근하도록 제공하는 기능
				//Class.forName(String className) : 문자열로 표현된 클래스를 전달받아 클래스를 읽어 메모리에 
				//저장하고 Class 객체(Clazz)를 반환하는 메소드 - ClassNotFoundException 발생
				//Class.getDeclaredConstructor() : 메모리에 저장된 클래스(Class 객체)의 생성자가 저장된 Constructor 객체를 반환하는 메소드
				//Constructor.newInstance() : Constructor 객체에 저장된 생성자를 이용하여 Object 타입의 객체를 생성하여 반환하는 메소드
				Action actionObject=(Action)Class
					.forName(actionClass).getDeclaredConstructor().newInstance();
				//
				//Map 객체에 엔트리(Entry - Key : 요청정보, Value : 모델 객체) 추가
				actionMap.put(actionCommand, actionObject);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	//
	//클라이언트의 요청을 처리하기 위한 자동 호출되는 메소드
	//→ 클라이언트가 서블릿(웹프로그램)을 요청할 때마다 서블릿 객체를 이용하여 반복적으로 호출
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//System.out.println("ControllerServlet 클래스의 service() 메소드 호출");
		//
		//2.클라이언트 요청 분석 : 요청 URL 주소 이용 - http://localhost:8000/mvc/XXX.do
		//HttpServletRequest.getRequestURI() : 요청 URL 주소에서 URI 주소를 반환하는 메소드 
		String requestURI=request.getRequestURI();
		//System.out.println("requestURI = "+requestURI);//requestURI = /mvc/XXX.do
		//
		//HttpServletRequest.getContextPath() : 요청 URL 주소에서 컨텍스트 경로를 반환하는 메소드 
		String contextPath=request.getContextPath();
		//System.out.println("contextPath = "+contextPath);//contextPath = /mvc
		//
		//클라이언트 요청에 대란 요청값을 반환받아 저장
		String command=requestURI.substring(contextPath.length());
		//System.out.println("command = "+command);//command = /XXX.do
		//
		//3.클라이언트 요청을 모델(Model)을 사용하여 처리하고 뷰(View) 관련 정보를 반환받아 저장
		//→ 모델 역활의 Java 클래스로 객체를 생성하여 요청 처리 메소드 호출
		//→ 하나의 요청에 대해 하나의 모델이 처리되도록 설정 - Command Controller Pattern
		//
		//회원관리 프로그램에서 클라이언트 요청에 대한 모델 객체가 매핑되도록 설계
		//→ 로그인정보 입력페이지(환영메세지 출력페이지) - /loginForm.do >> LoginFormModel Class
		//→ 로그인 처리페이지 - /login.do >> LoginModel Class
		//→ 로그아웃 처리페이지 - /logout.do >> LogoutModel Class
		//→ 회원정보 입력페이지 - /writeForm.do >> WriteFormModel Class
		//→ 회원정보 삽입페이지 - /write.do >> WriteModel Class
		//→ 회원목록 출력페이지 - /list.do >> ListModel Class
		//→ 회원정보 출력페이지 - /view.do >> ViewModel Class
		//→ 변경회원정보 입력페이지 - /modifyForm.do >> ModifyFormModel Class
		//→ 회원정보 변경페이지 - /modify.do >> ModifyModel Class
		//→ 회원정보 삭제페이지 - /remove.do >> RemoveModel Class
		//→ 에러메세지 출력페이지 - /error.do >> ErrorModel Class
		/*
		//모델 클래스가 상속받은 인터페이스를 이용하여 참조변수 선언
		//→ 참조변수에는 인터페이스를 상속받은 모든 자식클래스(모델)로 생성된 객체 저장 가능
		Action action=null;
		//
		if(command.equals("/loginForm.do")) {
			action=new LoginFormModel();
		} else if(command.equals("/login.do")) {
			action=new LoginModel();
		} else if(command.equals("/logout.do")) {
			action=new LogoutModel();
		} else if(command.equals("/writeForm.do")) {
			action=new WriteFormModel();
		} else if(command.equals("/write.do")) {
			action=new WriteModel();
		} else if(command.equals("/list.do")) {
			action=new ListModel();
		} else if(command.equals("/view.do")) {
			action=new ViewModel();
		} else if(command.equals("/modifyForm.do")) {
			action=new ModifyFormModel();
		} else if(command.equals("/modify.do")) {
			action=new ModifyModel();
		} else if(command.equals("/remove.do")) {
			action=new RemoveModel();
		} else if(command.equals("/error.do")) {
			action=new ErrorModel();
		} else {//요청에 대한 모델 클래스가 없는 경우
			action=new ErrorModel();
		}
		*/
		//
		//Map 객체에 저장된 엔트리에서 요청정보(Key)를 이용하여 모델 객체(Value)를 반환받아 저장
		//→ 메모리 효율 및 가독성 증가
		Action action=actionMap.get(command);
		if(action==null) {//참조변수에 요청에 대한 모델 객체가 저장되어 있지 않은 경우
			action=actionMap.get("/error.do");
		}
		//
		//인터페이스 참조변수를 이용하여 추상메소드를 호출하면 참조변수에 저장된 모델 객체에 오버라이드 선언된 요청 처리 메소드 호출 - 오버라이드에 의한 다형성
		//→ 요청 처리 메소드에 의해 요청 처리 후 응답 관련 정보가 저장된 ActionForward 
		//객체를 반환받아 저장
		ActionForward actionForward=action.execute(request, response);
		//
		//4.응답 관련 정보를 저장된 ActionForward 객체를 이용하여 응답 처리
		if(actionForward.isForward()) {//ActionForward 객체의 forward 필드값이 [true]인 경우 - 포워드 이동
			//컨트롤러에서 뷰(XXX.jsp)로 스레드를 이동하여 JSP 문서의 실행결과(HTML 문서)를 클라이언트에게 전달하여 응답
			request.getRequestDispatcher(actionForward.getPath()).forward(request, response);
		} else {//ActionForward 객체의 forward 필드값이 [false]인 경우 - 라다이렉트 이동
			//컨트롤러에서 클라이언트에게 요청 URL 주소(XXX.do)를 전달하여 재요청하도록 응답
			response.sendRedirect(actionForward.getPath());
		}
	}
}

📃web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>mvc</display-name>
  <!-- servlet : 서블릿 클래스를 웹프로그램(서블릿)으로 등록하기 위한 엘리먼트 -->
  <servlet>
  	<servlet-name>controller</servlet-name>
  	<servlet-class>xyz.itwill.mvc.ControllerServlet</servlet-class>
  	<!-- init-param : 서블릿 클래스에 필요한 값을 제공하기 위한 엘리먼트 -->
  	<init-param>
  		<param-name>configFile</param-name>
  		<param-value>/WEB-INF/model.properties</param-value>
  	</init-param>
  	<!-- load-on-startup : WAS 실행시 서블릿 클래스를 서블릿 객체로 생성하기 위한 엘리먼트 -->
  	<!-- → 클라이언트의 요청 없이 WAS 실행시 서블릿 객체를 미리 생성 - init() 메소드가 자동 호출되어 초기화 작업 -->
  	<!-- → 엘리먼트값은 0 이상의 정수값으로 설정하며 정수값이 작을수록 먼저 서블릿 객체로 생성 -->
  	<load-on-startup>1</load-on-startup>
  </servlet>
  <!-- servlet-mapping : 웹프로그램(서블릿)에 URL 패턴을 등록하기 위한 엘리먼트 -->
  <servlet-mapping>
  	<servlet-name>controller</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
</web-app>

🌈STEP_4 인터페이스 생성

※xyz.itwill.mvc 패키지에 Action.java 인터페이스 생성

📢모든 모델 역활의 클래스가 반드시 상속받아야 되는 인터페이스

→ 모델 클래스의 요청 처리 메소드에 대한 작성 규칙 제공
→ 컨트롤러 역활의 서블릿에서 모델 객체로 요청 처리 메소드를 쉽게 호출할 수 있으며 유지보수의 효율성 증가

📢요청 처리 메소드를 추상 메소드로(명령이 없는 메소드) 선언

→ 인터페이스를 상속받은 모든 자식클래스에서 반드시 추상 메소드를 오버라이드 선언
→ HttpServletReqest 객체와 HttpServletResponse 객체를 매개변수 전달받아 요청 처리하고 뷰 관련 정보를 ActionForward 객체로 반환하도록 작성
※(클라이언트의 요청을 처리하기위해서는 request,response가 무조건 필요)
→ 요청 처리 메소드에서 발생되는 ServletException과 IOException는 예외 전달

📃Action.java

package xyz.itwill.mvc;import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
//모든 모델 역활의 클래스가 반드시 상속받아야 되는 인터페이스
//→ 모델 클래스의 요청 처리 메소드에 대한 작성 규칙 제공
//→ 컨트롤러 역활의 서블릿에서 모델 객체로 요청 처리 메소드를 쉽게 호출할 수 있으며 유지보수의 효율성 증가
//요청 처리 메소드를 추상 메소드로(명령이 없는 메소드) 선언
//→ 인터페이스를 상속받은 모든 자식클래스에서 반드시 추상 메소드를 오버라이드 선언
//→ HttpServletReqest 객체와 HttpServletResponse 객체를 매개변수 전달받아 요청 처리하고 뷰 관련 정보를 ActionForward 객체로 반환하도록 작성 
//(클라이언트의 요청을 처리하기위해서는 request,response가 무조건 필요)
//→ 요청 처리 메소드에서 발생되는 ServletException과 IOException는 예외 전달
public interface Action {
	ActionForward execute(HttpServletRequest request, HttpServletResponse response)//ActionForward 클래스를 만들어야지 에러가 안생김
		throws ServletException,IOException;
}

📢응답 관련 정보(뷰 - View)를 저장하기 위한 클래스

📃ActionForward.java

package xyz.itwill.mvc;
//
//응답 관련 정보(뷰 - View)를 저장하기 위한 클래스
public class ActionForward {
	//이동 형식에 대한 정보를 저장하기 위한 필드
	//→ false : 리다이렉트 이동, true : 포워드 이동
	//리다이렉트 이동 : 클라이언트에게 요청 URL 주소(/XXX.do)를 전달하여 다시 요청하도록 응답 처리
	//→ 클라이언트 브라우저의 요청 URL 주소 변경
	//포워드 이동 : 서블릿(컨트롤러)에서 JSP(뷰)로 스레드를 이동하여 응답 처리
	//→ 클라이언트 브라우저의 요청 URL 주소 미변경
	private boolean forward;//필드 생성
	//
	//이동될 웹프로그램의 경로를 저장하기 위한 필드
	//→ 리다이렉트 이동 : /XXX.do, 포워드 이동 : /XXX.jsp
	private String path;//필드 생성
	//
	public ActionForward() {
		// TODO Auto-generated constructor stub
	}
	public boolean isForward() {
		return forward;
	}
	public void setForward(boolean forward) {
		this.forward = forward;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
}

🌈STPE_5 Error Model 생성

※ xyz.itwill.mvc 패키지에 ErrorModel.java 클래스 생성

📢클라이언트가 [/error.do]로 요청한 경우 실행될 모델 클래스

→ [user_error.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체를 반환

📃ErrorModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
//클라이언트가 [/error.do]로 요청한 경우 실행될 모델 클래스
//→ [user_error.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체를 반환
public class ErrorModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		actionForward.setForward(true);
		actionForward.setPath("/model_two/user_error.jsp");
		return actionForward;
	}
}

📃user_error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 에러메세지를 전달하는 JSP 문서 --%>
<%-- → [로그인 페이지 이동] 태그를 클릭한 경우 로그인 정보 입력페이지(loginForm.do)로 이동 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
<style type="text/css">
body {
	text-align: center;
}
.message {
	color: red;
	font-size: 1.5em;
}
</style>
</head>
<body>
	<h1>에러페이지</h1>
	<hr>
	<p class="message">프로그램 실행에 예기치 못한 오류가 발생 하였거나 비정상적 방법으로 프로그램을 요청하여 오류가 발생 하였습니다.</p>
	<button type="button" onclick="location.href='loginForm.do';">로그인 페이지 이동</button>
</body>
</html>

🌈STPE_6 LoginFormModel 생성

※ xyz.itwill.mvc 패키지에 LoginFormModel.java 클래스 생성

📢클라이언트가 [/loginForm.do]로 요청한 경우 실행될 모델 클래스

→ [user_login.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체 반환

📃LoginFormModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
//클라이언트가 [/loginForm.do]로 요청한 경우 실행될 모델 클래스
//→ [user_login.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체 반환
public class LoginFormModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		actionForward.setForward(true);
		actionForward.setPath("/model_two/user_login.jsp");
		return actionForward;
	}
}

📢비로그인 사용자인 경우 사용자로부터 로그인정보를 입력받기 위한 JSP 문서

→[로그인] 태그를 클릭한 경우 로그인 처리페이지(/login.do)로 이동 - 입력값 전달

📢로그인 사용자인 경우 환영메세지를 전달하는 JSP 문서

→ [회원목록] 태그를 클릭한 경우 회원목록 출력페이지(/list.do)로 이동
→ [로그아웃] 태그를 클릭한 경우 로그아웃 처리페이지(/logout.do)로 이동
→ [회원등록] 태그를 클릭한 경우 회원정보 입력페이지(/writeForm.do)로 이동 - 관리자에게만 적용

📃user_login.jsp

<%@page import="xyz.itwill.dto.UserinfoDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 비로그인 사용자인 경우 사용자로부터 로그인정보를 입력받기 위한 JSP 문서 --%>
<%-- →[로그인] 태그를 클릭한 경우 로그인 처리페이지(/login.do)로 이동 - 입력값 전달 --%>
<%-- 로그인 사용자인 경우 환영메세지를 전달하는 JSP 문서 --%>
<%-- → [회원목록] 태그를 클릭한 경우 회원목록 출력페이지(/list.do)로 이동 --%>
<%-- → [로그아웃] 태그를 클릭한 경우 로그아웃 처리페이지(/logout.do)로 이동 --%>
<%-- → [회원등록] 태그를 클릭한 경우 회원정보 입력페이지(/writeForm.do)로 이동 - 관리자에게만 적용 --%>
<%
	UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
	//
	String message=(String)request.getAttribute("message");
	if(message==null) {
		message="";
	} 
	//
	String userid=(String)session.getAttribute("userid");
	if(userid==null) {
		userid="";
	} 
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%-- 요청 웹프로그램(컨트롤러)의 URL 주소 경로와 응답 JSP 문서의 경로가 서로 다르므로 웹자원의 경로는 절대경로로 표현하는 것을 권장 --%>
<link rel=stylesheet href="<%=request.getContextPath() %>/model_two/css/user.css" type="text/css">
<script language="JavaScript">
function userLogin() {
	if ( f.userid.value == "" ) {
		alert("아이디를 입력하십시요.");
		f.userid.focus();
		return;
	} 
	if ( f.password.value == "" ) {
		alert("비밀번호를 입력하십시요.");
		f.password.focus();
		return;
	}	
	//
	f.action = "login.do";
	f.submit();
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td style="color: red;"><%=message %></td>			
	</tr>
	<tr>
	  <td width="20"></td>
	  <td>
  	  <!--contents-->
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>회원관리 - 로그인</b></td>
		  </tr>
	  </table>  
	  <br>
	 <% if(loginUserinfo==null) {//비로그인 사용자인 경우 %>	
	  <!-- login Form  -->
	  <form name="f" method="post">
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">사용자 아이디</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:150" name="userid" value="<%=userid%>">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">비밀번호</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="password" style="width:150" name="password">
			</td>
		  </tr>
	  </table>
	  </form>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
				<input type="button" value="로그인" onClick="userLogin();"> &nbsp;
			</td>
		  </tr>
	  </table>
	<% } else {//로그인 사용자인 경우 %>
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td align=center bgcolor="E6ECDE" height="22">
				<%=loginUserinfo.getName() %>님, 환영합니다.
			</td>
			</td>
		  </tr>
	  </table>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
				<button type="button" onclick="location.href='list.do';">회원목록</button>
				<button type="button" onclick="location.href='logout.do';">로그아웃</button>
				<% if(loginUserinfo.getStatus()==9) { %>
				<button type="button" onclick="location.href='writeForm.do';">회원등록</button>
				<% } %>
			</td>
		  </tr>
	  </table>
	<% } %>
	  </td>
	</tr>
</table>  
</body>
</html>

🌈STPE_7 LoginModel 생성

※ xyz.itwill.mvc 패키지에 LoginModel.java 클래스 생성

📢클라이언트가 [/login.do]로 요청한 경우 실행될 모델 클래스

→ 로그인 정보를 전달받아 USERINFO 테이블에 저장된 회원정보와 비교하여 인증 처리
→ 인증 성공 : 세션에 권한 관련 정보를 저장하고 [loginForm.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
→ 인증 실패 : : [user_login.jsp]로 포워드 이동하기 위한 정보가 ActionForward 객체 반환

📢객체 반환 - 에러메세지와 아이디를 속성값으로 저장하여 JSP 문서에 제공

📃LoginModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
import xyz.itwill.exception.AuthFailException;
import xyz.itwill.service.UserinfoService;
//
//클라이언트가 [/login.do]로 요청한 경우 실행될 모델 클래스
//→ 로그인 정보를 전달받아 USERINFO 테이블에 저장된 회원정보와 비교하여 인증 처리
//→ 인증 성공 : 세션에 권한 관련 정보를 저장하고 [loginForm.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
//→ 인증 실패 : : [user_login.jsp]로 포워드 이동하기 위한 정보가 ActionForward 객체 반환
//객체 반환 - 에러메세지와 아이디를 속성값으로 저장하여 JSP 문서에 제공 
public class LoginModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		//요청을 처리하면서 발생되는 모든 예외를 처리하기 위한 예외처리 기능 구현
		try {
			if(request.getMethod().equals("GET")) {//비정상적인 요청인 경우
				throw new Exception();//인위적인 예외 발생
			}
			//
			//전달값을 반환받아 저장
			String userid=request.getParameter("userid");
			String password=request.getParameter("password");
			//
			//모델 클래스의 요청 처리 메소드에서는 Service 객체로 메소드를 호출하여 데이터베이스 관련된 작업이 처리되도록 작성
			//
			//UserinfoService 클래스의 auth() 메소드를 호출하여 인증 처리
			//→ AuthFailException이 발생된 경우 인증 실패
			UserinfoService.getService().auth(userid, password);
			//
			//인증이 성공된 경우 세션의 권한 관련 정보(회원정보) 저장
			//→ 세션을 바인딩하여 HttpSession 객체를 반환받아 저장
			HttpSession session=request.getSession();
			//Session Scope : 동일한 세션을 사용하는 모든 웹프로그램에서 속성값을 반환받아 사용 가능
			//→ 웹브라우저가 종료되면 클라이언트에 바인딩된 세션은 자동으로 제거
			session.setAttribute("loginUserinfo", UserinfoService.getService().getUserinfo(userid));
			//
			actionForward.setForward(false);
			actionForward.setPath("loginForm.do");
		} catch (AuthFailException e) {
			//인증 실패에 의해 발생된 예외에 대한 처리 명령 작성
			//Request Scope : 스레드가 이동된 웹프로그램(JSP)에서만 속성값을 반환받아 사용 가능
			request.setAttribute("message", e.getMessage());
			request.setAttribute("userid", request.getParameter("userid"));
			actionForward.setForward(true);
			actionForward.setPath("/model_two/user_login.jsp");
		} catch (Exception e) {
			//모든 예외에 대한 처리 명령 작성
			//→ [error.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
			e.printStackTrace();//콘솔에 에러 출력
			//브라우저에 에러 출력
			actionForward.setForward(false);
			actionForward.setPath("error.do");
		}
		return actionForward;
	}
}

🌈STPE_8 LogoutModel 생성

※ xyz.itwill.mvc 패키지에 LogoutModel.java 클래스 생성

📢클라이언트가 [/logout.do]로 요청한 경우 실행될 모델 클래스

→ 로그아웃 처리
→ [loginForm.do]로 리다이렉트 이동하기 정보가 저장된 ActionForward 객체 반환

📃 LogoutModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
//클라이언트가 [/logout.do]로 요청한 경우 실행될 모델 클래스
// → 로그아웃 처리
// → [loginForm.do]로 리다이렉트 이동하기 정보가 저장된 ActionForward 객체 반환
public class LogoutModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		HttpSession session=request.getSession();
		//session.removeAttribute("loginUserinfo");
		session.invalidate();
		//
		ActionForward actionForward=new ActionForward();
		actionForward.setForward(false);
		actionForward.setPath("loginForm.do");
		return actionForward;
	}
}

🌈STPE_9 WriteFormModel 생성

※ xyz.itwill.mvc 패키지에 WriteFormModel.java 클래스 생성

📢클라이언트가 [/writeForm.do]로 요청한 경우 실행될 모델 클래스

→ 관리자만 요청 가능하도록 권한 설정
→ [user_write.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체 반환

📃 WriteFormModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
import xyz.itwill.dto.UserinfoDTO;
//
//클라이언트가 [/writeForm.do]로 요청한 경우 실행될 모델 클래스
// => 관리자만 요청 가능하도록 권한 설정
// => [user_write.jsp]로 포워드 이동하기 정보가 저장된 ActionForward 객체 반환
public class WriteFormModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		try {
			HttpSession session=request.getSession();
			UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
			//비로그인 사용자이거나 로그인 사용자가 관리자가 아닌 경우 - 비정상적인 요청
			if(loginUserinfo==null || loginUserinfo.getStatus()!=9) {
				throw new Exception();
			}
			//정상적인 요청
			actionForward.setForward(true);
			actionForward.setPath("/model_two/user_write.jsp");
		} catch (Exception e) {
			e.printStackTrace();
			actionForward.setForward(false);
			actionForward.setPath("error.do");
		}
		return actionForward;
	}
}

📌사용자로부터 회원정보를 입력받기 위한 JSP 문서 - 관리자만 요청 가능한 페이지

→ [회원등록] 태그를 클릭한 경우 회원정보 삽입페이지(write.do)로 이동 - 입력값 전달
→ [로그인] 태그를 클릭한 경우 로그인정보 입력페이지(loginForm.do)로 이동

📃user_write.jsp

<%@page import="xyz.itwill.dto.UserinfoDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 사용자로부터 회원정보를 입력받기 위한 JSP 문서 - 관리자만 요청 가능한 페이지 --%>
<%-- → [회원등록] 태그를 클릭한 경우 회원정보 삽입페이지(write.do)로 이동 - 입력값 전달 --%>
<%-- → [로그인] 태그를 클릭한 경우 로그인정보 입력페이지(loginForm.do)로 이동 --%>
<%
	String message=(String)request.getAttribute("message");
	if(message==null) {
		message="";
	}
	//
	UserinfoDTO userinfo=(UserinfoDTO)request.getAttribute("userinfo");
	if(userinfo==null) {
		userinfo=new UserinfoDTO();
		userinfo.setUserid("");
		userinfo.setPassword("");
		userinfo.setName("");
		userinfo.setEmail("");
		userinfo.setStatus(1);
	}
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<%=request.getContextPath() %>/model_two/css/user.css" type="text/css">
<script language="JavaScript">
function userCreate() {
	if ( f.userid.value == "" ) {
		alert("아이디를 입력하십시요.");
		f.userid.focus();
		return;
	} 
	if ( f.password.value == "" ) {
		alert("비밀번호를 입력하십시요.");
		f.password.focus();
		return;
	}
	if ( f.name.value == "" ) {
		alert("이름을 입력하십시요.");
		f.name.focus();
		return;
	}
	//
	f.action = "write.do";
	f.submit();
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td style="color: red;"><%=message %></td>			
	</tr>
	<tr>
	  <td width="20"></td>
	  <td>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>회원관리 - 회원등록</b></td>
		  </tr>
	  </table>  
	  <br>
	  <form name="f" method="post">
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">아이디</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:150" name="userid" value="<%=userinfo.getUserid()%>">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">비밀번호</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="password" style="width:150" name="password" value="<%=userinfo.getPassword()%>">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">이름</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="name" value="<%=userinfo.getName()%>">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">이메일</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="email" value="<%=userinfo.getEmail()%>">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">회원등급</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<select name="status">
					<option value="1" <% if(userinfo.getStatus()==1) { %> selected <% } %>>일반회원</option>
					<option value="9" <% if(userinfo.getStatus()==9) { %> selected <% } %>>관리자</option>
				</select>
			</td>
		  </tr>		  
	  </table>
	  </form>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
				<input type="button" value="회원등록" onClick="userCreate();">
				<input type="button" value="로그인" onClick="location.href='loginForm.do';">
			</td>
		  </tr>
	  </table>
	  </td>
	</tr>
</table>  
</body>
</html>

🌈STPE_10 WriteModel 생성

📢클라이언트가 [write.do]로 요청한 경우 실행될 모델 클래스

→ 회원정보를 전달받아 USERINFO 테이블에 삽입 처리
→ [loginForm.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환

📃WriteModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.exception.ExistsUserinfoException;
import xyz.itwill.service.UserinfoService;
//
//클라이언트가 [write.do]로 요청한 경우 실행될 모델 클래스
//→ 회원정보를 전달받아 USERINFO 테이블에 삽입 처리
//→ [loginForm.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
public class WriteModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		UserinfoDTO userinfo=null;
		try {
			if(request.getMethod().equals("GET")) {
				throw new Exception();
			}
			//
			request.setCharacterEncoding("utf-8");
			//
			String userid=request.getParameter("userid");
			String password=request.getParameter("password");
			String name=request.getParameter("name");
			String email=request.getParameter("email");
			int status=Integer.parseInt(request.getParameter("status"));
			//
			userinfo=new UserinfoDTO();
			userinfo.setUserid(userid);
			userinfo.setPassword(password);
			userinfo.setName(name);
			userinfo.setEmail(email);
			userinfo.setStatus(status);
			//
			//UserinfoService 클래스의 addUserinfo() 메소드 호출
			//→ 전달받은 아이디가 USERINFO 테이블에 저장된 기존 회원의 아이디와 중복될 경우 ExistsUserinfoException 발생
			UserinfoService.getService().addUserinfo(userinfo);
			actionForward.setForward(false);
			actionForward.setPath("loginForm.do");
		} catch (ExistsUserinfoException e) {
			//아이디가 중복될 경우 발생되는 예외에 대한 처리 명령 작성
			request.setAttribute("message", e.getMessage());
			request.setAttribute("userinfo", userinfo);//try 밖에다가 변수 선언해야 에러 안뜸
			actionForward.setForward(true);
			actionForward.setPath("/model_two/user_write.jsp");
		} catch (Exception e) {
			e.printStackTrace();//콘솔에 에러 출력
			actionForward.setForward(false);//브라우저에 에러 출력
			actionForward.setPath("error.do");//브라우저에 에러 출력
		}
		return actionForward;
	}
}

🌈STPE_11 ListModel 생성

📢클라이언트가 [list.do]로 요청한 경우 실행될 모델 클래스

→ 로그인 사용자만 요청 가능하도록 권한 설정
→ USERINFO 테이블에 저장된 모든 회원정보를 검색하여 request 속성값으로 저장
→ [user_list.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체 반환

📃ListModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.service.UserinfoService;
//클라이언트가 [list.do]로 요청한 경우 실행될 모델 클래스
//→ 로그인 사용자만 요청 가능하도록 권한 설정
//→ USERINFO 테이블에 저장된 모든 회원정보를 검색하여 request 속성값으로 저장
//→ [user_list.jsp]로 포워드 이동하기 위한 정보가 저장된 ActionForward 객체 반환
public class ListModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		try {
			//로그인 사용자만 요청 가능하도록
			HttpSession session=request.getSession();
			UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
			//비로그인 사용자인 경우 - 비정상적인 요청
			if(loginUserinfo==null) {
				throw new Exception();
			}
			//UserinfoService 클래스의 getUserinfoList() 메소드를 호출하여 반환된 회원목록을 포워드 이동될 JSP에서 사용하기 위해 request 속성값으로 저장
			request.setAttribute("userinfoList", UserinfoService.getService().getUserinfoList());
			//
			actionForward.setForward(true);
			actionForward.setPath("/model_two/user_list.jsp");
		} catch (Exception e) {
			e.printStackTrace();//콘솔에 에러 출력
			actionForward.setForward(false);//브라우저에 에러 출력
			actionForward.setPath("error.do");//브라우저에 에러 출력
		}
		return actionForward;
	}
}

📢request 속성값으로 제공된 회원목록을 전달하는 JSP 문서

→ 회원정보에서 [회원이름]을 클릭한 경우 회원정보 출력페이지(view.do)로 이동 - 아이디 전달
→ [회원등록] 태그를 클릭한 경우 회원정보 입력페이지(writeForm.do)로 이동 - 관리자에게만 제공
→ [로그아웃] 태그를 클릭한 경우 로그아웃 처리페이지(logout.do)로 이동

📃user_list.jsp

<%@page import="xyz.itwill.dao.UserinfoModelOneDAO"%>
<%@page import="java.util.List"%>
<%@page import="xyz.itwill.dto.UserinfoDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- request 속성값으로 제공된 회원목록을 전달하는 JSP 문서 --%>
<%-- → 회원정보에서 [회원이름]을 클릭한 경우 회원정보 출력페이지(view.do)로 이동 - 아이디 전달 --%>
<%-- → [회원등록] 태그를 클릭한 경우 회원정보 입력페이지(writeForm.do)로 이동 - 관리자에게만 제공 --%>
<%-- → [로그아웃] 태그를 클릭한 경우 로그아웃 처리페이지(logout.do)로 이동 --%>
<%
	UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
	//
	List<UserinfoDTO> userinfoList=(List<UserinfoDTO>)request.getAttribute("userinfoList");
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<%=request.getContextPath() %>/model_two/css/user.css" type="text/css">
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
<tr>
	<td width="20"></td>
	<td>
	  	<table width=590 border=0 cellpadding=0 cellspacing=0>
		  	<tr>
				<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>회원관리 - 회원목록</b></td>
		  	</tr>
	  	</table>  
	  	<br>
	  	<table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  	<tr>
				<td width=190 align=center bgcolor="E6ECDE" height="22">아이디</td>
				<td width=200 align=center bgcolor="E6ECDE">이름</td>
				<td width=200 align=center bgcolor="E6ECDE">이메일</td>
		  	</tr>
		  	<% for(UserinfoDTO userinfo:userinfoList) { %>
		  	<tr>
				<td width=190 align=center bgcolor="ffffff" height="20">
					<%=userinfo.getUserid() %>
				</td>
				<td width=200 align=center bgcolor="ffffff">
					<a href="view.do?userid=<%=userinfo.getUserid() %>" class="user">
						<%=userinfo.getName() %>
					</a>
				</td>
				<td width=200 align=center bgcolor="ffffff">
					<% if(userinfo.getEmail()!=null) { %>
						<%=userinfo.getEmail() %>
					<% } %>
				</td>
		  	</tr>
		  	<% } %>
	  	</table>
		<br>
	  	<table border="0" cellpadding="0" cellspacing="1" width="590">
			<tr>
				<td align="right">
					<% if(loginUserinfo.getStatus()==9) { %>
					<input type="button" value="회원등록" onclick="location.href='writeForm.do';"/>
					<% } %>
					<input type="button" value="로그아웃" onclick="location.href='logout.do';"/>
				</td>
			</tr>
		</table>		
	</td>
</tr>
</table>  
</body>
</html>

🌈STPE_12 ViewModel 생성

📢클라이언트가 [/view.do]로 요청한 경우 실행될 모델 클래스

→ 로그인 사용자만 요청 가능하도록 권한 설정
→ 아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 검색하여 request 속성값으로 저장
→ [user_view.jsp]로 포워드 이동하기 정보가 저장된 ActionForward 객체 반환

📃ViewModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.service.UserinfoService;
//
//클라이언트가 [/view.do]로 요청한 경우 실행될 모델 클래스
//→ 로그인 사용자만 요청 가능하도록 권한 설정
//→ 아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 검색하여 request 속성값으로 저장
//→ [user_view.jsp]로 포워드 이동하기 정보가 저장된 ActionForward 객체 반환
public class ViewModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		try {
			HttpSession session=request.getSession();
			UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
			//비로그인 사용자인 경우 - 비정상적인 요청
			if(loginUserinfo==null) {
				throw new Exception();
			}
			//
			if(request.getParameter("userid")==null) {
				throw new Exception();
			}
			//
			String userid=request.getParameter("userid");
			//
			//UserinfoService 클래스의 getUserinfo() 메소드를 호출하여 반환된 회원정보를
			//포워드 이동될 JSP에서 사용하기 위해 request 속성값으로 저장
			//→ UserinfoService 클래스의 getUserinfo() 메소드에서 해당 아이디의 회원정보가
			//검색되지 않은 경우 UserinfoNotFoundException 발생 >> 에러페이지 이동
			request.setAttribute("userinfo", UserinfoService.getService().getUserinfo(userid));
			//
			actionForward.setForward(true);
			actionForward.setPath("/model_two/user_view.jsp");
		} catch (Exception e) {
			e.printStackTrace();
			actionForward.setForward(false);
			actionForward.setPath("error.do");
		}
		return actionForward;
	}
}

📢request 속성값으로 제공된 회원정보를 전달하는 JSP 문서

→ [수정] 태그를 클릭한 경우 변경회원정보 입력페이지(modifyForm.do)로 이동 - 아이디 전달
→ [삭제] 태그를 클릭한 경우 회원정보 삭제페이지(remove.do)로 이동 - 아이디 전달
→ [목록] 태그를 클릭한 경우 회원목록 출력페이지(list.do)로 이동
→ [수정] 태그와 [삭제] 태그는 관리자에게만 제공

📃user_view.jsp

<%@page import="xyz.itwill.dto.UserinfoDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- request 속성값으로 제공된 회원정보를 전달하는 JSP 문서 --%>
<%-- → [수정] 태그를 클릭한 경우 변경회원정보 입력페이지(modifyForm.do)로 이동 - 아이디 전달 --%>
<%-- → [삭제] 태그를 클릭한 경우 회원정보 삭제페이지(remove.do)로 이동 - 아이디 전달 --%>
<%-- → [목록] 태그를 클릭한 경우 회원목록 출력페이지(list.do)로 이동 --%>
<%-- → [수정] 태그와 [삭제] 태그는 관리자에게만 제공 --%> 
<%
	UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
	//
	UserinfoDTO userinfo=(UserinfoDTO)request.getAttribute("userinfo");
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<%=request.getContextPath() %>/model_two/css/user.css" type="text/css">
<script language="JavaScript">
function userRemove(userid) {
	if (confirm("정말로 삭제 하시겠습니까?") ) {
		location.href='remove.do?userid='+userid;
	}
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>회원관리 - 회원정보</b></td>
		  </tr>
	  </table>  
	  <br>
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">아이디</td>
			<td width=490 bgcolor="ffffff"  style="padding-left:10px;">
				<%=userinfo.getUserid() %>
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">이름</td>
			<td width=490 bgcolor="ffffff"  style="padding-left:10px;">
				<%=userinfo.getName() %>
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">이메일</td>
			<td width=490 bgcolor="ffffff"  style="padding-left:10px;">
				<% if(userinfo.getEmail()!=null) { %>
					<%=userinfo.getEmail() %>
				<% } %>
			</td>
		  </tr>		  
	  </table>
	  <br> 
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
			<% if(loginUserinfo.getStatus()==9) { %>
			<input type="button" value="수정" onClick="location.href='modifyForm.do?userid=<%=userinfo.getUserid()%>';">
			<input type="button" value="삭제" onClick="userRemove('<%=userinfo.getUserid()%>');">
			<% } %>
			<input type="button" value="목록" onClick="location.href='list.do';"> 
			</td>
		  </tr>
	  </table>
	  </td>
	</tr>
</table>  
</body>
</html>

🌈STPE_13 ModifyFormModel 생성

📌클라이언트가 [/modifyForm.do]로 요청한 경우 실행될 모델 클래스

→ 관리자만 요청 가능하도록 권한 설정
→ 아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 검색하여 request 속성값으로 저장
→ [user_modify.jsp]로 포워드 이동하기 정보가 저장된 ActionForward 객체 반환

📃ModifyFormModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.service.UserinfoService;
//
//클라이언트가 [/modifyForm.do]로 요청한 경우 실행될 모델 클래스
//→ 관리자만 요청 가능하도록 권한 설정
//→ 아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 검색하여 request 속성값으로 저장
//→ [user_modify.jsp]로 포워드 이동하기 정보가 저장된 ActionForward 객체 반환
public class ModifyFormModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		try {
			HttpSession session=request.getSession();
			UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
			//비로그인 사용자이거나 로그인 사용자가 관리자가 아닌 경우 - 비정상적인 요청
			if(loginUserinfo==null || loginUserinfo.getStatus()!=9) {
				throw new Exception();
			}
			//
			if(request.getParameter("userid")==null) {
				throw new Exception();
			}
			//
			String userid=request.getParameter("userid");
			//
			//UserinfoService 클래스의 getUserinfo() 메소드를 호출하여 반환된 회원정보를
			//포워드 이동될 JSP에서 사용하기 위해 request 속성값으로 저장
			//→ UserinfoService 클래스의 getUserinfo() 메소드에서 해당 아이디의 회원정보가
			//검색되지 않은 경우 UserinfoNotFoundException 발생 >> 에러페이지 이동
			request.setAttribute("userinfo", UserinfoService.getService().getUserinfo(userid));
			//
			actionForward.setForward(true);
			actionForward.setPath("/model_two/user_modify.jsp");
		} catch (Exception e) {
			e.printStackTrace();
			actionForward.setForward(false);
			actionForward.setPath("error.do");
		}
		return actionForward;
	}
}

📢request 속성값으로 제공된 회원정보를 입력태그의 초기값으로 설정하고 변경할 회원정보를 사용자로부터 입력받기 위한 JSP 문서

→ [수정] 태그를 클릭한 경우 회원정보 변경페이지(modify.do)로 이동 - 입력값 전달
→ [목록] 태그를 클릭한 경우 회원목록 출력페이지(list.do)로 이동

📃user_modify.jsp

<%@page import="xyz.itwill.dao.UserinfoModelOneDAO"%>
<%@page import="xyz.itwill.dto.UserinfoDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- request 속성값으로 제공된 회원정보를 입력태그의 초기값으로 설정하고 변경할 회원정보를 사용자로부터 입력받기 위한 JSP 문서 --%>
<%-- → [수정] 태그를 클릭한 경우 회원정보 변경페이지(modify.do)로 이동 - 입력값 전달 --%>
<%-- → [목록] 태그를 클릭한 경우 회원목록 출력페이지(list.do)로 이동 --%>
<%
	UserinfoDTO userinfo=(UserinfoDTO)request.getAttribute("userinfo");
%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<%=request.getContextPath() %>/model_two/css/user.css" type="text/css">
<script language="JavaScript">
function userModify() {
	if ( f.name.value == "" ) {
		alert("이름을 입력하십시요.");
		f.name.focus();
		return false;
	}
	f.action = "modify.do";
	f.submit();
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>회원관리 - 회원정보수정</b></td>
		  </tr>
	  </table>  
	  <br>
	  <form name="f" method="post">
	  <input type="hidden" name="userid" value="<%=userinfo.getUserid()%>">
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">아이디</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<%=userinfo.getUserid()%>
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">비밀번호</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="password" style="width:150" name="password">
				<span style="color: red;">** 비밀번호를 변경하지 않을 경우 입력하지 마세요. **</span>
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">이름</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="name" value="<%=userinfo.getName()%>">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">이메일 주소</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<% if(userinfo.getEmail()!=null) { %>
					<input type="text" style="width:240" name="email" value="<%=userinfo.getEmail()%>">
				<% } else { %>
					<input type="text" style="width:240" name="email">
				<% } %>
			</td>
		  </tr>		  
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">회원등급</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<select name="status">
					<option value="1" <% if(userinfo.getStatus()==1) { %> selected <% } %>>일반회원</option>
					<option value="9" <% if(userinfo.getStatus()==9) { %> selected <% } %>>관리자</option>
				</select>
			</td>
		  </tr>	
	  </table>
	  </form>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
			<input type="button" value="수정" onClick="userModify();">
			<input type="button" value="목록" onClick="location.href='list.do';">
			</td>
		  </tr>
	  </table>
	  </td>
	</tr>
</table>  
</body>
</html>

🌈STPE_14 ModifyModel 생성

📢클라이언트가 [/modify.do]로 요청한 경우 실행될 모델 클래스

→ 회원정보를 전달받아 USERINFO 테이블에 저장된 회원정보 변경 처리
→ [view.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환 - 아이디 전달

📃ModifyModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.service.UserinfoService;
//클라이언트가 [/modify.do]로 요청한 경우 실행될 모델 클래스
//→ 회원정보를 전달받아 USERINFO 테이블에 저장된 회원정보 변경 처리
//→ [view.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환 - 아이디 전달
public class ModifyModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		try {
			if(request.getMethod().equals("GET")) {
				throw new Exception();
			}
			//
			request.setCharacterEncoding("utf-8");
			//
			String userid=request.getParameter("userid");
			String password=request.getParameter("password");
			String name=request.getParameter("name");
			String email=request.getParameter("email");
			int status=Integer.parseInt(request.getParameter("status"));
			//
			UserinfoDTO userinfo=new UserinfoDTO();
			userinfo.setUserid(userid);
			if(password==null || password.equals("")) {
				//비밀번호 전달값이 없는 경우 - 기존 회원의 비밀번호 사용
				userinfo.setPassword(UserinfoService.getService().getUserinfo(userid).getPassword());
			} else {
				//비밀번호 전달값이 있는 경우 - 입력된 비밀번호 사용
				userinfo.setPassword(password);
			}
			userinfo.setName(name);
			userinfo.setEmail(email);
			userinfo.setStatus(status);
			//
			//UserinfoService 클래스의 modifyUserinfo() 메소드 호출
			UserinfoService.getService().modifyUserinfo(userinfo);
			//
			actionForward.setForward(false);
			actionForward.setPath("view.do?userid="+userid);
		} catch (Exception e) {
			e.printStackTrace();
			actionForward.setForward(false);
			actionForward.setPath("error.do");
		}
		return actionForward;
	}
}

🌈STPE_15 RemoveModel 생성

📢클라이언트가 [/remove.do]로 요청한 경우 실행될 모델 클래스

→ 관리자만 요청 가능하도록 권한 설정
→ 아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보 삭제 처리
→ [list.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
→ 관리자가 자신 계정의 회원정보를 삭제한 경우 [logout.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환

📃RemoveModel.java

package xyz.itwill.mvc;
//
import java.io.IOException;
//
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//
import xyz.itwill.dto.UserinfoDTO;
import xyz.itwill.service.UserinfoService;
//
//클라이언트가 [/remove.do]로 요청한 경우 실행될 모델 클래스
//→ 관리자만 요청 가능하도록 권한 설정
//→ 아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보 삭제 처리
//→ [list.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
//→ 관리자가 자신 계정의 회원정보를 삭제한 경우 [logout.do]로 리다이렉트 이동하기 위한 정보가 저장된 ActionForward 객체 반환
public class RemoveModel implements Action {
	@Override
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ActionForward actionForward=new ActionForward();
		try {
			HttpSession session=request.getSession();
			UserinfoDTO loginUserinfo=(UserinfoDTO)session.getAttribute("loginUserinfo");
			//비로그인 사용자이거나 로그인 사용자가 관리자가 아닌 경우 - 비정상적인 요청
			if(loginUserinfo==null || loginUserinfo.getStatus()!=9) {
				throw new Exception();
			}
			//
			if(request.getParameter("userid")==null) {
				throw new Exception();
			}
			//
			String userid=request.getParameter("userid");
			//
			//UserinfoService 클래스의 removeUserinfo() 메소드 호출
			UserinfoService.getService().removeUserinfo(userid);
			//
			actionForward.setForward(false);
			if(loginUserinfo.getUserid().equals(userid)) {
				actionForward.setPath("logout.do");
			} else {
				actionForward.setPath("list.do");
			}
		} catch (Exception e) {
			e.printStackTrace();
			actionForward.setForward(false);
			actionForward.setPath("error.do");
		}
		return actionForward;
	}
}

🌈STPE_16 properties를 이용해 프로그램 작성

※ControllerServlet.java 수정
※web.xml 수정

⭕properties 파일 만드는법
1. WEB-INF 우클릭 → New → File

2. File name : model.properties 작성 후 Finish

📃model.properties

#Command(Key - String) = ModelClass(Value - String)
/loginForm.do = xyz.itwill.mvc.LoginFormModel
/login.do = xyz.itwill.mvc.LoginModel
/logout.do = xyz.itwill.mvc.LogoutModel
/writeForm.do = xyz.itwill.mvc.WriteFormModel
/write.do = xyz.itwill.mvc.WriteModel
/list.do = xyz.itwill.mvc.ListModel
/view.do = xyz.itwill.mvc.ViewModel
/modifyForm.do = xyz.itwill.mvc.ModifyFormModel
/modify.do = xyz.itwill.mvc.ModifyModel
/remove.do = xyz.itwill.mvc.RemoveModel
/error.do = xyz.itwill.mvc.ErrorModel

0개의 댓글