[1.SERVLET]
ㅁ contextPath 까지의 URL이 곧 webapp 폴더를 가리킨다.
ㅁ 이클립스를 껐다 키면 서버도 종료된다.
- 개발이 끝나고 서버에 배포가 되는 실 서버는 사용자들이 24시간 이용할 수 있게 24시간 열려 있다.
- 지금 우리는 개발서버를 뒀다. 개발 서버는 스타트를 해줘야 접속할 수 있다.
ㅁ 화면구현 파일 열어보기
- http://localhost:8888/servlet/a_lifecycle/main.html를 브라우저에 입력하면 방금 우리가 만든 main.html 문서가 보인다.
- .html뿐 아니라 .jsp 파일도 이렇게 열어볼 수 있다.
- 그런데 <a href="http://localhost:8888/servlet/a_lifecycle/main.html">는 너무 길다.
사실 이미 index.html을 보고 있을 때 contextPath까지는 이미 기술이 되어 있는 거다.
그래서 그냥 <a href="a_lifecycle/main.html">만 써도 된다. (절대경로 방식)
ㅁ Servlet
- 웹 서비스를 위한 Java 클래스를 의미.
- Java를 활용해서 웹 개발을 할 때 필요한 기술.
- 사용자의 요청을 받아 처리하고 그에 해당하는 결과를 다시 사용자에게 응답하는 역할.
즉, MVC 패턴 중에 Controller 역할
- 사용자의 요청을 받아 처리한 후 응답해주는 Java 클래스.
ㅁ 요청
- 요청을 보낸다는 것은 a 태그를 클릭해서 요청을 보낼 수도 있고,
form 태그를 둬서 사용자에게 입력을 받아서 요청을 보낼 수도 있다.
- 요청을 보내는 방식은 크게 두 가지로 나뉜다. get 방식과 post 방식.
ㅁ < Get 방식의 특징 >
- 요청시 전달되는 데이터가 URL의 Header 영역에 포함되어 전달된다.
URL에 데이터가 노출되기 때문에 보안 유지가 불가능하다.
- Header 영역은 전송하는 길이에 대해 제한이 있다.
방대한 데이터를 전송할 경우 초과된 데이터가 절단되어서 넘어감.
- 단, 해당 URL을 즐겨찾기(북마크)할 경우 동일한 데이터를 넘기면서 재요청이 가능하다.
기존에 봤던 페이지를 다시 볼 수 있다.
- Get 방식에 적합한 경우 : 검색요청
- Get 방식에 부적합한 경우 : 로그인 요청, 회원가입 요청, 게시판 작성 및 수정 요청(방대한 데이터)
- 게시글 내용같은거 get 방식으로 하면 안 된다. 내용은 엄청 길어서.
방대한 데이터를 넘길 때는 get방식으로 넘기면 안 된다.
ㅁ < Post 방식 특징 >
- 요청시 전달되는 데이터가 URL의 Body 영역에서 포함돼서 전달
- URL에 데이터가 노출되지 않는다. 보안 유지 가능하다.
- Body 영역은 전송하는 길이에 대한 제한이 없다. 방대한 데이터를 전송할 수 있다.
- 단, 즐겨찾기 후 재요청시 기존의 데이터가 넘어가지 않는다.
기존에 보던 페이지를 다시 바로 볼 수 없다.
- Get 방식에 비해 상대적으로 처리 속도가 느리다.
페이지 요청시 기다리는 시간이 소요될 수 있다.
- Post 방식에 적합한 경우 : 로그인 요청, 회원가입 요청, 게시판 작성 및 수정 요청(방대한 데이터 전송 가능하니까)
- Post 방식에 부적합한 경우 : 검색 요청
ㅁ 단순 페이지 요청이 아닌 Sevlet을 요청해본다.
- url에 서버를 작성하고, 어플리케이션을 작성하고, URLMapping을 쓸 수 있다.
URLMapping이 곧 서블릿을 가리킨다.
ㅁ URLMapping
- 웹 애플리케이션 내부 경로를 의미 (즉, 이 웹 어플리케이션이 가지고 있는 서블릿 같은 걸 지칭할 수 있다.)
- 단순 페이지 요청은 상대경로로 하면 되는데, 서블릿 요청할 때는 절대경로 방식으로 contextPath를 항상 작성하고 URLMapping 값을 작성한다.
- URLMapping을 작성할 때 절대경로방식으로 작성한다면 슬래시로 시작한다.
슬래시로 시작하는 구문을 절대경로방식이라고 한다.
- 절대경로 방식은 서버(ip주소:포트번호)까지만 가리킨다. 그래서 슬래시(/) 뒤에 context path를 작성한다.
※ 이 둘은 같다.
- http://localhost:8888/servlet/life
- /servlet/life
ㅁ 메인페이지
- <a href="/servlet">홈으로 가기</a>
이렇게 context path까지 작성하면 메인페이지가 보여진다.
(web.xml에 작성되어 있기 때문에)
ㅁ Servlet 파일 생성
- 서블릿은 java 클래스이기 때문에 src/main/java에 만든다.
- 패키지를 우클릭하고 new - Servlet을 클릭한다.
- 서블릿도 클래스이기 때문에 클래스 이름을 준다. LifeCycle이라고 짓고 Next를 누른다.
ㅁ Servlet LifeCycle
- 1) 최초 요청일 경우 Servlet 객체 생성(생성자) => init() 메소드 호출
- 2_1) service() 메소드 호출
- 2_2) doGet() 또는 doPost() 호출 (service()메소드가 정의되어있지 않을 경우)
- 3) 더이상 Servlet이 서비스되지 않을 경우 destroy() 호출
(주로 서버종료 / 재컴파일시)
ㅁ service() 메소드
- 클라이언트로 부터 요청을 받을 수 있음 (HttpServletRequest 매개변수)
클라이언트로 응답할 수 있음 (HttpServletResponse 매개변수)
- service() 메소드가 있을 경우 여기서 요청과 응답을 다 처리함 (doGet, doPost 메소드가 있어도)
- service() 메소드가 없을 경우 doGet() 또는 doPost() 메소드가 "요청방식에 따라 호출됨"
- doGet(), doPost() 메소드에 자동으로 코드가 적혀 있는데, service()를 쓸 때 그 두 메소드 내용을 다 지웠다.
ㅁ doGet()
- service() 메소드가 없을 경우 GET 방식 요청시 자동으로 호출된다.
※ GET 방식 요청 케이스
(1) a 태그
<a href='/servlet/life'>
- a 태그는 기본적으로 get방식이다.
(2) form 태그 (method='get')
<form action='/servlet/life' method='get'>
(3) 자바 스크립트방식으로 url 요청
location.href = '/servlet/life';
(4) 팝업창
window.open('/servlet/life');
(5) ajax
$.ajax({
url : '/servlet/life',
type : 'get',
...
});
ㅁ doPost()
- service() 메소드가 없을 경우 POST 방식 요청시 자동으로 호출된다.
※ POST 방식 요청 케이스
(1) form 태그
<form action='/servlet/life' method='post'>
(2) ajax
$.ajax({
url : '/servlet/life',
type : 'post',
...
});
ㅁ 지금처럼 서블릿 클래스의 모든 메소드들을 다 둘 필요는 없고 doGet(), doPost() 메소드만 두고 작업할 예정이다.
- 왜냐면 서블릿이 생성됐을 때, init() 메소드, destroy() 메소드가 실행됐을 때 실행할 내용이 딱히 없다.
- 우리는 요청이 들어왔을 때 요청을 받아서 처리하고 응답해주면 되는데 그때 이제 필요한 메소드가 저 둘이다.
ㅁ 수시로 서버 재시작, project-clean, 브라우저 새로고침
- 아무리 서버를 재구동해도 문제가 없어보이는데도 계속 문제가 발생한다면,
서버를 잠시 멈추고 상단 메뉴 Project - clean 누르면 강제로 소스코드들이 재컴파일된다.
그리고 서버 다시 start하고 요청 보내보기.
- 화면단만 수정한 경우에는 굳이 서버를 재시작하지 않아도 되지만,
자바 코드를 수정한 경우에는 서버를 재시작해야한다.
ㅁ <a href="/servlet/request?name=홍길동&age=20&hobby=sports&hobby=reading">
- 아까까지는 그냥 서블릿 요청만 했다면, 이번엔 요청시 강제로 전달값도 같이 전달 해본다.
- 물음표 뒤는 키=밸류 세트로 넘어가는 데이터로 쿼리 스트링(query string)이라고 한다.
(get 방식의 경우다. url이 보이는 경우니까)
ㅁ < HttpServletRequest >
- 클라이언트의 요청관련 정보가 담겨있는 객체
- doGet() 또는 doPost() 메소드가 실행시 해당 객체가 생성돼서 매개변수(request)에 전달됨.
그래서 이 객체로부터 메소드 호출시 데이터(요청과 관련된 정보)를 꺼낼 수 있다.
- 요청 관련 주요 메소드
(1) getContextPath() : 애플리케이션의 contextPath 반환
(2) getRequestURI() : 요청 URL의 contextPath + URLMapping값 반환
(3) getRequestURL() : 요청 URL의 전체 경로 반환
(4) getParameterMap() : 요청에 포함된 parameter들을 Map<String, String[]> 로 반환
(5) getParameter(String) : 요청에 포함된 parameter 특정 데이터를 "문자열"로 반환
(6) getPrameterValues(String) : 요청에 포함된 parameter 다수의 데이터들을 "문자열 배열"로 반환
(7) setCharacterEncoding(String) : 요청에 포함된 parameter들의 인코딩을 설정하는 메소드
- (1), (5), (6), (7)은 자주 쓴다.
- (5), (6)은 어떤 데이터를 꺼낼건지 그 key를 제시해야한다.
ㅁ parameter(파라미터 = 매개변수)는 요청시 전달되는 값을 의미한다.
- 사용자가 입력한 값도 되고 직접 전달되는 값도 된다.
- 모든 파라미터는 String 타입이다. 숫자여도 문자열의 형식으로 온다.
웹상에서 데이터를 주고받을 때는 문자열의 형식으로만 데이터를 주고받을 수 있다.
- 파라미터를 반환하는 메소드를 사용했는데 전달되는 파라미터 자체가 존재하지 않으면 null을 반환한다.
- 파라미터를 반환하는 메소드를 사용했는데 파라미터 key는 있고 값이 존재하지 않을 경우 빈 문자열을 반환한다.
- 빈문자열을 파싱하면 NumberFormatException 오류발생한다. (String을 int형으로 parsing시 주의)
- name 속성으로 key 값을 부여 해줘야 값이 넘어간다.
- 텍스트 상자는 기본적으로 문자열이 작성되어있다.
그래서 입력하지 않은 상태에서 요청시에는 빈 문자열이 들어온다.
- checkbox로 같은 key 값으로 여러개의 값이 넘어오면 String[]로 넘어온다.
ㅁ 에러
- 500 에러는 자바 코드 문제다.
- 404 오류가 뜨는 이유는 서블릿을 못 찾을 거나 이동할 경로(html 페이지)를 못찾는 경우다.
대부분 오타다. 특히 대소문자.
서블릿 annotation과 포워드 메소드 getRequestDispatcher(이동할경로)에 오타가 없는지 체크한다.
ㅁ 서블릿 or 정적 페이지
- http://localhost:8888/contextPath/정적인페이지의경로
- http://localhost:8888/contextPath/Servlet의URLMapping
ㅁ 상대경로와 절대경로 두 가지 방식으로 servlet 요청하기
- 상대경로 : <a href="../../../test1">상대경로방식</a>
- 절대경로 : <a href="/servlet/test1">절대경로방식</a>
ㅁ 상대경로와 절대경로 두 가지 방식으로 정적페이지 요청하기
- 상대경로 : <a href="../../abc/main.html">상대경로방식</a>
- 절대경로 : <a href="/servlet/abc/main.html">절대경로방식</a>
ㅁ post방식에서 데이터를 뽑을 때는 인코딩 작업을 해야 한다.
request.setCharacterEncoding("UTF-8");
ㅁ 서블릿 활용 과정
- request 객체에서 데이터를 뽑고, 뽑은 데이터를 가지고 DB에 쿼리문을 실행한다.
- data를 service를 호출하면서 넘기고, service에서는 dao로 넘기고, dao에서 insert문 때려서 그 결과를 돌려받는다.
(jdbc과정. 서블릿이 controller단이다.)
- 성공적으로 다 되었다면 응답페이지를 제작해서 돌려줘야 한다.
요청에 대한 결과 페이지를 사용자에게 보여줘야한다.
ㅁ < HttpServletResponse >
- 요청을 보낸 클라이언트에게 응답할 수 있는 객체
- doGet() 또는 doPost() 메소드 실행시 해당 객체가 생성되어 매개변수(response)에 전달
- 응답 관련 주요 메소드
1) getWriter() : 클라이언트에게 응답문자를 전송할 수 있는 출력 스트림(PrintWriter 타입) 반환
2) setContentType(String) : 응답문자의 데이터 형식(MIME-TYPE)을 설정
3) sendRedirect(String) : 리다이렉트할 URL 전송
- getWriter()는 통로다. 응답 데이터를 전달하려면 클라이언트와 연결된 통로가 필요하다.
출력 스트림을 통해 클라이언트에게 응답 데이터를 전달한다.
- ContentType이라고도 하고 MIME-TYPE이라고도 한다. 문자의 유형. 데이터 형식.
- 3)은 Redirect.
ㅁ 지금 화면 구현을 서블릿에서 out.println("")으로 하고 있는데, JSP 배우면 응답페이지 제작 과정을 JSP에 위임함.
- response 객체를 이용해서 한땀한땀 사용자에게 응답페이지를 보여줄 수도 있지만,
너무 번거롭기 때문에 JSP 배우면 응답 페이지 제작 과정은 JSP에게 위임한다.
ㅁ 포워드 하는 구문
- request.getRequestDispatcher("이동할경로").forward(request, response);
- context path는 빼고 url mapping만 이동할경로에 작성하면 된다
ㅁ 첫번째 목적지에서 포워딩시 request, response를 두번째 도착지로 전달했다.
- 그래서 doGet 메소드에 각각 대입되어있다.
- 첫번째 목적지에서 넘어온 파라미터를 두번째 서블릿의 doGet 메소드에서 고스란히 꺼낼 수 있다.
- forward는 요청의 방식을 유지하므로, GET이든 POST든 원래 요청된 방식을 그대로 사용합니다.
처음 get방식으로 서블릿을 요청했으면 forward로 이동한 서블릿에서도 doGet 메소드만 호출됨.
- forward로 이동한 경로(second)는 보이지 않는다.
ㅁ 서블릿이 실행되는 경우 3가지
(1) 클라이언트 요청에 의해서 (a, form submit 등)
(2) 서블릿에서 또다른 서블릿으로 "이동"할 경우 (forward)
(3) 서블릿에서 또다른 서블릿을 "재호출"할 경우 (redirect) <- url을 다시 강제로 호출
ㅁ < forward >
- 특정 처리를 대신할 Servlet 및 JSP로 이동시 사용하는 기술
주로 응답페이지 제작하는 과정을 JSP에게 위임할 때 사용할 예정
- 이동 경로 작성시 contextPath를 제외하고 작성한다.
- ★★★ URL에는 forward된(이동된) 경로가 노출되지 않는다. ★★★
클라이언트에게 이동한 경로를 숨길 수 있다. 최초 요청한 서블릿의 url mapping값만 보여진다.
ㅁ 주로 forward 하는 경우
1) 단순히 페이지 이동할 때
- 경로작성해서 그냥 이동해도 되지만 url이 노출되니까 보안상 위험해서 이동한 경로를 숨기고자 할 때.
- 그냥 링크로 이동해도 되는데, 서블릿을 호출해서, 거기서 포워드 메소드로 페이지로 이동.
2) select 쿼리 이후
- 조회 이후 forward를 굉장히 자주한다. db로부터 데이터를 조회 후 페이지로 이동할 때 forward 한다.
ㅁ 버튼에 클릭 이벤트 핸들러를 연결한다.
document.getElementById("writebtn").addEventListener("click", function() {
location.href = '/servlet/e_redirect/boardWrite.html';
})
- location.href는 현재 페이지의 URL을 설정하는 속성입니다.
이 속성에 새로운 URL을 할당하면, 웹 브라우저는 해당 URL로 페이지를 이동합니다.
- location.href와 forward 모두 기존에 있던 페이지에서 다른 페이지로 이동하는 것을 의미합니다. 하지만 그 동작 방식과 결과가 다릅니다.
- location.href는 항상 GET 요청이다.
이동하는 페이지 주소가 그대로 노출된다.
새로운 페이지로 이동할 때 이동하는 URL이 그대로 브라우저의 주소창에 노출됩니다.
ㅁ db로부터 조회할 데이터 없는 단순 페이지 이동이라하더라도 서블릿을 호출해서 포워딩 방식으로 이동하는게 제일 좋다.
- URL에 해당 애플리케이션 내부 디렉토리가 노출되기 때문이다.
- location.href = '/servlet/e_redirect/boardWrite.html'; 대신 location.href = '/servlet/writeForm.bo';
ㅁ redirect
- forward 방식은 서버 내부에서만 요청을 전달하기 때문에, 클라이언트의 새 요청이 발생하지 않습니다.
- db에 insert하고 새로 추가된 데이터를 다시 조회해서 뿌릴 때는 forward 방식 대신 redirect를 사용한다.
- request.getRequestDispatcher("/e_redirect/boardList.html").forward(request, response); 대신
response.sendRedirect("/servlet/list.bo"); // => list.bo의 Servlet을 재실행 (재요청)
- DB로부터 데이터를 조회해서 해당 페이지로 이동하는 Servlet이 이미 존재함. 해당 서블릿을 재호출하면 된다.
ㅁ < redirect >
- 기존에 정의해둔 Servlet을 재실행 시키는 개념 (URL 요청과 동일)
- 등록 및 수정/삭제 후에 다시 조회 페이지를 요청할 때 주로 사용함
- redirect 시 현재 서블릿에 존재하는 request, response를 전달하지 않음.
서블릿이 새로 실행되는 것이기 때문에 저 객체들도 다시 생성된다.
- 요청할 URL 작성시 contextPath부터 작성
response.sendRedirect("/servlet/list.bo"); <- 이 경로가 보여지게 된다.
- 클라이언트 측에서 redirect된 경로(최종 목적지)를 확인할 수 있음
URL에 현재 redirect한 URL이 보여진다.
- 주로 redirect 하는 경우
1) insert 쿼리 이후 => 게시글의 전체 조회 페이지 redirect
2) update 쿼리 이후 => 게시글의 상세 조회 페이지 redirect
3) delete 쿼리 이후 => 게시글의 전체 조회 페이지 redirect
=========================================================
[2.JSP]
ㅁ < Servlet >
- 사용자의 요청을 받아 처리한 후 "자바코드를 이용해서 HTML을 작성"해서 응답해주는 Java 클래스
- 즉 Java 베이스에 HTML을 구현함
out.println 문으로 출력하면 화면에 출력된다.
- 단점
(1) 복잡한 웹 화면을 구현하기 어려움
(2) 비즈니스 로직과 프리젠테이션 로직이 같이 기술되어 있어 유지보수가 불편하다.
그래서 나온게 JSP다.
ㅁ < JSP >
- Java Server Page
- HTML 베이스에 Java 코드를 작성할 수 있다. (즉 서블릿과 반대. <- 근데 얘도 서블릿임)
- 장점
(1) HTML 기반이기 때문에 웹 화면을 보다 쉽게 구현 가능하다.
(2) 비즈니스 로직(Java)과 프리젠테이션 로직(HTML)을 분리해서 관리할 수 있다.
- 개발자는 오직 비즈니스 로직에 집중하고, 퍼블리셔들은 프리젠테이션 로직에만 집중하게 분리 가능하다.
= 이제부터 페이지는 html이 아닌 JSP로 만든다.
ㅁ
- HTML comment <!-- -->는 Java 코드 및 JSP 관련 구문을 주석처리 할 수 없지만
JSP comment <%-- --%>는 Java 코드 및 JSP 관련 구문을 주석처리할 수 있다.
- jsp 주석은 jsp 파일에서만 쓸 수 있다. jsp 파일에선 웬만해선 jsp 주석을 쓰는게 좋다.
ㅁ JSP 스크립팅 원소 (Scripting Elements)
- jsp에서 java 코드를 기술할 수 있게 해주는 표현법.
(1)스크립틀릿 (Scriptlet)
- Java 코드 작성시 사용하는 기본 표현법
- 변수 선언, 제어문(조건문, 반복문) 등 작성
- <% Java 코드작성 %>
(2) 표현식 (Expression)
- Java에서의 값(변수에 담긴 값, 메소드호출을 통해 반환되는 값)을 출력할 때 사용
- 표현식 안에 메소드 호출구문 작성시 ; 찍어서는 안됨 // 호출이 되어버림
- <%= Java값 %>
- <%= sum %>하면 내부적으로 <% out.println(sum); %>이다.
ㅁ <% String[] name = {"가가가", "나나나", "다다다", "라라라"}; %>
- 배열에 담긴 값 : <%= String.join("-", name) %>
- 배열에 담긴 값 : 가가가-나나나-다다다-라라라
ㅁ <%-- for문 활용 (반복적으로 요소 생성) --%>
<ul>
<% for(int i=0; i<name.length; i++) { %>
<li><%= name[i] %></li>
<% } %>
</ul>
ㅁ <%-- if문 활용 (선택적으로 요소 생성) --%>
<% if(sum >= 10) { %>
<b>덧셈결과가 10이상입니다.</b>
<% }else { %>
<i>덧셈결과가 10미만입니다.</i>
<% } %>
- 문구만 출력하는 거면 out.println()으로도 되겠지만 b 태그와 i 태그를 출력하고 있다.
- if문으로 선택적으로 요소를 생성시킨 것이다.
ㅁ JSP 지시어 (Directives)
- JSP_Page Directive
- JSP_Include Directive
- 나머지 JSP 지시어와 JSP 액션태그는 세미 이후에 배운다.
- <%@ 다음에 page가 붙으면 page 지시어고, include가 붙으면 include 지시어고, taglib이 붙으면 taglib 지시어다.
ㅁ 페이지 지시어
- jsp 파일은 항상 상단에 <%@ %>가 있다. 이게 페이지 지시어다. 이미 만들어져 있다.
- 현 jsp 페이지에 대한 정보(각종 속성)를 표현하고 있는 부분이다.
- <%@ page 속성="값" 속성="값" ...%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
(1) import문
- <%@ page import="java.util.Date"%>
- import="java.util.List, java.util.ArrayList" 이렇게 컴마로 여러개 기술도 가능하지만 import는 한 줄씩 따로 쓰는게 좋다.
(2) 에러페이지
- <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="/b_page_directive/error500.jsp" %>
- 이러면 이 페이지에서 에러가 발생하면 화면에 저 경로에 제작해 놓은 에러페이지가 보여진다.
- 그런데 이렇게 하지 않고 web.xml에 여러개의 에러페이지를 메인페이지처럼 한번에 등록해놓을 수 있다.
ㅁ web.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>02_jsp</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>
<error-page>
<error-code>500</error-code>
<location>/b_page_directive/error500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/b_page_directive/error404.jsp</location>
</error-page>
</web-app>
ㅁ include 지시어
- 애플리케이션의 어떤 페이지든 항상 header랑 footer는 존재해야 한다.
section에는 그 페이지에서 보여줘야할 내용이 출력된다.
- header랑 footer는 매 페이지마다 동일하게 보여진다.
그렇다고 매 페이지마다 header와 footer 페이지를 만들 필요는 없다. 별도로 jsp로 정의해두고 include로 표현할 수 있다.
<%@ include file="header.jsp" %>
- 현재 이 페이지와 같은 폴더에 header.jsp가 있다면 위와 같이 경로를 파일명만 작성하면 된다.
- header, footer, nav 등의 태그도 결국 div다. 의미를 부여한 시멘틱 태그다.
- header.jsp와 footer.jsp의 body 영역에 보여지는 요소가 들어온다
- 회사에선 head, body 태그 다 떼고 보여질 요소만 작성한다. 딱 body에 표현할 요소만을 작성한다.
다른 곳에 포함될 페이지는 전체 구조를 다 둘 필요 없이 포함될 요소만 작성해도 된다.
- 사이드 영역도 매 페이지마다 같다면 include로 포함시킨다.
- header.jsp에서 선언한 변수를 main.jsp에서도 쓸 수 있다.
말 그대로 저 페이지상에 존재하는 모든 구문들이 이 자리에 들어갔다.
===========================================================
[3.Servlet과 JSP 결합]
ㅁ 서블릿과 JSP를 결합시켜서 사용자가 요청할 수 있는 페이지를 제작한다.
- 요청은 서블릿이 처리하고, 처리된 결과를 JSP 페이지를 통해 사용자에게 응답하여 표현한다.
ㅁ select
- key값은 select 태그에 한번만 작성하면 된다
- option에 value 속성을 두지 않으면 텍스트값이 넘어간다.
<select name="pizza">
<option>치즈피자</option>
<option>페퍼로니피자</option>
<option>하와이안피자</option>
<option>씨푸드피자</option>
</select>
ㅁ checkbox와 라디오 버튼은 name 속성(key), value 속성을 다 써줘야 한다.
<input type="checkbox" name="topping" value="고구마무스">
<input type="radio" name="payment" value="card" checked>
ㅁ 현재 <form action="/jsp/order.do" method="post">인 상태다.
ㅁ 서블릿은 MVC 패턴 중에 컨트롤러 역할이기 때문에 controller 패키지로 만든다.
- controller 패키지에 서블릿으로 PizzaOrder.java를 만든다.
- 서블릿의 annotaion을 "/order.do"로 변경한다.
- doPost() 메소드는 doGet() 메소드를 호출한다.
ㅁ doGet() 메소드
- 1. 요청하면서 전달한 값(파라미터)을 뽑아서, 그 값을 가지고 요청을 처리한다. (주로 JDBC)
- 2. 돌려받은 결과를 가지고 응답페이지를 제작한다.
(1) 요청시 전달값 뽑기
request.setCharacterEncoding("utf-8"); // post방식 요청이기 때문에 데이터를 뽑기 이전에 인코딩 지정해야 한다.
String userName = request.getParameter("userName");
// 요청과 같이 전달된 값을 뽑아서 곧바로 요청처리 하려하지말고, 항상 출력해서 잘 넘어왔는지 확인해봐라.
System.out.println("유저이름 : " + userName);
(2) 요청처리 (주로 JDBC)
// => service => dao => 쿼리 실행 => 결과 돌려받기
// 요청 처리 후 돌려받은 결과가 주문번호라고 가정.
String orderNo = "20240828-1234567";
(3) 돌려받은 결과를 가지고 응답페이지 제작하기
// resoponse 객체를 이용해서 한땀한땀 html 구문을 출력해도 되지만,
이제부턴 응답페이지 제작하는 과정을 jsp로 이동(forward)해서 진행한다.
// ㅁ HttpServletRequest 객체의 응답데이터 처리 메소드
- 응답페이지에서 필요한 데이터는 보통 request 객체에 담아서 forward로 넘긴다.
- setAttribute(String 속성, Object 값) : 이동(forward)되는 jsp에서 사용할 데이터를 담는 메소드
- getAttribute(String 속성) : 해당 데이터를 Object 타입으로 반환 (형변환이 필요할 수 있음)
- removeAttribute(String 속성) : 해당 데이터를 제거하는 메소드
request.setAttribute("userName", userName);
request.setAttribute("orderNo", orderNo);
request.getRequestDispatcher("/d_pizza/result.jsp").forward(request, response);
- 요청시 전달된 다수의 값을 service, dao로 넘길 때 vo객체가 있다면 거기에 담아서 한번에 넘긴다.
담는 과정도 여기서 진행한다.
- setAttribute(String 속성, Object 값)에서 String 속성은 속성명이고 Object 객체가 내가 request 객체에 담고자 하는 값이다.
배열도 담을수 있고 리스트도 담을 수 있다. vo객체도 담을 수 있다.
ㅁ 항상 이런 흐름으로 간다.
- 요청을 보내면 요청시 전달값을 뽑아서 sql query를 실행해서 결과를 돌려받고,
그에 해당하는 응답페이지를 jsp로 만들어서 이동시킨다.
- 그때 응답페이지에서 필요한 데이터는 위와 같이 setAttribute라는 메소드로 request 객체에 담아서 전달시킨다.
ㅁ 아래와 같이 응답페이지인 result.jsp를 만든다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String userName = (String)request.getAttribute("userName"); // 실제론 String 타입의 데이터지만 반환은 Object로 됨.
String orderNo = (String)request.getAttribute("orderNo");
String pizza = (String)request.getAttribute("pizza");
String[] topping = (String[])request.getAttribute("topping");
String[] side = (String[])request.getAttribute("side");
String payment = (String)request.getAttribute("payment");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>주문 완료</h2>
<h3>주문번호 : <%= orderNo %></h3>
<h3>주문자명 : <%= userName %></h3>
<h3>주문내역</h3>
<ul>
<li>피자 : <%= pizza %></li>
<%-- 토핑과 사이드는 체크한게 없으면 null일 수 있다. --%>
<li>토핑 :
<% if(topping == null) { %>
<b>선택안함</b>
<% }else { %>
<%= String.join(", ", topping) %>
<% } %>
</li>
<li>사이드 :
<%
if(side== null) {
out.println("<b>선택안함</b>");
}else {
out.println(String.join(", ", side));
}
%>
</li>
<li>결제방식 : <%= payment.equals("card") ? "카드" : "현금" %></li>
</ul>
</body>
</html>
- 응답페이지(.jsp)에서 request 객체로부터 getAtrribute로 데이터를 꺼낸다.
- request 객체에서 데이터를 뽑는 구문은 페이지 로드되자마자 바로 실행되게끔 주로 상단에 쓴다.
- jsp에서는 request객체를 import 없이 바로 쓸 수 있다. jsp 내장객체다.
- <% %> 에는 자바코드만 있어야 하고 html 구문이 있어서는 안 된다.
out.println문에 html태그를 쓰면 된다.
'05_Server (04. JSP 프로그래밍 구현)' 카테고리의 다른 글
[AJAX] 1. ajax를 이용한 비동기식 요청 (0) | 2024.09.29 |
---|---|
실제 프로젝트 작업 (1) | 2024.09.22 |
X [4-3] 사진게시판서비스 상세조회요청(슬라이드이미지) (0) | 2024.09.11 |
X [4-2] 사진게시판서비스 목록조회요청(썸네일형식) (0) | 2024.09.11 |
X [4-1] 사진게시판서비스 작성요청(다중파일업로드) (0) | 2024.09.11 |