자바웹프로그래밍에서 사용되는 대표적인 아키텍처 패턴 중 하나
<!--jstl 문법: 태그 형식으로 코딩하는 방법(디자이너에게 직관적임)-->
<c:forEach var ="i" begin = "1" end = "10">
${i}
</c:forEach>
<%@ 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>Welcome!</h1>
<a href="/chap02/dancer/register">댄서 등록(서블릿버전)</a>
<a href="/chap03/dancer/register.jsp">댄서 등록(jsp버전)</a>
<a href="/chap04/dancer/form">댄서 등록(mvc버전)</a>
</body>
</html>
// 역할: 댄서 등록 화면을 요청하면 해당 html파일을 열기만해주는 역할
@WebServlet("/chap04/dancer/form")
public class DancerFormRequestServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// forward를 통해 적당한 view에게 화면처리를 위임 (controller -> view 위임)
// forwarding: 화면 파일을 찾아서 열어주는 개념
RequestDispatcher rd
= req.getRequestDispatcher("/WEB-INF/chap04/register.jsp");
rd.forward(req, resp); // jsp에게 화면처리하라고 던짐
}
}
<h2>${d.name}님(소속: ${d.crewName})이 정상 등록</h2>
처럼 쉽게 끌어다 쓸 수 있음package com.jsp.chap04;
import com.jsp.entity.Dancer;
import com.jsp.repository.DancerJdbcRepo;
import com.jsp.repository.DancerMemoryRepo;
import javax.servlet.DispatcherType;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// 역할: 새로운 댄서 정보를 데이터베이스에 등록하기 위해
// 댄서 정보들을 가져와서 처리하는 역할
@WebServlet("/chap04/new-dancer")
public class AddNewDancerServlet extends HttpServlet {
// private DancerMemoryRepo repo = DancerMemoryRepo.getInstance();
private DancerJdbcRepo repo = DancerJdbcRepo.getInstance();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 요청파라미터를 읽어서 댄서 정보 가져오기
req.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
String crewName = req.getParameter("crewName");
String danceLevel = req.getParameter("danceLevel");
String[] genres = req.getParameterValues("genres");
// 댄서 객체 생성
Dancer dancer = new Dancer();
dancer.setName(name);
dancer.setCrewName(crewName);
dancer.setDanceLevel(Dancer.DanceLevel.valueOf(danceLevel));
List<Dancer.Genre> genreList = new ArrayList<>();
for (String genre : genres) {
genreList.add(Dancer.Genre.valueOf(genre));
}
dancer.setGenres(genreList);
System.out.println("dancer = " + dancer);
// 생성된 댄서 객체를 데이터베이스에 저장
// 데이터베이스 처리에 특화된 객체에게 위임
repo.save(dancer);
// JSP에게 전달할 동적데이터를 어떻게 전달할 것인가?
// 수송객체 (page, request, session, application)
// request: 한 번의 요청과 응답이 끝날동안만 보관
// session: 브라우저가 꺼질 때 까지 or 세션시간이 만료될 때 까지 보관
req.setAttribute("d",dancer);
// 적당한 HTML(JSP) 응답
RequestDispatcher rd
= req.getRequestDispatcher("/WEB-INF/chap04/result.jsp");
rd.forward(req,resp);
}
}
package com.jsp.repository;
import com.jsp.chap05.Person;
import com.jsp.entity.Dancer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
// 역할: 실제 데이터베이스에 댄서들을 CRUD
// Model
public class DancerJdbcRepo {
private static DancerJdbcRepo repo = new DancerJdbcRepo();
// 싱글톤 구현
private DancerJdbcRepo() {
}
// 싱글객체를 리턴하는 메서드
public static DancerJdbcRepo getInstance() {
return repo;
}
private String username = "root"; // db계정명
private String password = "mariadb"; // db 패스워드
private String url = "jdbc:mariadb://localhost:3307/spring5"; // db url : 데이터베이스 설치 위치
private String driverClassName = "org.mariadb.jdbc.Driver"; // db벤더별 전용 커넥터 클래스
// 댄서를 데이터베이스에 저장하는 기능
public boolean save(Dancer dancer) {
try (Connection conn
= DriverManager.getConnection(url, username, password)) {
Class.forName(driverClassName);
String sql = "INSERT INTO tbl_dancer " +
"(name, crew_name, dance_level) " +
"VALUES (?, ?, ?)";
// 4. SQL 실행 객체 생성
PreparedStatement pstmt = conn.prepareStatement(sql);
// 5. ? 값 채우기
pstmt.setString(1, dancer.getName());
pstmt.setString(2, dancer.getCrewName());
pstmt.setString(3, dancer.getDanceLevel().toString());
// 6. 실행 명령
// INSERT, UPDATE, DELETE 같은 명령을 사용
pstmt.executeUpdate();
return true;
// 7. 데이터베이스 연결 해제
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// 댄서리스트를 반환하는 기능
public List<Dancer> retrieve() {
try (Connection conn // 테이블이 정보를 가지고있음
= DriverManager.getConnection(url, username, password)) {
Class.forName(driverClassName);
String sql = "SELECT * FROM tbl_dancer " +
"ORDER BY id DESC";
// SQL 실행 객체 생성
PreparedStatement pstmt = conn.prepareStatement(sql);
// ? 채우기
// 실행 명령 - SELECT는 다른 메서드를 사용
// ResultSet : SELECT의 결과집합 표를 가져옴
ResultSet rs = pstmt.executeQuery();
// ResultSet 데이터 가져오기
List<Dancer> dancerList = new ArrayList<>();
while (rs.next()) { // rs.next(): 표의 행을 지목하는 커서
// 커서가 가리키는 행의 데이터를 하나씩 추출
int id = rs.getInt("id");
String name = rs.getString("name");
String crewName = rs.getString("crew_name");
String danceLevel = rs.getString("dance_level");
Dancer dancer = new Dancer();
dancer.setName(name);
dancer.setCrewName(crewName);
dancer.setDanceLevel(Dancer.DanceLevel.valueOf(danceLevel));
dancerList.add(dancer);
}
return dancerList;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- <%
String name = (String) request.getAttribute("name");
String crew = (String) request.getAttribute("crew");
%> -->
<h1>댄서 등록 결과페이지 입니다.</h1>
<h2>${d.name}님(소속: ${d.crewName})이 정상 등록되었습니다~~</h2>
<h3>댄스 수준: ${d.danceLevel}</h3>
<a href="/chap04/dancer/form">새로운 댄서 등록하러 가기</a> <br>
<a href="/chap04/show-list">댄서 목록 조회하기</a> <br>
</body>
</html>
package com.jsp.chap04;
import com.jsp.entity.Dancer;
import com.jsp.repository.DancerJdbcRepo;
import com.jsp.repository.DancerMemoryRepo;
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 java.io.IOException;
import java.util.List;
// 역할: 댄서 목록 조회 요청을 받아서 데이터베이스에 있는 댄서 정보를
// 가져온 후 적당한 HTML을 찾아서 forwarding
@WebServlet("/chap04/show-list")
public class ShowDancerListServlet extends HttpServlet {
private DancerJdbcRepo repo = DancerJdbcRepo.getInstance();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 데이터베이스에 접근하여 댄서 목록을 가져옴
List<Dancer> dancerList = repo.retrieve();
// 가져온 댄서 목록을 JSP를 통해 디자인
// JSP파일에게 보낼 데이터 수송객체에 담기
req.setAttribute("dancers", dancerList);
// JSP 파일 열기
RequestDispatcher rd
= req.getRequestDispatcher("/WEB-INF/chap04/dancer-list.jsp");
rd.forward(req, resp);
}
}