JSP 수업 #06 MVC 패턴 (2) 상품리스트, 세부정보 구현 (진행중)

sookyoung.k·2022년 12월 22일
0

JSP

목록 보기
8/8

view - productList.jsp / productInfo.jsp

controller - ProductController.java

model - Product.java(DO) (, ProductService.java)


Product.java: 상품 정보를 표기하기 위한 DO
ProductService: 데이터베이스 없이 샘플 데이터를 제공하기 위한 클래스
[기본 원리] 뷰에서 컨트롤러에 요청을 하면, 컨트롤러는 모델에서 데이터를 받아와 뷰에 포워딩해준다.

🎃 view

productList.jsp 구현

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>상품목록</h2>
	<hr>
	<table border="1">
		<tr>
			<th>번호</th>
			<th>상품명</th>
			<th>가격</th>
		</tr>
		<!-- for(Product p : products) -->
		<c:forEach var="p" varStatus="i" items="${products}">
			<tr>
				<td>${i.count}</td>
				<%--쿼리스트링! 잘 복습하고 기억해두자...?action=키&info=데이터--%>
				<td><a href="/jsp_study/pcontrol?action=info&id=${p.id}">${p.name}</a></td>
				<td>${p.price}</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

이 부분은 JSTL을 사용한 것이다. JSTL은 JSP 표준 태그 라이브러리의 약어이고, 자신만의 태그를 추가할 수 있는 기능을 제공한다.

다운받은 lib을 WEB-INF/lib에 추가해서 넣고 위처럼 선언해주면 된다!

html로 구현한 화면.

<c:forEach var="p" varStatus="i" items="${products}">
이 부분은 자바의 for문과 유사하게 사용하는 jstl 태그. 반복문을 수행할 수 있게 해준다.
var: 변수명을 'p'로 선언! -> for문 내부에서 사용할 변수명이다.
items: ${리스트가 받아올 배열 이름} -> 우리는 products라는 배열을 받아올 것이라는 의미다.
varStatus: 상태용변수... 라는데 이게 조금 어려운 것 다. 상태용 변수를 지정하면 다양하게 활용이 가능하다는데 여기선 활용을 하지 않은듯?
예를 들어 ${i.current}를 사용하면 현재 for문에 해당하는 번호를 얻을 수 있고 ${i.index}를 사용하면 0부터의 순서를 얻을 수 있고... 등등의 기능이 있는 것 같다.

productInfo.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>
	<ul>
		<li>상품코드: ${p.id}</li>
		<li>상품명: ${p.name}</li>
		<li>제조사: ${p.maker}</li>
		<li>가격: ${p.price}</li>
		<li>등록일: ${p.date}</li>
	</ul>
</body>
</html>

구현된 화면은 아래와 같다.

데이터를 넣어주면... 들어가겠죠.

🎄 controller

ProductController.java 구현

package ch08;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ProductController
 */
@WebServlet("/pcontrol")
public class ProductController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	ProductService service;

	
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		//서블릿이 초기화 될 때 ProductService 객체를 생성 
		service = new ProductService();
	}
	
	

	//클라이언트에서 request가 오면 service가 실행된다. 
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action"); // action 파라미터의 값을 얻어온다. 
		String view = "";
		
		if (action == null) {
			getServletContext().getRequestDispatcher("/pcontrol?action=list").forward(request, response);
		} else {
			switch(action) {
			case "list": view = list(request, response); break;
			case "info": view = info(request, response); break;
			}
			
			getServletContext().getRequestDispatcher("/ch08/" + view).forward(request, response);
		}
	}


	private String info(HttpServletRequest request, HttpServletResponse response) {
		// 한 가지 상품만 가져온다. 
		Product p = service.find(request.getParameter("id"));
		request.setAttribute("p", p);
		return "productInfo.jsp"; 
	}



	private String list(HttpServletRequest request, HttpServletResponse response) {
		// 모든 상품을 가져온다.
		List<Product> plist = service.findAll();
		request.setAttribute("products", plist);
		return "productList.jsp";
	}
}

@WebServlet("/pcontrol") : @WebServlet 어노테이션!! @WebServlet("url")을 적어서 사용하면 된다.

@WebServlet 어노테이션은 name, value 키워드를 통해서 하나 혹은 다수의 url을 연결할 수 있다.

public class ProductController extends HttpServlet : HttpServlet은 서블릿이 웹상에서 HTTP프로토콜을 이용하여 서비스를 처리하기 위해서 반드시 상속 받아야 하는 클래스이다. 모든 서블릿 클래스의 상위 클래스는 HttpServlet이다.

public void init(ServletConfig config) throws ServletException: init()메소드는 서블릿이 최초로 호출되었을 때 서블릿 컨테이너가 자동으로 실행한다. 최초의 한 번만 실행되고, 서블릿의 초기화 작업을 담당한다.

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException: service()메소드는 클라이언트의 요청이 있을 때마다 서블릿 컨테이너가 자동으로 실행한다. 서블릿 실행 요청이 있을 때마다 실행되어야 하는 내용을 구현하는 역할을 한다.

Servlet에서 값을 받는 메소드가 몇 가지 있는데, 그 중 request.getParameter("name");- 전송한 값들 중 지정한 "name"을 String 값으로 가져온다.
(HttpServletRequest 객체를 이용하여 파라미터 값을 얻는다.)

String action = request.getParameter("action"); : action 파라미터 값을 얻어온다는 의미!

String view = ""; : 일단 빈 문자열 값을 가지고 있음.

if (action == null): if문 시작. action 값이 null일때!
getServletContext().getRequestDispatcher("/pcontrol?action=list").forward(request, response); 코드를 실행한다.

getServletContext().getRequestDispatcher("/pcontrol?action=list").forward(request, response);: ServletContext는 서블릿 컨테이너와 통신하기 위해 사용되는 메소드를 지원하는 인터페이스다. 서블릿 컨텡너가 시작될 때 WAS를 통해 ServletContext 객체가 자동으로 생성된다. 이는 웸 애플리케이션 서비스가 중지될 때 소멸된다. getServletContext()는 ServletContext 인터페이스 객체를 얻기 위한 메소드이다. ServletConfig의 메소드! 객체를 얻었으니 거기서 getRequestDispatcher() 메소드 호출. RequestDispatcher는 클라이언트로부터 최초로 들어온 요청을 JSP 내에서 원하는 자원으로 요청을 넘기는 역할을 수행한다. getRequestDispatcher() 메소드의 값으로 이동할 페이지의 경로를 지정한다. pcontrol 서블렛에 넘겨주고 action이 list인 페이지로 경로를 넘겨준다는 것임. forward()메소드는 페이지를 이동시키는 메소드이다. forward()는 클라이언트가 요청하면서 전송한 데이터를 그대로 유지한다. 때문에 포워딩이 되더라도 주소가 변경되지 않고 같은 request 영역을 공유한다.

else: action이 null 값이 아닌 경우!

switch(action): switch문을 사용하여 코드 작성

case "list": view = list(request, response); break; : action값이 list인 경우! list를 view에 저장.

case "info": view = info(request, response); break; : action값이 info인 경우에는 info를 view에 저장.

getServletContext().getRequestDispatcher("/ch08/" + view).forward(request, response); : switch문을 빠져나와서 페이지를 이동시킨다. 경로는 /ch08/ 뒤에 저장된 view값을 넣어준다. 그렇다면 /ch08/list 혹은 /ch08/info로 페이지 이동이 일어날 것이다.

하 근데 그러면... info 메소드랑 list 메소드는 언제 실행이 되는거지...? 진짜 눈물난다. 뭐가 뭔지 모르겠어.
이건 다음에 질문을 하는거로 하고...

++ 아!! 시발 퀴즈 풀다가 알아냈다!! action 값이 list일 때!! 아래에 만들어둔 list() 메소드가 실행되는 것이고... action값이 info일 때는 info() 메소드가 실행되는 것!!!

하하 시발 하다보니까 알게 됨. 좆같다 좆같아.

🎋 model

Product.java(DO) 구현

package ch08;

public class Product {
	// 필드(=속성)
	// 상품 정보와 관련된 리스트를 만들어야 하니까 상품에 대한 클래스를 만든다.
	private String id;
	private String name;
	private String maker;
	private int price;
	private String date;
	
	// 생성자
	public Product(String id, String name, String maker, int price, String date) {
		this.id = id;
		this.name = name;
		this.maker = maker;
		this.price = price;
		this.date = date;
	}

	// getter, setter 
	public String getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public String getMaker() {
		return maker;
	}

	public void setMaker(String maker) {
		this.maker = maker;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}
	
	
}

db와 연동될 클래스 = 상품에 대한 클래스이다.
필드(속성)은 db의 컬럼들이 하나씩 매칭될 것.

ProductService.java 구현

package ch08;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 데이터 샘플을 제공해주는 클래스 
public class ProductService {
	//"키", "값"을 저장할 수 있다. 
	Map<String, Product> products = new HashMap<>();
	
	public ProductService() {
		Product p = new Product("101", "아이폰12", "애플", 1200000, "2020.12.12");
		products.put("101", p);
		p = new Product("102", "삼전우주폰", "삼성전자", 1300000, "2021.2.2");
		products.put("102", p);
		p = new Product("103", "엘스듀얼폰", "엘스전자", 1500000, "2021.3.2");
		products.put("103", p);
	}
	
	// 모든 상품 데이터를 가져오는 메소드 (select * from)
	public List<Product> findAll() {
		return new ArrayList<>(products.values());
	}
	
	// id로 원하는 상품을 가져오는 메소드 (select * from where id="102")
	public Product find(String id) {
		return products.get(id);
	}
}

우린 아직 db와 연결을 하지 않고 구현을 하고 있기 때문에... db 역할을 대신하는 클래스다.

profile
영차영차 😎

0개의 댓글