데이터융합 JAVA응용 SW개발자 기업 채용연계 연수과정 42일차 강의 정리

misung·2022년 5월 12일
0

JSP

세션

실습 3. 세션을 통한 회원가입 구현하기 (이어서)

login_welcome.jsp

<%@page import="user.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	User user = (User)session.getAttribute("login");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<% if(user != null) { %>
		<h2><%=user.getNickName()%>(<%=user.getAccount()%>)님 환영합니다!</h2>
		<a href="login_form.jsp">로그인 화면으로</a>
		<a href="logout.jsp">로그아웃하기</a>
		<a href="delete.jsp">회원 탈퇴하기</a>
	<% } else { %>
		<script>
			alert('로그인이 필요합니다.')
			location.href="login_form.jsp";
		</script>
	<% } %>
</body>
</html>

웰컴 페이지는 login이라는 이름을 가진 Attribute를 찾아 user 객체를 채워준다. 유저 정보가 유효한 경우에만 화면을 구성하고, 아닌 경우 경고창을 출력하고 로그인 폼으로 돌려보낸다.

logout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	// 세션 날리기
	session.invalidate();
%>

<script>
	alert("로그아웃 처리되었습니다.")
	location.href="login_form.jsp";
</script>

delete.jsp

<%@page import="user.UserRepository"%>
<%@page import="user.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	User user = (User)session.getAttribute("login");
	UserRepository.deleteUser(user.getAccount());
	session.invalidate();
%>

<script>
	alert("회원 탈퇴 처리되었습니다.");
	location.href="login_form.jsp";
</script>

로그아웃과 회원탈퇴를 구현한 jsp 페이지다.

Application

  • 특정 웹 어플리케이션에 포함된 모든 JSP 페이지는 하나의 application 기본 객체를 공유한다.
  • application 객체는 웹 어플리케이션 전반에 걸쳐서 사용되는 정보를 담고 있다.

실습 1. Application 객체 사용

app_basic.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	int count = 0;
	
	if (application.getAttribute("visit") != null) {
		count = (int)application.getAttribute("visit");
	}

	count++;
	application.setAttribute("visit", count);
%>

위 내용의 페이지를, session_welcome.jsp 에서 @include 하였다.

session_welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	/*
	1. 로그인하지 않은 사용자가 주소창에 이 페이지의 URL를 직접 적고
	들어왔을 경우 로그인창으로 돌려보내는 코드를 작성하세요.
	(조건문을 사용하여 로그인 성공 시 생성되는 세션이 있는지를 확인.)
	
	2. 로그인한 회원 아이디와 별명을 통해 "nick(id)님 환영합니다!" 를
	 출력하세요.
	 
	3. a태그로 로그인창으로 돌아가는 링크와 request폴더에 앨범 선택 페이지로
	 갈 수 있는 링크 2개를 작성하세요.
	 
	4. session_login.jsp에서도 로그인 세션이 존재하는지를 확인하여 이미 로그인 중인 사용자와
	 그렇지 않은 사용자가 서로 다른 화면을 볼 수 있도록 작성해 주세요.
	 (로그인 성공 -> 이미 로그인 중이라는 화면, 로그인 x -> 폼)
	*/ 
	
	if (session.getAttribute("user_id") == null) {
		response.sendRedirect("session_login.jsp");
	} else {
		String id = (String)session.getAttribute("user_id");
		String nick = (String)session.getAttribute("user_nick");

%>

<%@include file="../Application/app_basic.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2><%=nick %>(<%=id%>)님 환영합니다!</h2>

	<a href="./session_login.jsp">로그인 화면으로 돌아가기</a>
	<a href="../JspObjRequest/req_album.jsp">앨범 선택 화면으로 이동</a>
	
	<hr>
	
	<h3>방문자 수: <%=count %></h3>
</body>
</html>

<% } %>

물론 이 페이지 말고도 다른 곳에 include 처리를 해 놓았고, 각 페이지를 옮겨다녀도 방문자 수는 없어지지 않고 잘 증가하는 값을 이곳 저곳의 페이지에서 확인할 수 있게 된다.

에러 처리

web.xml에 에러 페이지를 등록해두면 각 jsp 파일마다 에러 페이지 설정 처리할 필요가 없어진다.

에러 페이지의 우선 순위
1. 페이지 지시자 태그의 errorPage 속성에 지정한 페이지
2. web.xml에 지정한 에러 타입에 따른 페이지
3. web.xml에 지정한 응답 상태 코드에 따른 페이지
4. 위 3항목에 해당하지 않을 경우 톰캣이 제공하는 에러 페이지.

실습 1. 에러 페이지 처리하기

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>JspBasic</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <error-page>
  	<error-code>404</error-code>
  	<location>/Exception/error_404.jsp</location>
  </error-page>
  
  <error-page>
  	<exception-type>java.lang.NullPointerException</exception-type>
  	<location>/Exception/error_null.jsp</location>
  </error-page>
</web-app>

이제 이렇게 해 놓고 각 페이지를 만든다.

error_404.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h4>페이지를 찾을 수 없는 404 에러입니다.</h4>
	<p>
		요청하신 페이지는 찾을 수 없습니다.<br>
		주소가 올바르지 않은 것 같습니다.
	</p>
</body>
</html>

error_null.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>서비스 과정에서 null 에러가 발생했습니다.</h2>
</body>
</html>

각 에러 페이지로 리다이렉트가 잘 되는지 확인하려면 아래의 코드를 작성해서 실행해보면 된다.

null 발생

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		String s = null;
		s.indexOf("메롱");
	%>
</body>
</html>

404 발생

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="hello.jsp">404에러 유발!</a>
</body>
</html>

DataBase

서버 내렸다 올리면 다 죽는 시대는 이제 끝났고! 드디어 데이터베이스..

DB 연동은 이제 하나의 파일에서 관리할 것임 (DAO)

MVC 패턴에서의 Model

DAO 클래스 (Data Access Object)

  • 데이터베이스에 접속해서 데이터의 추가, 삭제, 수정 등의 작업을 하는 클래스입니다.

  • 일반적으로 JSP 혹은 Servlet에서 위의 로직을 함께 기술할 수도 있지만, 유지보수 및 코드의 모듈화를 위해 별도의 DAO 클래스를 만들어 사용한다.

  • 보통 한 개의 테이블마다 한 개의 DAO 클래스를 작성한다.

  • DAO 클래스는 테이블로부터 데이터를 읽어와 자바 객체로 변환하거나 자바 객체의 값을 테이블에 저장한다.

  • 따라서 DAO를 구현하면 테이블의 컬럼과 매핑되는 값을 갖는 자바빈 클래스를 항상 작성해야 한다. 이 자바빈 클래스를 VO 클래스라 부른다.

VO 클래스(Valut Object) / DTO 클래스(Data Transfer Object)

  • DAO 클래스를 이용하여 데이터베이스에서 데이터를 관리할 때 데이터를 일반적인 변수에 할당하여 작업할 수도 있지만, 별도의 VO 클래스를 작성하여 데이터베이스와 관련된 변수들의 모음 역할을 한다.

  • VO 클래스는 자바빈 클래스로 생성한다.

실습 준비

새로운 Dynamic Web Project 를 만들고 이름은 JdbcBasic으로 한다. 그리고 아래와 같은 명령어를 cmd에서 입력한다.

sqlplus
CREATE USER jsp IDENTIFIED BY jsp;
GRANT CREATE SESSION TO jsp;
GRANT CONNECT, RESOURCE TO jsp;

ALTER USER jsp DEFAULT TABLESPACE users
QUOTA UNLIMITED ON users;

그리고 SQL Developer 에서 다음과 같은 쿼리를 작성하고 실행한다. (물론 id:jsp, pw:jsp로 접속한 후에)

-- 학생들 점수 정보를 저장할 테이블
CREATE TABLE scores (
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30) NOT NULL,
    kor NUMBER(3) DEFAULT 0,
    eng NUMBER(3) DEFAULT 0,
    math NUMBER(3) DEFAULT 0,
    total NUMBER(3) DEFAULT 0,
    average NUMBER(5, 2)
);

CREATE SEQUENCE id_seq
    START WITH 1
    INCREMENT BY 1
    MAXVALUE 1000
    NOCACHE
    NOCYCLE;

SELECT * FROM scores;

실습 1. JSP와 데이터베이스를 통해 학생 점수 저장하기

먼저 학생 점수를 입력받기 위한 insert_form.jsp를 작성한다.

insert_form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>시험 점수 등록하기</h1>
	<form action="insert_controller.jsp" method="post">
		<p>
			#이름: <input type="text" name="name" maxlength="5"> <br>
			#국어: <input type="text" name="kor" maxlength="3"> <br>
			#영어: <input type="text" name="eng" maxlength="3"> <br>
			#수학: <input type="text" name="math" maxlength="3"> <br>
			<input type="submit" value="확인">
		</p>
	</form>
</body>
</html>

그리고 이제 컨트롤러를 만든다.

insert_controller.jsp

<%@page import="kr.co.jsp.score.model.ScoreDAO"%>
<%@page import="kr.co.jsp.score.model.ScoreVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	request.setCharacterEncoding("utf-8");

	String name = request.getParameter("name");
	int kor = Integer.parseInt(request.getParameter("kor"));
	int eng = Integer.parseInt(request.getParameter("eng"));
	int math = Integer.parseInt(request.getParameter("math"));
	
	int total = kor + eng + math;
	double avg = total / 3.0;
	
	ScoreVO vo = new ScoreVO(0, name, kor, eng, math, total, avg);
	
	ScoreDAO dao = ScoreDAO.getInstance();
	boolean flag = dao.insert(vo);
	
	if (flag) {
		response.sendRedirect("insert_success.jsp");
	} else {
		response.sendRedirect("insert_form.jsp");
	}
%>

이 과정에서 Score에 대한 VO, DAO를 만들어야 한다.

먼저 데이터베이스에 저장될 객체의 각 속성값들에 대해 I/O를 관리하는 VO를 먼저 작성하자.

ScoreVO.java

package kr.co.jsp.score.model;

/*
 * CREATE TABLE scores (
    id NUMBER PRIMARY KEY,
    name VARCHAR2(30) NOT NULL,
    kor NUMBER(3) DEFAULT 0,
    eng NUMBER(3) DEFAULT 0,
    math NUMBER(3) DEFAULT 0,
    total NUMBER(3) DEFAULT 0,
    average NUMBER(5, 2)
);

CREATE SEQUENCE id_seq
    START WITH 1
    INCREMENT BY 1
    MAXVALUE 1000
    NOCACHE
    NOCYCLE;
 */

public class ScoreVO {
	// 자바빈 클래스란, 데이터베이스와의 반복적인 작업을
	// 쉽게 처리하기 위해 디자인하는 클래스이다.
	
	// 자바빈 클래스는 은닉(캡슐화)을 사용하여 설계한다.
	
	// 자바빈 클래스는 데이터베이스의 컬럼과 1:1로 매칭되는 멤버변수를 선언한다.
	
	private int id;
	private String name;
	private int kor;
	private int eng;
	private int math;
	private int total;
	private double average;
	
	// 자바빈 클래스는 일반적으로 기본 생성자(필수)와 
	// 모든 필드값을 매개값으로 받는 생성자(선택)를 하나씩 제작해 준다.
	
	public ScoreVO() {}

	public ScoreVO(int id, String name, int kor, int eng, int math, int total, double average) {
		super();
		this.id = id;
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		this.math = math;
		this.total = total;
		this.average = average;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public double getAverage() {
		return average;
	}

	public void setAverage(double average) {
		this.average = average;
	}
	
	
}

그리고 VO를 관리할 DAO클래스를 만든다.

ScoreDAO.java

package kr.co.jsp.score.model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

// DAO는 웹 서버의 DB 연동 요청이 발생할 때 마다
// DataBase CRUD(Create, Read, Update, Delete)
public class ScoreDAO {
	// 싱글톤 디자인 패턴 (객체의 생성을 단 하나로 제한하기 위한 코드 디자인 패턴)
	
	// 1. 클래스 외부에서 객체를 생성하지 못하게 생성자에 private 접근 제한을 붙임
	private ScoreDAO() {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	// 2. 이제 객체를 생성할 수 있는 영역은 해당 클래스 내부 뿐이므로,
	// 스스로의 객체를 단 하나만 생성한다.
	private static ScoreDAO dao = new ScoreDAO();
	
	// 3. 외부에서 객체를 요구할 시 공개된 메서드를 통해
	// 2번에서 미리 만들어 놓은 단 하나의 객체의 주소값을 리턴.
	public static ScoreDAO getInstance() {
		if (dao == null) {
			dao = new ScoreDAO();
		}
		return dao;
	}
	
	
	// --------------------------------------------------------
	
	// DB 관련 여러 작업 메서드가 들어갈 공간
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	// 모든 메서드에서 공용적으로 사용할 Connection 객체를 얻을 수 있는 유틸 메서드
	private Connection getConnection() throws Exception {
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String uid = "jsp";
		String upw = "jsp";
		
		return DriverManager.getConnection(url, uid, upw);
	}
	
	// 점수 데이터를 저장하는 메서드
	public boolean insert(ScoreVO vo) {
		boolean flag = false;
		String sql = "INSERT INTO scores VALUES(id_seq.NEXTVAL, ?,?,?,?,?,?)";
		
		try {
			conn = getConnection();
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, vo.getName());
			pstmt.setInt(2, vo.getKor());
			pstmt.setInt(3, vo.getEng());
			pstmt.setInt(4, vo.getMath());
			pstmt.setInt(5, vo.getTotal());
			pstmt.setDouble(6, vo.getAverage());
			
			int rn = pstmt.executeUpdate();
			if (rn == 1) flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				pstmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return flag;
	}
}

이제 success 페이지를 만든다.

insert_success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>점수 등록 성공!</h1>
	<a href="insert_form.jsp">새로운 점수 등록하기</a>
	<a href="score_list.jsp">점수 전체 조회하기</a>
</body>
</html>

내일은 점수 전체를 조회하는 기능을 구현하도록 한다.

0개의 댓글