개념
- 전통적인 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 에서 정의된 태그들을 사용할 수 있게 해준다.
- 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 패턴을 사용할 수 있습니다
- 재사용성과 모듈화
- 서블릿 매핑을 통해 특정 서블릿을 여러 URL 패턴과 연결할 수 있어, 서블릿의 재사용성을 높일 수 있다.
web.xml 파일 이용
- web.xml 파일은 Java 웹 애플리케이션의 설정 파일로, 애플리케이션의 전반적인 구성 및 배포 정보를 담고 있다
- webapp > WEB-INF 폴더 아래에 위치하며, 애플리케이션 서버에 의해 읽혀져서 애플리케이션의 동작 방식을 정의한다
- 주로 서블릿, 필터, 리스너 등의 컴포넌트를 선언하고, 이들 간의 매핑을 설정하는 데 사용된다.
- 주요 역할
- 서블릿 설정 : 서블릿을 정의하고 매핑을 설정(서블릿 간의 연결을 설정)하여 특정 URL 패턴에 대해 서블릿이 처리할 수 있도록 함
- 서블릿 매핑은 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 |