본문 바로가기
코딩도전기/MVC

CODO Day23_JAVA_MVC(Exception)

by 코도꼬마 2023. 3. 6.

Exception & Error(면접질문*)

  • Error 문법문제로 실행에 문제가 생겨 발생하는 오류(실행되지 않음)
  • Exception  : 사용자의 오조작이나 외부문제로 발생하는 오류(실행은 시작되나 오류가 발견되면 멈춤)

 

 

Exception의 종류

  • 일반예외(Exception)  :  Compile time에 실행되는 exception으로 coding 중에 알 수 있음(이클립스에서 잡아줌)
    • JVM에서 필요하다고 판단하면 자동으로 예외처리를 해주기 때문에 Runtime Exception만 신경쓰면됨
  • 실행예외(Runtime Exception)  :  Run time에 실행되는 exception으로 실행해봐야 알 수 있음

 

Runtime Exception의 종류

  • NullPointException 객체가 없는 상태에서 객체를 사용할 경우
  • ArrayIndexOutofBoundException 배열 인덱스 범위를 초과하여 사용 할 경우
  • NumberFormatException 숫자 변환 시 문자가 포함되어 있는 경우
  • ClassCastException  :  매개값으로 받은 타입의 종류를 알 수 없을 경우

 

 

예외처리

  • 불가피한 외부문제로 Exception이 발생하므로 예외처리를 통해 프로그램이 정상 작동하도록 대비해야함
  • 예외처리 방법은 Try-catchThrows가 있음

 

Throws 

  • 예외처리를 하지 않고 작업을 지시한 메서드에게 처리를 넘김
  • 프로그램 시작점(controller)에서도 throws할 경우 JVM에서 처리(예외내용(에러코드) 콘솔 출력)

 

Try-catch

  • 예외가 발생한 곳에서 해결
  • try영역의 코드에서 exception 발생 시 catch영역의 코드 실행
  • finally는 exception 발생 시에도 꼭 실행할 code 작성

 

  • Exception이 여러개 발생한 경우 multi catch or OR exception 사용

 

  # 모든 예외는 Exception을 상속받기 때문에 모든 예외를 다루고 싶을 경우 Exception으로 처리

 

  # 기존 예외 외에도 새로운 예외를 만들 수 있음
      But 반드시 [Exception | RuntimeException] 클래스를 상속받아야 함
      & 테스트를 위해서 강제로 특정 예외를 발생시킬 수 있음

 

# 예외발생 예시

  • index.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>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style>
	table, th, td{
		border: 1px solid black;
		border-collapse: collapse;
	}
	th, td{
	padding: 5px 10px;
	}
	
</style>
</head>
<body>
	<form action="join" method="post">
		<table>
			<tr>
				<th>ID</th>
				<td>
					<input type="text" name="id" value=""/>
				</td>
			</tr>
			<tr>
				<th>PW</th>
				<td>
					<input type="password" name="pw" value=""/>
				</td>
			</tr>
			<tr>
				<th>나이</th>
				<td>
					<input type="text" name="age" value="" placeholder="20세 이상만 가입 가능"/>
				</td>
			</tr>
			<tr>
				<th>취미(2가지)</th>
				<td>
					<input type="checkbox" name="hobby" value="sports"/>스포츠 &nbsp;
					<input type="checkbox" name="hobby" value="movie"/>영화 &nbsp;
					<input type="checkbox" name="hobby" value="game"/>게임 &nbsp;
					<input type="checkbox" name="hobby" value="fishing"/>낚시 &nbsp;
				</td>
			</tr>
			<tr>
				<th>성별</th>
				<td>
					<input type="radio" name="gender" value="남"/>남자 &nbsp;&nbsp;
					<input type="radio" name="gender" value="여"/>여자
				</td>
			</tr>
			<tr>
				<th colspan="2"><button>가입</button></th>
			</tr>
		</table>
	</form>
</body>
<script></script>
</html>

 

  • JoinModel
package kr.co.web.model;

public class JoinModel {
	
	//20세 이상 나이 체크
	public String ageCheck(String ageStr) {
		
		//NumberFormatException : 숫자형태가 아닌 값이 숫자로 형변환하려고 할 때 발생
		int age = Integer.parseInt(ageStr);
		String msg = "20세 미만이므로 가입 불가합니다.";
		
		if(age>=20) {
			msg = "20세 이상이므로 가입 가능합니다.";
		}
		return msg;
	}
	
	//받아온 취미 서버에 저장
	//ArrayIndexOutOfBoundsException : 담을 배열보다 더 많은 값이 올 경우(2개 초과)
	public String[] hobbyCheck(String[] hobby) {
		
		String[] list = new String[2];
		for (int i = 0; i < hobby.length; i++) {
			list[i] = hobby[i];
		}		
		return list;
	}
	
	//성별 체크(남 >> male / 여 >> female)
	//NullPointerException : null인 값에 무언가 하려고 할 경우(값입력X)
	public String genderCheck(String gender) {
		String result = "female";
		
		if(gender.equals("남")) {
			result = "male";
		}
		return result;
	}
}

 

  • JoinController
package kr.co.web.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
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 kr.co.web.model.JoinModel;

@WebServlet("/join")
public class JoinController extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		String id = req.getParameter("id");
		String pw = req.getParameter("pw");
		String age = req.getParameter("age");
		String[] hobby = req.getParameterValues("hobby");
		String gender = req.getParameter("gender");
		System.out.println(id + " / " + pw + " / " + age + " / " + hobby + " / " + gender);
		
		JoinModel model = new JoinModel();
		String ageChk = model.ageCheck(age);
		String[] hobbyChk = model.hobbyCheck(hobby);
		String genderChk = model.genderCheck(gender);
		
		req.setAttribute("age", ageChk);
		req.setAttribute("hobby", hobbyChk);
		req.setAttribute("gender", genderChk);
		RequestDispatcher dis = req.getRequestDispatcher("result.jsp");
		dis.forward(req, resp);
	}
}

 

  • result
<%@ 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 charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
</head>
<body>
	<p>나이 : ${age}</p>
	<p>성별 : ${gender}</p>
	<p>취미 : 
		<c:forEach items="${hobby}" var="hb">
			${hb}
		</c:forEach>
	</p>	
</body>
<script></script>
</html>

 

 

# 예외처리

  • index.jsp(위의 idex.jsp와 동일)

 

  • AdultException
package kr.co.web.model;

public class AdultException extends Exception {

	public AdultException(String message) {
		super(message);		
	}
}

 

  • ReservedException
package kr.co.web.model;

public class ReservedException extends RuntimeException {
	
	public ReservedException(String message) {
		//System.out.println(message);  //부모가 객체화되기 전에 자식은 아무것도 할 수 없음
		super(message);  //부모 생성자
	}
}

 

  • JoinModel
package kr.co.web.model;

public class JoinModel {
	
	//20세 이상 나이 체크
	public void ageCheck(String ageStr) throws AdultException, NumberFormatException{
		int age = Integer.parseInt(ageStr);
		if(age<20) {
			throw new AdultException("20세 미만은 가입할 수 없습니다.");
		}
	}
	
	//받아온 취미 서버에 저장
	//ArrayIndexOutOfBoundsException : 담을 배열보다 더 많은 값이 올 경우
	public String[] hobbyCheck(String[] hobby) {
		String[] list = new String[2];
		
		try {
			for (int i = 0; i < hobby.length; i++) {
				list[i] = hobby[i];
			}
		} catch (ArrayIndexOutOfBoundsException e) {
			list[0] = "취미는 두개까지만 가능합니다.";
		}	
		return list;
	}
	
	//성별 체크(남 >> male / 여 >> female)
	//NullPointerException : null인 값에 무언가 하려고 할 경우
	//throws : 여기서 처리하지 않고 일을 시킨 메서드에게 넘김
	public String genderCheck(String gender) throws NullPointerException{ 
		String result = "female";
		
		if(gender.equals("남")) {
			result = "male";
		}
		return result;
	}
	
	public void reservedCheck(String id) {
		String[] reserved = {"admin", "tester", "member"};
		for(String name : reserved) {
			if(id.equals(name)) {
				//throw new 000Exception : 강제 예외 발생
				throw new ReservedException(id+"는 예약어 입니다.");
			}
		}
	}
	
}

 

  • JoinController
package kr.co.web.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.servlet.RequestDispatcher;
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 kr.co.web.model.AdultException;
import kr.co.web.model.JoinModel;

@WebServlet("/join")
public class JoinController extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp){
		
		try { //예외가 발생할 가능성이 있는 코드
			req.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException e) { //해당 예외 발생 시 실행할 코드
			// TODO Auto-generated catch block
			e.printStackTrace(); //예외에 대한 정보를 상세히 출력
		}
		
		String id = req.getParameter("id");
		String pw = req.getParameter("pw");
		String age = req.getParameter("age");
		String[] hobby = req.getParameterValues("hobby");
		String gender = req.getParameter("gender");
		System.out.println(id + " / " + pw + " / " + age + " / " + hobby + " / " + gender);
		
		JoinModel model = new JoinModel();		
		
		try {
			model.reservedCheck(id);	
		} catch (Exception e) {
			id = "사용할 수 없는 아이디입니다.";
			System.out.println(e.toString());
		}
		
		//String ageChk = model.ageCheck(age);
		String ageChk = "가입이 가능한 나이입니다.";
		
		try {
			model.ageCheck(age);
		} catch (NumberFormatException e) {
			ageChk = "숫자만 입력해주세요.";
			System.out.println(e.toString());
		} catch (AdultException e) {
			ageChk = "20세 미만은 가입이 불가능합니다.";
			System.out.println(e.toString());
		}
		
		String[] hobbyChk = model.hobbyCheck(hobby);
		String genderChk;
		
		try {
			genderChk = model.genderCheck(gender);
		} catch (NullPointerException e) {
			System.out.println(e.toString());
			genderChk = "성별 선택은 필수입니다.";
		}
		
		req.setAttribute("id", id);
		req.setAttribute("age", ageChk);
		req.setAttribute("hobby", hobbyChk);
		req.setAttribute("gender", genderChk);
		RequestDispatcher dis = req.getRequestDispatcher("result.jsp");
		
		//여러 예외가 발생할 수도 있는 경우 1
		try { 
         	dis.forward(req, resp); //해당 코드를 실행하다가 
		} catch (ServletException e) { //해당 예외 발생 시 
        	System.out.println("서버 통신 과정에서 예외 발생"); 
            e.printStackTrace(); 
		} catch (IOException e) { //해당 예외 발생 시
             System.out.println("외부와 데이터 교환 중에 예외 발생"); 
             e.printStackTrace(); 
		}
		
		//여러 예외가 발생할 수도 있는 경우 2(multi catch)
		try { 
        	dis.forward(req, resp); 
        } catch (ServletException | IOException e) { //00 또는 00예외 발생 시 한곳에서 처리 
        	e.printStackTrace(); 
        }
		
		//여러 예외가 발생할 수도 있는 경우 3(다형성 활용* - 많이 사용)
		try {
			dis.forward(req, resp);
		} catch (Exception e) {			
			e.printStackTrace();
		} 
	}

}

 

  • 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" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
</head>
<body>
	<p>ID : ${id}</p>
	<p>나이 : ${age}</p>
	<p>성별 : ${gender}</p>
	<p>취미 : 
		<c:forEach items="${hobby}" var="hb">
			${hb}
		</c:forEach>
	</p>	
</body>
<script></script>
</html>