본문 바로가기
Kosta DevOps 과정 280기/Java

MVC 패턴

by 롯슈83 2024. 7. 15.

개념 

  • 전통적인 java 기반의 웹 기술인 jsp 는 하나의 jsp 문서에 사용자의 요청, 요청에 따른 처리 그리고 결과를 보여주기 위한 view 를 하나의 jsp 에서 모두 처리하게 된다.
  • 이것은 웹 초기에는 jsp 문서 안에서 html 과 자바 문법을 같이 쓸 수 있어서 장점이었으나 그러나 현대의 웹 환경에서는 사용자 요구가 복잡해지고 프로젝트 규모가 커짐에 따라 또, 협업과 유지보수 하기에는 어려움이 있다.
  • 그래서 현대의 웹 환경에서는 하나의 jsp 안에서 모든 처리(사용자의 요청 파악, 그 요청에 따른 일처리, 그리고 결과를 보여주기 위한 View의 역할)를 하지 않고 별도의 역할 분담을 하기를 권장한다.
  • 사용자의 요청 파악은 "Controller"가 하고 그 요청에 따른 일처리는 "Model"이 담당하고, 일처리된 결과를 보여주기 역할은 "View"가 하도록 한다.
  • 이러한 방식을 "MVC" 패턴이라고 한다.
    • M (Model)은 사용자의 요청에 따른 일처리를 위한 모든 자바 클래스를 말한다.
    • V (View)는 사용자의 요청에 따른 처리된 결과를 보여주는 역할을 하는 JSP 를 말한다.
    • C (Controllor)는 사용자의 요청을 파악하여 해당 Model 에게 일처리를 맡기고 그 처리된 결과에 따라서 적합한 View를 연결시켜주는 담당을 한다. 컨트롤러의 역할을 jsp 로도 만들 수 있지만 일반적으로는 서블릿으로 한다.

jstl : jsp에서 자바 문법을 완전히 걷어내기

  • html 에서 자바 문법을 사용하려고 할  때, 즉 컨트롤러에서 request 에 상태 유지한 값 출력하기는 다음과 같이 나타낼 수 있다.
    • 자바 문법 --> <%= %> : 표현식
    • 표현 언어 --> ${msg} (A.속성이름을 하면 getter() 메소드가 자동으로 동작된다.)
  • 단, 단순히 request 등으로 받은 값을 출력하는 일만 필요한 것이 아니라 때때로 for문과 if 문등을 써주어야 하는 일 등이 있다. 그럴 때는 자바 문법을 사용할 수 있는 태그를 이용한다.
  • 만약 위의 표현식과 자바 문법을 사용할 수 있는 태그를 사용하려면 standard.jar와 jstl.jar 라이브러리를 wepapp > WEBINF > lib 폴더에 추가시켜야 한다.

 

standard.jar 와 jstl.jar의 역할과 차이(chatGPT의 도움을 받아 작성된 내용입니다.)

  • 두 파일은 JavaServer Pages(JSP)에 많이 사용하는 라이브러리이다.
  • 이 두 라이브러리는 JSP 태그 라이브러리로서, JSP 페이지에서 더욱 간편하고 효율적으로 다양한 기능을 사용할 수 있게 도와준다.
  • JSTL(JavaServer Pages Standard Tag Library)
    • jstl.jar
      • JSTL 태그 라이브러리의 정의
      • 역할 : JSTL 은 JSP 페이지에서 자주 사용되는 공통적인 기능을 하는 태그 라이브러리이다. 이를 통해 JSP 페이지에서 반복적인 Java 코드를 줄이고, 코드의 가독성과 유지 보수성을 높일 수 있다.
      • 주요 기능
        • 코어 태그 : 조건문, 반복문, URL관리, 흐름 제어 등의 기본적인 기능
        • 포맷팅 태그 : 숫자, 날짜, 통화 등의 형식화를 지원
        • SQL 태그 : 데이터베이스와의 상호 작용을 위한 태그를 제공
        • XML 태그 : XML 데이터를 다루기 위한 태그를 포함
        • 국제화 태그 : 다국어 지원 및 현지화를 위한 태그를 제공
    • standard.jar
      • JSTL 태그 라이브러리의 구현
      • 역할 : standard.jar는 JSTL 의 구현체로서, 실제로 JSTL 태그를 동작하게 하는 핵심 라이브러리이다. JSTL
      • 을 사용할 때, 'standard.jar'파일이 필요하며, 이는 JSTL 사양에 따라 정의된 태그를 구현한다.
      • 주요 기능
        • standard.jar는 JSTL 사양에 정의된 모든 기능을 포함하며, 이들을 실제로 동작시키는 역할을 한다.
        • jstl.jar 에서 정의된 태그들을 사용할 수 있게 해준다.

 

MVC 패턴 예제

  • webapp > WEB-INF > lib 폴더에 jstl.jar, standard.jar ojdbc8.jar 파일 추가(어노테이션을 쓰지 않을 시 web.xml 파일 추가)

 

<!-- start.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="listCustomer.do">고객목록</a>
	<a href="insertCustomer.do">고객등록</a>
</body>
</html>
<!--listCustomer.jsp-->
<%@page import="java.util.ArrayList"%>
<%@ 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>
</head>
<body>
	<h2>고객 목록</h2>
	<a href="insertCustomer.do">고객등록</a>
	<br>
	<table border="1" width="80%">
		<tr>
			<th>고객번호</th>
			<th>고객이름</th>			
		</tr>
		
		<c:forEach var="c" items="${list }">
			<tr>
				<td>${c.custid }</td>   
				<td> 
					<a href="detailCustomer.do?custid=${c.custid }">${c.name }</a>
				</td>   				
			</tr>
		</c:forEach>
	</table>
</body>
</html>
<!-- insertCustomer.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>고객등록</h2>
	<hr>
	<form action="insertCustomerOK.do" method="post">
		고객번호 : <input type="text" name="custid"><br>
		고객이름 : <input type="text" name="name"><br>
		고객주소 : <input type="text" name="address"><br>
		고객전화 : <input type="text" name="phone"><br>
		<input type="submit" value="등록">
		<input type="reset" value="다시입력">
	</form>
</body>
</html>
<!-- insertCustomerOK.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>
	${msg }
	<hr>
	<a href="listCustomer.do">고객목록</a><br>
	<a href="insertCustomer.do">고객등록</a><br>
</body>
</html>
<!-- updateCustomer.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>고객수정</h2>
	<hr>
	<form action="updateCustomerOK.do" method="post">
		고객번호 : <span>${c.custid }</span><input type="hidden" name="custid" value="${c.custid }"><br>
		고객이름 : <input type="text" name="name" value="${c.name }"><br>
		고객주소 : <input type="text" name="address" value="${c.address }"><br>
		고객전화 : <input type="text" name="phone" value="${c.phone }"><br>
		<input type="submit" value="수정">
		<input type="reset" value="다시입력">
	</form>
</body>
</html>
<!-- updateCustomerOK.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>
	${msg }
	<hr>
	<a href="listCustomer.do">고객목록</a><br>
	<a href="insertCustomer.do">고객등록</a><br>
</body>
</html>
<!-- deleteCustomer.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>
	${msg }
	<hr>
	<a href="listCustomer.do">고객목록</a><br>
	<a href="insertCustomer.do">고객등록</a><br>
</body>
</html>
package com.kosta.controllor;

import java.io.IOException;
import java.util.ArrayList;

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 com.kosta.dao.CustomerDAO;
import com.kosta.vo.CustomerVO;

@WebServlet("/listCustomer.do")
public class ListCustomer extends HttpServlet {	
	
	private CustomerDAO dao;
	public ListCustomer() {
		dao = new CustomerDAO();
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ArrayList<CustomerVO> list = dao.findAll();
		
		//View(jsp)에서 사용할 수 있도록 상태유지 합니다.
		//forword 메소드로
		request.setAttribute("list", list);
		request.setAttribute("msg", "hello kosta");
		
		//결과를 보여줄 jsp를 변수에 저장합니다.
		String viewPage = "listCustomer.jsp";
		
		//결과를 보여줄 jsp로 이동시키기 위한 RequestDipatcher 객체를 생성합니다.
		//jsp 페이지에 연결
		RequestDispatcher dispatcher
		= request.getRequestDispatcher(viewPage);
		
		//jsp로 이동합니다.
		dispatcher.forward(request, response);
	}
}
package com.kosta.controllor;

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;


@WebServlet("/insertCustomer.do")
public class InsertCutomer extends HttpServlet {	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String viewPage = "insertCustomer.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
		dispatcher.forward(request, response);
	}
}
package com.kosta.controllor;

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 com.kosta.dao.CustomerDAO;
import com.kosta.vo.CustomerVO;

@WebServlet("/insertCustomerOK.do")
public class InsertCustomerOK extends HttpServlet {
	
	private CustomerDAO dao;
	public InsertCustomerOK() {
		dao = new CustomerDAO();
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		int custid = Integer.parseInt(request.getParameter("custid"));
		String name= request.getParameter("name");
		String address= request.getParameter("address");
		String phone= request.getParameter("phone");
		
		CustomerVO c= new CustomerVO();
		c.setCustid(custid);
		c.setName(name);
		c.setAddress(address);
		c.setPhone(phone);
		
		int re = dao.insert(c);
		if(re > 0) {
			request.setAttribute("msg", "고객등록에 성공하였습니다.");
		}else {
			request.setAttribute("msg", "고객등록에 실패하였습니다.");
		}
		String viewPage = "insertCustomerOK.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
		dispatcher.forward(request, response);
	}
}
package com.kosta.controllor;

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 com.kosta.dao.CustomerDAO;
import com.kosta.vo.CustomerVO;

/**
 * Servlet implementation class DetailCutomer
 */
@WebServlet("/detailCustomer.do")
public class DetailCutomer extends HttpServlet {
	private CustomerDAO dao;
	public DetailCutomer() {
		dao = new CustomerDAO();
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		int custid = Integer.parseInt(request.getParameter("custid"));
		CustomerVO c= dao.findByCustid(custid);
		request.setAttribute("c", c);
		String viewPage = "detailCustomer.jsp";
		
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
		dispatcher.forward(request, response);
	}
}
package com.kosta.controllor;

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 com.kosta.dao.CustomerDAO;
import com.kosta.vo.CustomerVO;

/**
 * Servlet implementation class UpdateCustomer
 */
@WebServlet("/updateCustomer.do")
public class UpdateCustomer extends HttpServlet {
	
	private CustomerDAO dao;
	public UpdateCustomer(){
		dao = new CustomerDAO();
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//수정할 고객번호를 받아 온다.
		int custid = Integer.parseInt(request.getParameter("custid"));
		
		//dao를 통해서 수정할 고객의 정보를 받아 온다.
		CustomerVO c = dao.findByCustid(custid);
		
		//view에서 사용하도록 상태유지 한다.
		request.setAttribute("c", c);
		
		//이동할 view페이지를 정한다.
		String viewPage = "updateCustomer.jsp";
		
		//view페이지로 이동시킨다.
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
		dispatcher.forward(request, response);
		
	}
}
package com.kosta.controllor;

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 com.kosta.dao.CustomerDAO;
import com.kosta.vo.CustomerVO;

@WebServlet("/updateCustomerOK.do")
public class UpateCustomerOK extends HttpServlet {
	
	private CustomerDAO dao;
	public UpateCustomerOK() {
		dao = new CustomerDAO();
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		int custid = Integer.parseInt(request.getParameter("custid"));
		String name= request.getParameter("name");
		String address= request.getParameter("address");
		String phone= request.getParameter("phone");
		
		CustomerVO c= new CustomerVO();
		c.setCustid(custid);
		c.setName(name);
		c.setAddress(address);
		c.setPhone(phone);
		
		int re = dao.udpate(c);
		if(re > 0) {
			request.setAttribute("msg", "고객수정에 성공하였습니다.");
		}else {
			request.setAttribute("msg", "고객수정에 실패하였습니다.");
		}
		String viewPage = "updateCustomerOK.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
		dispatcher.forward(request, response);
	}
}
package com.kosta.controllor;

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 com.kosta.dao.CustomerDAO;

/**
 * Servlet implementation class DeleteCustomer
 */
@WebServlet("/deleteCustomer.do")
public class DeleteCustomer extends HttpServlet {
	
	private CustomerDAO dao;
	public DeleteCustomer() {
		dao = new CustomerDAO();
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//삭제할 고객번호를 받아 옵니다.
		int custid = Integer.parseInt(request.getParameter("custid"));
				
		//Dao를 통해서 해당 고객을 삭제합니다.
		int re = dao.delete(custid);
		
		//삭제여부를 상태유지 합니다.
		if(re > 0) {
			request.setAttribute("msg", "고객의 정보를 삭제하였습니다.");
		}else {
			request.setAttribute("msg", "고객의 정보 삭제에 실패하였습니다.");
		}
		
		//이동할 view페이지를 정해 줍니다.
		String viewPage = "deleteCustomerOK.jsp";
		
		//View페이지로 이동시키기 위한 RequestDistpatcher 객체를 생성합니다.
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
		
		//뷰페이지로 이동시킵니다.
		dispatcher.forward(request, response);
	}
}

 

서블릿과 매핑(chatGPT의 도움을 받아 작성된 내용입니다.)

  • 서블릿에서 매핑이 필요한 이유는 서블릿을 웹 애플리케이션의 특정 URL 패턴과 연결하여 클라이언트의 요청을 처리할 수 있게 하기 위해서이다. 매핑을 통해 어떤 서블릿이 어떤 URL 요청을 처리할지 정의할 수 있습니다. 자세한 이유는 다음과 같다
  • URL과 서블릿 간의 연결
    • 서블릿 매핑은 URL과 서블릿 간의 연결을 설정합니다. 이를 통해 웹 브라우저나 다른 클라이언트가 특정 URL을 요청할 때, 해당 요청이 어떤 서블릿으로 전달될지를 명확히 할 수 있습니다.
  • 요청 처리의 분리
    • 매핑을 사용하면 다양한 요청을 서로 다른 서블릿이 처리하도록 분리할 수 있습니다. 예를 들어, 로그인 요청은 LoginServlet이 처리하고, 회원 가입 요청은 RegisterServlet이 처리하도록 할 수 있습니다.
  • 유지보수성과 가독성 향상
    • 서블릿 매핑을 사용하면 URL 패턴에 따라 서블릿을 관리할 수 있어, 코드의 유지보수성과 가독성을 높일 수 있습니다. 각 서블릿은 특정 기능에 집중할 수 있으며, 이는 코드 구조를 명확하게 만듭니다.
  • URL 패턴을 통한 유연성 제공
    • 서블릿 매핑을 통해 다음과 같은 다양한 URL 패턴을 사용할 수 있습니다
      • 정확한 매핑: /login
      • 경로 매핑: /user/*
      • 확장자 매핑: *.do
      • 기본 서블릿 매핑: /
  • 재사용성과 모듈화
    • 서블릿 매핑을 통해 특정 서블릿을 여러 URL 패턴과 연결할 수 있어, 서블릿의 재사용성을 높일 수 있다.

 

 

web.xml 파일 이용

  • web.xml 파일은 Java 웹 애플리케이션의 설정 파일로, 애플리케이션의 전반적인 구성 및 배포 정보를 담고 있다
  • webapp > WEB-INF 폴더 아래에 위치하며, 애플리케이션 서버에 의해 읽혀져서 애플리케이션의 동작 방식을 정의한다
  • 주로 서블릿, 필터, 리스너 등의 컴포넌트를 선언하고, 이들 간의 매핑을 설정하는 데 사용된다.
  • 주요 역할
    • 서블릿 설정 : 서블릿을 정의하고 매핑을 설정(서블릿 간의 연결을 설정)하여 특정 URL 패턴에 대해 서블릿이 처리할 수 있도록 함
      • 서블릿 매핑은 URL과 서블릿 간의 연결을 설정하여 클라이언트의 요청을 적절한 서블릿이 처리하도록 한다. 이는 요청 처리의 분리, 코드의 유지보수성 향상, 유연한 URL 패턴 매핑, 재사용성 및 모듈화 등을 가능하게 합니다. 매핑을 통해 웹 애플리케이션은 더욱 구조적이고 관리하기 쉬워진다.
    • 필터 설정 : 요청과 응답을 필터링할 수 있는 필터를 정의하고 매핑
    • 리스너 설정 : 애플리케이션의 라이프 사이클 이벤트를 처리할 리스너를 정의
    • 리소스 설정 : 초기화 매개변수, 환경 엔트리, 데이터 소스 등을 정의
    • 보안 설정 : 애플리케이션의 보안 제약을 설정
    • 환영 파일 설정 : 애플리케이션의 기본 문서를 지정
  • 요약
    • 이 파일은 java 웹 어플리케이션의 설정과 배포 정보를 정의하는 중요한 파일이다.
    • 서블릿, 필터, 리스너 등을 정의하고 매핑하는데 사용되며, 환영 파일과 보안 설정 등을 포함할 수 있다.
    • 다음의 제공된 예제에서는 서블릿 kosta 를 정의하고 do 로 끝나는 URL 요청을 이 서블릿으로 매필하는 설정을 포함한다.
  • web.xml 예시 코드 해석
<!--XML 선언 및 네임스페이스 정의--> 
<!--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>day0715_mvc_frontcontrol</display-name>
  
  <!-- 환영 파일 목록 -->
  <!-- 애플리케이션에 접근할 때 기본적으로 보여줄 파일 목록을 정의-->
  <!-- 이 목록에 있는 파일 하나가 존재하면 해당 파일이 기본 페이지로 표시됨-->
  <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>
  
  <!-- 서블릿 정의 -->
  <!-- servlet 을 정의-->
  <servlet>
  	<!-- 서블릿의 이름을 지정-->
    <servlet-name>kosta</servlet-name>
    <!-- 서블릿의 구현 클래스 이름을 지정-->
    <servlet-class>com.kosta.controller.KostaController</servlet-class>
  </servlet>
  
  <!-- 서블릿 매핑 -->
  <!-- 서블릿과 URL 패턴을 매핑-->
  <servlet-mapping>
  	<!--매핑할 서블릿의 이름을 지정-->
    <servlet-name>kosta</servlet-name>
    <!-- 서블릿이 처리할 URL 패턴을 지정-->
    <!-- 여기서는 .do로 끝나는 모든 요청이 kosta 서블릿으로 처리됨-->
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>
package com.kosta.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

import com.kosta.db.ConnectionProvider;
import com.kosta.vo.CustomerVO;

public class CustomerDAO {	
	
	public CustomerVO findByCustid(int custid) {
		CustomerVO c = null;
		String sql = "select * from customer where custid=?";
		try {
			Connection conn= ConnectionProvider.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, custid);
			ResultSet rs = pstmt.executeQuery();
			if(rs.next()) {
				c = new CustomerVO(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4));
			}
			ConnectionProvider.close(rs, pstmt, conn);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
		return c;
	}
	
	
	public int delete(int custid) {
		int re = -1;
		String sql = "delete customer where custid=?";
		try {
			Connection conn = ConnectionProvider.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(sql);			
			pstmt.setInt(1,custid);
			re = pstmt.executeUpdate();
			ConnectionProvider.close(pstmt, conn);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
		return re;
	}
	public int udpate(CustomerVO c) {
		int re = -1;
		String sql = "update customer set name=?,address=?,phone=? where custid=?";
		try {
			Connection conn = ConnectionProvider.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, c.getName());
			pstmt.setString(2, c.getAddress());
			pstmt.setString(3, c.getPhone());
			pstmt.setInt(4, c.getCustid());
			re = pstmt.executeUpdate();
			ConnectionProvider.close(pstmt, conn);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
		return re;
	}
	public int insert(CustomerVO c) {
		int re = -1;
		String sql = "insert into customer values(?,?,?,?)";
		try {
			Connection conn = ConnectionProvider.getConnection();
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, c.getCustid());
			pstmt.setString(2, c.getName());
			pstmt.setString(3, c.getAddress());
			pstmt.setString(4, c.getPhone());
			re = pstmt.executeUpdate();
			ConnectionProvider.close(pstmt, conn);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
		return re;
	}
	
	
	
	public ArrayList<CustomerVO> findAll(){
		ArrayList<CustomerVO> list = new ArrayList<CustomerVO>();
		String sql = "select * from customer";
		try {
			Connection conn = ConnectionProvider.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			while(rs.next()) {
				list.add(new CustomerVO(rs.getInt(1), rs.getString(2), 
						rs.getString(3), rs.getString(4)));
			}
			ConnectionProvider.close(rs, stmt, conn);
		}catch (Exception e) {
			System.out.println("예외발생:"+e.getMessage());
		}
		return list;
	}
}
package com.kosta.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class ConnectionProvider {
	public static Connection getConnection() {
		Connection conn = null;
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@localhost:1521:XE";
		String username = "c##madang";
		String password = "madang";
		try {
			Class.forName(driver);
			conn= DriverManager.getConnection(url, username, password);
			
		}catch(Exception e) {
			System.out.println("예외발생: "+e.getMessage());
		}
		return conn;
	}
	
	public static void close(ResultSet rs, Statement stmt, Connection conn) {
		try {
			if(rs != null) {rs.close();}
			if(stmt != null) {stmt.close();}
			if(conn != null) {conn.close();}
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	public static void close(Statement stmt, Connection conn) {
		try {
			if(stmt != null) {stmt.close();}
			if(conn != null) {conn.close();}
		} catch (Exception e) {
			System.out.println(e);
		}
	}
}
package com.kosta.vo;

public class CustomerVO {
	private int custid;
	private String name;
	private String address;
	private String phone;
	public int getCustid() {
		return custid;
	}
	public void setCustid(int custid) {
		this.custid = custid;
	}
	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;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public CustomerVO(int custid, String name, String address, String phone) {
		super();
		this.custid = custid;
		this.name = name;
		this.address = address;
		this.phone = phone;
	}
	public CustomerVO() {
		super();
		// TODO Auto-generated constructor stub
	}
	
}

 

<%@%> : 지시자 - jsp 를 동작하기 전에 선행 처리 되어야 할 내용을 써준다.

 

어노테이션 사용

  • Java EE 6 (Servlet 3.0)부터는 애플리케이션 설정을 애너테이션을 통해 수행할 수 있게 되면서 web.xml의 많은 기능을 대체할 수 있게 되었다
  • 애너테이션을 사용하면 코드에 설정을 직접 포함시킬 수 있어, 설정과 코드가 분리되지 않고 한눈에 볼 수 있는 장점이 있다.
  • 주요 애너테이션
    • @WebServlet: 서블릿을 선언하고 URL 패턴을 매핑할 때 사용합니다.
    • @WebFilter: 필터를 선언하고 URL 패턴을 매핑할 때 사용합니다.
    • @WebListener: 리스너를 선언할 때 사용합니다.
    • @ServletContextListener: 서블릿 컨텍스트의 생명주기 이벤트를 처리합니다.
  • 장점
    • 간결성: 설정이 코드에 직접 포함되므로 별도의 설정 파일 없이도 쉽게 관리할 수 있습니다.
    • 유지보수성: 코드와 설정이 한 곳에 있으므로 변경 시 관리가 용이합니다.
    • 자동화: 애플리케이션 서버가 자동으로 애너테이션을 검색하여 설정을 처리합니다.
  • 단점
    • 코드 분리의 부족: 설정과 로직이 함께 있으므로, 설정 파일을 선호하는 경우에는 불편할 수 있습니다.
    • 복잡한 설정: 복잡한 설정을 처리할 때는 여전히 web.xml이 더 명확할 수 있습니다.

 

properties 파일 사용하여 어노테이션을 관리

  • Properties 파일의 정의
    • Properties 파일은 키-값 쌍으로 구성된 설정 파일로, 애플리케이션의 설정을 외부화하여 쉽게 관리할 수 있도록 한다
    • 이를 통해 설정 변경 시 코드 수정 없이 파일만 변경하여 설정을 업데이트할 수 있다.
    • 단, Properties 를 통해 관리할 경우 각  controllor의(java 파일) 어노테이션을 제거해줘야한다. 
join.do=com.kosta.action.JoinAction
joinOK.do=com.kosta.action.JoinOKAction
login.do=com.kosta.action.LoginAction
loginOK.do=com.kosta.action.LoginOKAction

insertBoard.do=com.kosta.action.InsertBoardAction
insertBoardOK.do=com.kosta.action.InsertBoardOKAction

listBoard.do=com.kosta.action.ListBoardAction
detailBoard.do=com.kosta.action.DetailBoardAction


updateBoard.do=com.kosta.action.UpdateBoardAction
updateBoardOK.do=com.kosta.action.UpdateBoardOKAction

deleteBoard.do=com.kosta.action.DeleteBoardAction
deleteBoardOK.do=com.kosta.action.DeleteBoardOKAction
  • Properties 파일을 사용하는 이유
    • 유연성 : 설정을 코드와 분리하여 쉽게 변경할 수 있다.
    • 환경 설정: 개발, 테스트, 프로덕션 등 다양한 환경에서 서로 다른 설정을 사용할 수 있습니다.
    • 관리 용이성: 모든 설정을 중앙화하여 관리할 수 있습니다.
  • 어노테이션과 Properties 파일의 상관관계
    • 설정 외부화: 어노테이션을 사용하면 설정을 코드에 직접 포함시킬 수 있지만, properties 파일을 사용하면 설정을 외부 파일로 분리할 수 있습니다. 이는 환경에 따라 설정을 쉽게 변경할 수 있게 합니다.
    • 코드와 설정의 분리: 어노테이션은 설정을 코드와 함께 유지하지만, properties 파일을 사용하면 설정을 코드와 분리하여 관리할 수 있습니다. 이는 설정 변경 시 코드의 재컴파일을 피할 수 있는 장점이 있습니다.
    • 동적 설정: Properties 파일을 사용하면 애플리케이션 실행 중에 설정을 동적으로 변경할 수 있습니다. 어노테이션은 정적인 설정에 적합하지만, properties 파일은 동적인 설정 변경에 유리합니다.
  • web.xml과 properties 파일 차이점
항목 web.xml properties 파일
용도 서블릿, 필터, 리스너 등 웹 애플리케이션 컴포넌트 구성 컴포넌트 구성 일반적인 애플리케이션 설정값 저장
형식 XML 키-값 쌍의 텍스트 파일
주요 내용 서블릿 매핑, 보안 설정, 초기화 매개변수 등 환경 설정, 데이터베이스 정보, 메시지 등
설정 변경 서버 재시작 필요 서버 재시작 없이 동적 변경 가능 (일부 경우)
읽기 방식 애플리케이션 서버가 자동으로 읽음 Java 코드에서 직접 읽음
복잡도 복잡한 설정 가능 단순한 설정에 적합
표준화 Java EE 표준 일반적인 설정 파일 형식 (특정 표준 없음)
장점 - 표준화된 형식으로 다양한 설정을 포괄적으로 관리 가능
- 서블릿, 필터, 리스너 등 웹 애플리케이션의 구조적 구성 가능
- 설정 변경이 용이하고, 서버 재시작 없이 동적 적용 가능 (일부 경우)
- 단순하고 가독성 좋은 형식
단점 - 설정 변경 시 서버 재시작 필요
- XML의 가독성이 떨어질 수 있음
- 웹 애플리케이션 컴포넌트의 복잡한 구성 관리에 부적합
- Java 코드에서 직접 읽어야 함
결론 서블릿, 필터, 리스너 등의 웹 애플리케이션 컴포넌트를 구성하고, 배포 설정을 관리하는 데 적합
(웹 애플리케이션의 구조적 설정 관리)
애플리케이션의 일반적인 설정값을 외부화하여 관리할 때 유용
(환경별로 달라지는 설정이나 자주 변경되는 설정 관리)

 

'Kosta DevOps 과정 280기 > Java' 카테고리의 다른 글

세션을 이용한 상태유지  (0) 2024.07.16
프론트 컨트롤러  (0) 2024.07.15
jsp 문장 구성 요소  (0) 2024.07.15
confirm  (0) 2024.07.15
jsp  (0) 2024.07.12