Model
데이터를 처리하는 영역(어떠한 동작을 수행하며 public 함수로만 이루어진다.)
View
컨트롤러의 처리결과를 화면에 생성
Controller
클라이언트의 요청 처리
사용하는 이유?
사용자 인터페이스로부터 비즈니스 로직을 분리한다. (=개발자, 웹 퍼블리셔의 영역 분리 가능)
> 애플리케이션의 시작적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 고칠 수 있다.
> view 교체, 변경 쉬워서 유지보수가 유용하다.
service
핵심 비즈니스 로직 구현
repository (= DAO : Data Access Object)
- Spring data JPA방식
- 도메인 객체를 DB에 접근하여 저장하고 관리 (저장소)
- interface로 사용
domain (= VO : Value Object , DTO : Data Transfer Objec , model)
비즈니스 도메인 객체, ex) 회원,주문,상품.. 주로 DB에 저장하고 관리됨 (엔티티)
디스패처 서블릿(DispatcherServlet)
유일한 서블릿 클래스로서 모든 클라이언트의 요청을 가장 먼저 처리하는 Front Controller(클라이언트 요청의 진입점)
웹 애플리케이션의 모든 클라이언트 요청을 처리하는 역할을 수행
<순서>
1. **클라이언트 요청 처리**
클라이언트가 보낸 요청이 DispatcherServlet에 도착, 어떤 컨트롤러가 요청을 처리할지를 결정
2. **HandlerMapping 사용**
클라이언트의 요청을 처리할 Controller(java)를 매핑 (어떤 컨트롤러를 선택할지를 결정)
+원하는 beans properties를 찾아오는 역할 수행
3. **컨트롤러 호출**
선택된 컨트롤러를 호출하여 실제 비즈니스 로직을 수행
4. **뷰 선택 및 데이터 전달**
컨트롤러가 처리한 결과데이터를 뷰(View)에 전달
5. **응답 생성**
뷰는 전달받은 데이터를 기반으로 클라이언트에게 보여줄 응답을 생성
이 응답은 HTML, CSS, JavaScript 등을 사용하여 웹 페이지로 구성되며,
클라이언트가 브라우저를 통해 볼 수 있는 형태로 제공
- **Bean Properties**
빈(Bean) 객체의 설정 정보를 담은 파일, 각 빈 객체의 이름과 해당하는 클래스, 속성 등의 설정 정보를 포함
1. 서블릿은 클라이언트의 모든 요청만 수신
2. 실제 비즈니스 로직은 자바 코드로 구현한 컨트롤러에서 처리
3. 데이터베이스에 접근하여 필요한 정보를 가져옴
dispacherservlet
package kr.co.mlec.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 유일한 서블릿 클래스 : 클라이언트의 요청을 가장 먼저 처리
public class DispatcherServlet extends HttpServlet {
private HandlerMapping mappings = null;
/*HandlerMapping: 클라이언트의 요청을 처리할 Controller(java)를 매핑
beans properties를 찾아와야하니까
*/
//매핑 :해당 값이 다른 값을 가리키도록 하는 것
/*서블렛 요청 호출 순서
1.init :메소드 사용하여 초기화 작업 수행
2.service: 사용자 요청에 대한 실제 응답 처리
3.destroy
*/
//servlet-> HandlerMapping
@Override //config : 환경 설정 , 예외를 던져
public void init(ServletConfig config) throws ServletException {
String propLoc =config.getInitParameter("propLocation");
mappings = new HandlerMapping(propLoc);
}
@Override
//controller 인터페이스 재정의 + 실제응답처리
//request 요청 : uri
//responce 응답 : contextPath 받아옴
public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
//uri: identify
String uri = request.getRequestURI();
String context = request.getContextPath();
//응답을 받아와야하니까 get, url주소를 가져오는 함수
uri = uri.substring(context.length()); //문자 추출
System.out.println("요청 URI : " + uri); //가져온 uri 출력
try { //session 때매?
Controller control = mappings.getController(uri);
// 인터페이스 변수 = 요청한 uri 가져오려고 매핑+get
String callPage = control.handleRequest(request, response);
// callPage : 인터페이스 control에서 재정의, uri 정보 담겨있음
//servlet이 jsp에 넘겨주려고 forward ->jsp 주소 알려줌
//uri 넘겨줄거임
RequestDispatcher dispatcher = request.getRequestDispatcher(callPage);
dispatcher.forward(request, response);
} catch(Exception e) {
e.printStackTrace();
throw new ServletException(e);
}
}
}
request.getContextPath() : 프로젝트 path만 얻어온다.
예) http://localhost:8081/board /list.jsp
return: /board
request.getRequestURI() : 프로젝트와 파일경로까지 얻어온다.
예) http://localhost:8081/board/list.jsp
return: /board/list.jsp
package kr.co.mlec.controller;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class HandlerMapping {
// 원하는 beans properties를 찾아오는 역할을 수행 ->매핑
//키 , 값
private Map<String, Controller> mappings = null;
///board/list.do 가져와
public HandlerMapping(String propLoc) {
//Properties 주요 클래스 :Key = Value 형태로 된 파일 가져와
Properties prop = new Properties();
mappings = new HashMap<>();
try {
//InputStream is = new FileInputStream("D:\\Lecture\\web-workspace\\Mission-Web-MVC\\bean.properties");
InputStream is = new FileInputStream(propLoc);
//inputStream : 데이터를 읽어옴
prop.load(is);
Set<Object> keys = prop.keySet(); //keySet: key의 값만 출력
for(Object key : keys) { //keys값 key에 넣어서 죄다 출력
String className = prop.getProperty(key.toString()); //key 객체타입이라 형변환
System.out.println(key + " : " + className);
Class<?> clz = Class.forName(className);
//클래스의 정보를 얻기위한 클래스
//forName():물리적인 클래스 파일명을 인자로 넣어주면 이에 해당하는 클래스를 반환
mappings.put(key.toString(), (Controller)clz.newInstance());
}
} catch(Exception e) {
e.printStackTrace();
}
}
public Controller getController(String uri) {
return mappings.get(uri);
}}
bean.properties
요청(String) = 응답(Controller)
/board/list.do=kr.co.mlec.controller.BoardListController
/board/writeForm.do=kr.co.mlec.controller.BoardWriteFormController
interface Controller
인터페이스를 중간에 두는 이유는 개발 코드를 수정하지 않고, 사용하는 객체를 변경할 수 있도록 하기 위해서
package kr.co.mlec.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Controller {
String handleRequest(HttpServletRequest request, HttpServletResponse response)throws Exception;
}
BoardListController
package kr.co.mlec.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.co.mlec.board.vo.BoardVO;
// /board/list.do (전체리스트조회)호출되었을 때
// 1. 비즈니스 로직 수행 (tbl_board에서 전체게시글 조회)
// 2. servlet에게 forward 시킬 jsp/board/list/jsp 알려줌
public class BoardListController implements Controller {
//controller 인터페이스 상속 받아 안의 내용 사용
@Override
public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{ //String으로 받는 이유는 jsp주소값으로 받기 때문에
List<BoardVO> list = new ArrayList<>();
list.add(new BoardVO("aaa","bbb"));
list.add(new BoardVO("ccc","ddd"));
list.add(new BoardVO("eee","fff"));
request.setAttribute("list", list);
//공유영역인 request에 등록해 준다.
return "/jsp/board/list.jsp";
}
}
BoardWriteFormController
package kr.co.mlec.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BoardWriteFormController implements Controller{
@Override
public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{
return "/jsp/board/write.jsp"; //절대경로
}
}
list.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>
</head>
<body>
<h2>전체게시글</h2>
<table border="1">
<tr>
<th>제목</th>
<th>작성자</th>
</tr>
<c:forEach items="${ list }" var="board">
<tr>
<td>${ board.title }</td>
<td>${ board.writer }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
'WEB JAVA SPRING > etc' 카테고리의 다른 글
JSON 배열 다루기 (0) | 2023.10.05 |
---|---|
객체지향 프로그래밍의 4가지 특징 (0) | 2023.08.28 |
Spring 어노테이션 (0) | 2023.08.28 |
Spring Security 인증/인가 (0) | 2023.08.28 |
Spring Data JPA(Java Persistence API) (0) | 2023.08.28 |