2023.06.14 ~ 2023.06.15 수업
- 자바 웹 개발 워크북 참고 45p~
● MVC 구조와 서블릿/JSP
- 서블릿 코드의 경우 자바 코드를 그대로 이용할 수 있지만 HTML처리는 번거로움
- JPS의 경우 HTML코드를 바로 사용할 수 있으므로 HTTP 메시지 작성에 적합
-> 서블릿이 컨트롤러의 역할 JSP가 뷰 역할을 담당
- 브라우저는 서블릿(컨트롤러)을 호출하고 컨트롤러를 통해 JSP에 접근함
◎ MVC 구조
'model - view - controller'
- 데이터는 컨트롤러에서 결과는 뷰에서 처리
- 서블릿은 JSP에 필요한 데이터를 가공하는 역할을 하는데 이때 필요한 데이터를 제공하는 객체를 Model이라고 함
* jsp로 뷰를 만들기
- HTML코드를 바로 사용할 수 있음
* Servlet으로 컨트롤러 만들기
- 자바 코드를 바로 사용할 수 있음
- 상속, 인터페이스 활용
-> 브라우저(클라이언트)의 요청이 서블릿에 전달되고 서블릿 내부에서는 응답에 필요한 데이터를 준비하여 JSP에 전달하고 JSP는 EL(Expression Language)을 이용하여 최종 데이터를 생성함
* EL : sysout과 유사
- 요청 > 서블릿 > JSP > 응답
서블릿 : 클라이언트 상대
JSP : 컨트롤러(서블릿)를 통해 뷰 생성 (비동기 프로그래밍)
* view
입력화면은 Get으로 설계
post방식으로 호출되는 화면 설계
* 전달 객체
RequestDispatcher : 서블릿에 전달된 요청을 다른 쪽으로 전달
- 매개체를 통해 방향을 바꿔 전달
-> jsp가 직접 요청을 받은 것이 아니라서 매개체 필요
-> 보안영역에 jsp파일이 있어서 간접적으로 접근하기 때문
* 전달 메소드
forward : 받은 것을 그대로 넘김
- 이전의 정보를 가지고 새로운 것을 추가함
Redirect : 단순히 방향을 바꿔 전달
- 내용물은 상관 없음, 새로운 시작임
▶ 실습
2023.06.20 - [백엔드/JSP & Servlet] - JSP / Servlet - 5(웹 프로젝트의 기본 구조)
JSP / Servlet - 5(웹 프로젝트의 기본 구조)
2023.06.14 수업 참고 교재 - 자바 웹 개발 워크북(16p~ ) ● 이론 * 웹 프로젝트의 기본 구조 브라우저 서버 데이터베이스 * 인텔리제이 - 통합 개발 도구(ex. 이클립스, VS Code) - 커뮤니티(무료) / 얼티
dustj0824.tistory.com
이어서
▷ calc 폴더 위치 변경 : WEB-INF
* WEB-INF은 브라우저에서 직접 접근이 불가능한 경로임
- InputController(서블릿)를 통하여 jsp에 접근
- RequestDispatcher : 서블릿에 전달된 요청을 다른쪽으로 전달 혹은 배포 역할을 하는 객체로 InputController가 jsp에 도달하는 경유지의 역할을 함
※웹 경로 설정하는 법
- 사용자에게 보이는 경로를 수정
- 프로젝트명을 생략하기
* 웹루트 // : 최상위 경로
* 컨텍스트 웹루트
- 경로가 프로젝트로 시작을 하여 에러
/JavaWeb를 최상위루트로 설정함
* 모듈설정
프로젝트에서 실행을 하면 http://localhost:9000/JavaWeb/ 으로 시작을 해야하나
JavaWeb/이하부터 실제 웹루트로 설정하여 JavaWeb(프로젝트명)을 생략하여 주소를 짧게 만들기
- Servers > 톰캣 > Modules > Path클릭 > Edit
-> 프로젝트명 없이 링크로 바로 접속 가능
* 웹루트의 실제경로가 /경로에서 자식폴더 /JavaWeb/으로 변경함
이제 http://localhost:9000/의 실제 파일 위치가 /JavaWeb/아래로 변경이 됨
JavaWeb : 메인폴더
-> 프로젝트를 만들면 http://localhost:9000/JavaWeb/ 가 생성됨
calc/input : 상대적 주소
http://localhost:9000/calc/input 가 실제 경로이나
현실적으로는 웹서비스 부모폴더(JavaWeb)를 누락시킴
(참고) /웹루트(게시판 사이트의 주소)
http://localhost[:80]/
https://localhost[:443]/
-> 이하부터 웹서비스 시작폴더(루트)
http://localhost[:80]/bbs
https://localhost[:443]/bbs
-> 웹루트의 서비스 중에서 bbs웹서비스의 시작폴더
* 컨텍스트 웹루트
http://localhost/웹서비스 시작명
컨텍스트명 = 프로젝트명
자바웹으로 실행하면 자바웹이 루트이다
▶ 코드 작성
1. 컨트롤러에서 뷰 호출
▷ 서블릿 만들기
프로젝트 : JavaWeb
패키지 : org.zerock.w1.calc
서블릿명 : InputController
-> 기본골격이 생성됨(doGet만 남기고 필요없는 것 지우기)
- get만 처리
- 서블릿 이름은 실제 서블릿객체와 연결됨
package org.zerock.w1.calc;
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;
/**
* Servlet implementation class InputController
*/
@WebServlet(name ="inputController", urlPatterns = "/calc/input")
public class InputController extends HttpServlet {
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 보안구역(WEB_INF/calc/input.jsp)에 외부에서 바로 직접 접근하지
// 못하므로 InputController객체를 통하여 간접적으로 접근을 함
System.out.println("InputController ... doGet() ..."); // 콘솔로그
// 서블릿을 사용한 보안구역 간접호출
RequestDispatcher dispatcher =
// 요청을 중개하겠다
request.getRequestDispatcher(
"/WEB-INF/calc/input.jsp");
dispatcher.forward(request, response);
}
}
@WebServlet 어노테이션은 요청이 들어오면 실행 할 서블릿을 매칭해줌
- 같은 이름의 서블릿이 존재할 수 있기 때문에 name과 urlPatterns을 활용하여 별칭url을 이용
-> urlPatterns주소로 들어오면 name이 실행됨
* 기본생성자는 자동으로 생성되기 때문에 지우기
/calc/input 요청 (실제 서블릿 : InputController)
웹브라우저 <--------------------> WAS(톰캣)
* InputController가 할 일
1) /calc/input 주소의 전권을 가짐
2) 요청화면(view)를 호출할 권한
3) 이 view는 웹브라우저에서 직접 접근 금지
-> 중간매개체 역할
* 보안구역(WEB-INF/calc/input.jsp)에 외부에서 바로 직접 접근하지 못하므로 InputController객체를 통하여 간접적으로 접근을 함
웹 요청이 발생하면 그 요청에 대한 요청객체와 응답객체는 한쌍이므로 이 객체들을 보안구역에 넘겨주고 input.jsp가 실행되도록 해야함
이 기능을 하는 클래스 : RequestDispatcher 클래스
이 클래스는 객체를 생성할때 호출할 jsp파일이나 서블릿을 등록
이렇게 생성된 객체에 한쌍의 요청객체와 응답객체를 넘겨주면 등록된 호출객체가 실행한 결과(HTML이나 문서)를 응답객체를 통해 웹브라우저로 돌려줌
-> 외부에서는 접근하지 못하지만 내부에서는 접근이 가능함, 내부에서 접근하는 중간매개체를 만들어서 외부로 송출
☆ 의문점 :
1) dispatcher.forward 둘 다 전달객체가 아닌가,,?
- dispatcher는 전달 객체이고 forward는 RequestDispatcher에 있는 메소드임
- forward : 실행할때 필요한 정보를 넘겨줌
2) name의 이름은 왜 소문자인가 ?
- name에는 서블릿의 별명을 적는 곳이라 아무 단어나 상관없음
- 객체라는 표식을 위해 소문자로 적음
* 시퀀스 다이어그램
순차적으로 발생
일이 진행되는 방향으로 화살표
2. post 방식을 통한 처리요청
▷ 서블릿 만들기
프로젝트 : JavaWeb
패키지 : org.zerock.w1.calc
클래스 : CalcController
- post만 처리
- 사용자가 입력한 숫자의 처리 전송을 처리하는 컨트롤러 역할
* WEB-INF/calc/input.jsp 의 <form>태그 수정하기
<form action="/calc/makeResult" method="post">
package org.zerock.w1.calc;
import java.io.IOException;
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 CalcController
*/
@WebServlet(name = "calcController", urlPatterns ="/calc/makeResult")
public class CalcController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 두 수를 입력받아 두 수의 합을 구하고 각 변수 출력
String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
System.out.printf("num1 : %s", num1);
System.out.printf("num2 : %s", num2);
// 빠른 응답 후 다른 페이지로 보냄
response.sendRedirect("/index");
}
}
- 브라우저로부터 입력받은 값은 문자열임 , 계산을 위해 문자열을 숫자로 변환해주어야함(Integer.parseInt)
2-1. sendRedirect()
- post 방식의 처리는 다른 페이지를 보도록 브라우저 화면을 이동시키는 것이 좋음
- CalcController는 보여줄 결과를 만들지 않기 때문에 브라우저에는 변화가 없어 계속 send 할 수 있다
- 계속 전송 가능하게 하면 데이터베이스의 저장공간이 늘어나는 등 위험함
-> 전송을 클릭하면 경고 메시지 뜨게 설정 등으로 활용
* response.sendRedirect("/index");
- sendRedirect를 통해 시작페이지로 보냄
get은 양식화면, 검색결과를 가져오는 것이 목적
post는 받아온 데이터 처리가 목적
* 실행하기(Run as)
● 게시판(bbs) 만들기
- PRG 패턴을 이용하여 'Todo List' 만들기
* PRG패턴(Post-Redirect-GET)
post방식과 Redirect를 결합하여 사용하는 패턴
ex. 게시판의 write
p : post 방식으로 데이터 처리 요청
r : 브라우저는 이동해야하는 주소를 받음
g : 브라우저는 get 방식으로 서버 호출
send하면 새로운 세션이 만들어짐
-> send를 계속하지 못하게 만들어야함
ex. 싱글톤 패턴, 알림창 띄우기
* PRG패턴을 이용하여 와이어프레임 작성하기
* 와이어프레임 : 설계를 통하여 어떤 흐름으로 동작하게되는지 미리 구성
종류 : 피그마, 어도비, PPT
* 와이어프레임의 구현
목록(get) TodoListController
등록[입력](get) TodoResisterController
등록[처리](post) TodoResisterController
조회(get) TodoReadController
수정[입력](get) TodoModifiyController
수정[처리](post) TodoModifiyController
삭제[처리] TodoRemoveController
▷ webapp아래 calc폴더 만들고 그 아래 index.html파일 만들기
- 브라우저에서 한글이 보이는지 확인하기 위한 파일
-> 외부에서 만들기
- 외부 폴더에서 작업하면 이클립스(sts)에서 Refresh하기
-> 실행하면 한글이 깨져보임
-> ! 독타입 ~ 작성하여 <body></body> 안에 내용 작성하면 한글이 보임
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
▷ webapp WEB-INF아래 index.jsp만들기
- 브라우저에서 접근이 가능한지 확인하기 위한 파일
-> http://localhost:9000/JavaWeb/WEB-INF/index.jsp는 404에러
- 서블릿은 Request를 통해 WEB-INF에 접근 가능
다이나믹 웹 프로젝트를 만들면 웹서비스루트(ex. calc)가 됨
* localhost/JavaWeb/ 를 localhost/ 로 변경하기(JavaWeb를 감춤)
- Servers > 톰캣 > Modules > Path클릭 > Edit
-> 설정하고 충돌이 발생하면 이클립스를 중지시키고 다시 실행하기
웹서비스폴더 : 실행이 됨
*(참고) index와 index.jsp는 다름
뒤에 아무것도 안붙으면 서블릿임
* 개발자도구 Network의 Headers(헤더) / Payload(바디) 임
● HttpServlet 자바 웹 개발 워크북 - 60p
- HttpServlet은 GET/POST에 맞게 doGet, doPost를 제공함
- HttpServlet를 상속함으로 WAS 내부에서 자동으로 객체를 생성하고 관리함
- 멀티스레드에 의해서 동시에 실행될 수 있음
* HttpServlet 의 라이프 사이클
- 서블릿은 웹이라는 특수한 환경으로 인해 개발자가 직접 객체를 생성하는 대신 톰캣에서 객체들을 관리함
1) 서블릿의 객체는 경로에 맞게 하나만 만들어짐
2) 매번 호출시에는 자동으로 doGet, doPost를 이용하여 처리됨
▶ 실습
▷서블릿 직접 만들기
- 실제동작 확인하기
패키지명 : org.zerock.w1
클래스명 : SampleServlet
1) HttpServlet 상속받기
2) @WebServlet 어노테이션 작성하기
3) 메소드 작성하기
- doGet, doPost, init, distroy
package org.zerock.w1;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "sampleServlet", urlPatterns = "/sample") // 특정 경로로 호출
public class SampleServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) {
System.out.println("...SampleServlet ... doGet()" + this);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res) {
System.out.println("...SampleServlet ... doPost()" + this);
}
@Override // 초기화 메소드
public void init() {
System.out.println("...SampleServlet ... init()");
}
@Override // 제거 메소드
public void destroy() {
System.out.println("...SampleServlet ... distroy()");
}
}
-> doGet(종료 시 까지 실행), init(1회 실행)
▷ web.xml 생성하기
4) 실행하기
- 새로고침해도 init는 1회만 실행됨
- 해쉬코드는 동일
-> 서블릿은 한개만 만들어짐을 알 수 있음
(생성자를 초기화 도구로 사용하면 오류가 발생할 수 있음)
※ HttpServletRequest의 기능 : 읽기
* HTTP 헤더관련
getHeaderNames() : 모두 가져와라
getHeader(이름) : 특정이름을 가져와라
* 사용자관련
getRemoteAddress() : 접속한 사용자(클라이언트)의 IP주소
* 요청관련
getMethod()
getRequestURL()
getRequestURI()
getServletPath()
* 쿼리스트링 관련 : 데이터를 추출하는 용도
getParameter()
getParameterValues()
getParameterNames()
* 쿠키관련 : 브라우저가 전송한 쿠키정보
getCookies()
* 전달관련 :
getRequestDispatcher()
* 데이터 저장 : 전달하기 전에 필요한 데이터를 저장하는 경우에 사용
setAttribute()
※ HttpServletResponse의 기능 : 쓰기
* MIME타입
setContentType() : 응답 데이터의 종류를 지정(이미지/html/xml 등)
* 헤더관련
setHeader: 특정 이름의 HTTP헤더 지정
* 상태관련
setStatus: 404, 200, 500등 응답 메시지 작성
* 출력관련
getWriter() : PrintWriter를 이용하여 응답 메시지 작성
* 쿠키관련
addCookie() : 응답 시 특정 쿠키 추가
* 전달관련
sendRedirect() : 브라우저에 이동을 지시
▷ToDoListController 구현
- list 보여주는 클래스 만들기
패키지명 : org.zerock.w1.todo
클래스명 : ToDoListController
- 아직 jsp가 구현되지 않았으므로 sysout을 활용하여 동작여부만 확인하기
package org.zerock.w1.todo;
import java.io.IOException;
import java.util.List;
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 org.zerock.w1.todo.dto.TodoDTO;
import org.zerock.w1.todo.service.TodoService;
@WebServlet(name = "toDoListController", urlPatterns = "/todo/list")
public class ToDoListController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
System.out.println("/todo/list");
// 정석
RequestDispatcher rd =
req.getRequestDispatcher("/WEB-INF/todo/list.jsp");
rd.forward(req, res);
}
}
▷ list.jsp 구현하기
WEB-INP하위에 todo폴더 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>제목은 여기에</title>
</head>
<body>
<h1>List Page</h1>
</body>
</html>
- 실행하면 페이지 보임
'백엔드 > 웹 개발' 카테고리의 다른 글
10 (JDBC 프로그래밍 준비) (0) | 2023.06.23 |
---|---|
9 (EL 표현식) (0) | 2023.06.23 |
8(JSTL + 게시판 만들기) (0) | 2023.06.22 |
7 (게시판 만들기) (0) | 2023.06.22 |
5(웹 프로젝트의 기본 구조) (0) | 2023.06.20 |