- JSP란?
- JSP(Java Server Page) : Java 코드가 들어있는 HTML 코드
- Java의 웹 서버 프로그램 스펙(Servlet)으로 변환되어 서비스 됨 - Servlet과 JSP의 차이점
- Servlet
: 웹 서비스 기능을 해주는 자바 클래스를 말하는 것으로,
자바 소스코드 안에 HTML 코드가 들어가는 형태
→ HTML 문서를 작성하는데 복잡하고 번거로움
- JSP
: 복잡한 Servlet을 조금 더 간단히 사용할 수 있음
Servlet과 반대로 HTML 소스코드 안에
자바 소스코드(scripting element/스크립팅 원소: <% %> / <%= %>)가 들어가는 형태
컴파일을 통해 .class 파일로 변환되어 웹 서버(WAS)에서 실행됨 - Servlet / JSP 동작 순서
1) 웹 서버가 사용자로부터 Servlet에 대한 요청을 받으면 Servlet Container에 그 요청을 전달함
2) 요청을 받은 Servlet Container는 HttpRequest와 HttpResponse 객체를 만들어
이를 Servlet doPost( )나 doGet( ) 메소드 중 하나를 호출
3) 클라이언트가 요청에 대한 응답 웹 페이지를 보여줄 때
기존 Servlet에서 출력 객체를 이용하여 HTML 문서를 작성하는 부분(프리젠테이션 로직)을
JSP로 분리함 → 데이터의 입력, 수정 등에 대한 제어를 JSP로 넘겨 가독성을 높임
4) JSP가 전달 받은 프리젠테이션 로직을 수행한 후 Servlet Container에게 Response 전달
5) 전달 받은 JSP 프리젠테이션 로직 수행 결과와 Servlet이 결합되어 .class 파일이 만들어짐
- JSP 장점
- Servlet보다 쉽고 작성하기 빠름
- 디자인 파트(HTML)와 로직 파트(Java)로 이루어져 있음
정보, 디자인 파트(HTML)와 로직 파트(Java)를 분리할 수도 있음
- 프로그래머가 직접 코딩한 Servlet보다 최적화된 Servlet으로 생성시켜주므로 효율적인 코드가 만들어짐
- 웹 애플리케이션 상에서 변수의 사용 가능한 범위(scope) 설정이 쉬움 - JSP를 이루는 기본 구성인자(element)
1. 지시어(directive)
1) page : 현재 JSP 페이지를 Container에서 처리하는데 필요한 각종 속성을 기술하는 부분
보통 소스의 맨 앞에 위치
<%@ page 속성1="속성값1" 속성2="속성값2" ... %>
page 지시어 속성 종류
- contenttype : MIME 형식 지정 및 캐릭터셋 설정
( contentType="text/html; charset=UTF-8" )
- pageEncoding : JSP 파일(페이지)에 기록된 소스코드 자체의 인코딩 방식
( pageEncoding="UTF-8" )
2. 스크립팅 원소(scripting element)
: JSP 페이지에서 Java 코드를 직접 기술할 수 있게 하는 기능
1) 선언문(declaration)
<%! Java 코드 %>
2) 스크립틀릿(scriptlet)
<% Java 코드 %>
3) 출력식, 표현식(expression)
<%= Java 코드 %> - JSP 페이지에서 사용할 수 있는 내장객체변수의 종류
- 일반적인 Java 프로그램에서는 변수를 사용하기 전에 반드시 선언을 해야 하지만,
JSP 페이지에서는 선언을 하지 않고도 사용 가능한 변수가 있음
→ 이러한 변수를 JSP 페이지의 "내장객체변수(implicit variable)"라고 함
※ Web-Container(= WAS, TomCat 서버)가 JSP 페이지를 Servlet 클래스로 변환해줄 때,
변수 선언을 자동으로 해주기 때문에 변수 선언 없이 사용 가능함
1) request
: doGet, doPost 메소드의 첫 번째 파라미터와 동일한 역할을 수행
웹 클라이언트에서 보내온 데이터 값을 받아서 처리하는 변수
데이터 저장소 역할이 가능함
2) response
: doGet, doPost 메소드의 두 번째 파라미터와 동일한 역할을 수행
웹 클라이언트의 요청에 대한 응답 결과 처리를 위한 변수
- JSP 기본 예제 - 1 : 로그인 기본 화면 동작 (아이디 비밀번호)
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSP Project</title>
</head>
<body>
<h3>Get 방식 요청</h3>
<form action="/JSPProject/login" method="get">
<!-- 요청 주소 : /JSPProject/login
데이터 전달 방식 : get (주소 뒤에 데이터가 붙어서 전달됨) -->
ID : <input type="text" name="inputId"><br>
PW : <input type="password" name="inputPw"><br>
<button>로그인</button>
</form>
</body>
</html>
- Servlet Container
package edu.kh.jsp.controller;
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;
// @webServlet("요청 주소") 어노테이션
// - 해당 클래스를 Servlet 클래스로 등록하고(== web.xml의 <servlet> 태그)
// 어떤 요청 주소를 처리할지 지정함(== web.xml의 <servlet-mapping> 태그)
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 요청 시 전달된 input 태그의 값(== Parameter) 얻어오기
// ★ 파라미터는 모두 String 타입
String inputId = req.getParameter("inputId");
String inputPw = req.getParameter("inputPw");
// 파라미터를 잘 얻어왔는지 확인
System.out.println("ID: " + inputId);
System.out.println("Pw: " + inputPw);
String result = null;
if(inputId.equals("user01") && inputPw.equals("pass01!")) {
result = inputId + "님이 로그인 하셨습니다.";
} else {
result = "아이디 또는 비밀번호가 일치하지 않습니다.";
}
// out.print("<html>"); -> JSP로 교체
// JSP란?(Java Server Page)
// - Servlet에서 HTML 코드 작성이 불편함
// -> 반대로 HTML 코드에 Java 코드를 쓸 수 있게 하는 문서
// ★ JSP 생성 폴더 위치
// -> webapp/WEB-INF 폴더 내부에 생성
//***************************************************************
// ★★★ JSP로 응답하기 ★★★
// Dispatcher : 필요한 정보를 제공하는 자 == 발송자
// 위임 : (맡은 일을) 넘겨주다
// forward : 전송하다, 보내다
// ★ 응답 화면을 만드는 Servlet의 일을
// 효율적으로 처리할 수 있는 JSP에게 넘겨줄 예정
// RequestDispatcher
// : Servlet -> JSP로 "HttpServletRequest 객체 / HttpServletResponse 객체"를
// 발송(위임)하는 역할의 객체
// req.getRequestDispatcher("JSP 경로");
// - HttpServletRequest 객체가 생성될 때
// 내부에 자동으로 요청발송자(RequestDispatcher)가 같이 생성됨(new 연산자로 생성 필요 X)
// ★★★ JSP 경로 작성 규칙 ★★★
// - ★★★webapp 폴더를 기준★★★으로 JSP 파일까지의 모든 경로 작성!!
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/loginResult.jsp");
// JSP에게 전송될 예정인 HttpServletRequest 객체에
// result 변수 값을 담아서 같이 전달
// req.setAttribute(String Key, Object value);
// - key는 String(문자열)
// Attribute : 속성(데이터, 값)
req.setAttribute("res", result);
// 요청 발송자를 이용하여 req, resp 객체를 전송(forward)
dispatcher.forward(req, resp);
}
}
- JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% // 자바 코드 작성 영역
// Servlet으로 부터 전송 받은 req, resp가 있는 상태
// -> req, resp 사용 가능함!
// 대신 이름이 request, response로 바뀜
// getAttribute("key값");
// 반환형 Object이기 때문에 원래 타입으로 강제 형변환!
String r = (String)request.getAttribute("res");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 결과 화면</title>
</head>
<body>
<!-- 위에서 선언된 변수 r에 저장된 값 출력 -->
<h1><%= r %></h1>
</body>
</html>
- 결과 화면
- JSP 기본 예제 - 2 : 피자 주문
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSP Project</title>
</head>
<body>
<h3>Servlet/JSP로 페이지 이동</h3>
<!-- 서버 요청 주소 작성 -->
<!--
GET 방식 요청 종류 : a태그, JS(location), 직접 주소 작성, form태그 method="get"
-->
<a href="/JSPProject/pizza/order">피자 주문하기</a>
</body>
</html>
- Servlet Container
package edu.kh.jsp.controller;
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;
@WebServlet("/pizza/order")
public class PizzaOrderServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// a태그 요청 == Get 방식
// 별도의 처리 없이 바로 JSP로 요청 위임
// RequestDispatcher : 요청 발송자
// -> 지정된 JSP로 요청 정보(HttpServletRequest), 응답 정보(HttpServletResponse)를
// 전송(발송)하는 역할
// JSP 경로는 webapp을 기준으로 작성함!!
//RequestDispatcher dispatcher = req.getRequestDispatcher("JSP 경로");
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/pizza_order.jsp");
// forward : 보내다, 전송하다
// -> JSP로 요청, 응답을 보내는 기능
dispatcher.forward(req, resp);
}
// form태그 POST 방식 제출 시
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// ★★★ POST 방식의 한글 깨짐 문제 ★★★
// - 데이터 전달 방식 차이점
// GET : 주소(URL)를 통해서 데이터 전달
// 이 때, 문자 인코딩은 제출된 HTML파일의 문자 인코딩(charset)을 따름
// POST : HTTP Body를 통해서 데이터 전달
// 이 때, 문자 인코딩은 서버의 기본 문자 인코딩을 따름
// 우리 서버(Tomcat) -> ISO-8859-1이 기본 문자 인코딩
// ★ 해결 방법 ★
// - POST 방식으로 전달 받은 데이터의 문자 인코딩을 UTF-8로 변경
req.setCharacterEncoding("UTF-8");
String pizza = req.getParameter("pizza"); // 치즈 피자-8000
String size = req.getParameter("size");
int amount = Integer.parseInt(req.getParameter("amount"));
// 피자 이름, 가격 나누기
String[] arr = pizza.split("-"); // "-"구분자로 쪼개서 String[]로 반환
// arr == {"치즈 피자", "8000"};
String pizzaName = arr[0]; // 치즈 피자
int price = Integer.parseInt(arr[1]); // 8000
// L 사이즈인 경우 4000원 추가
if(size.equals("L")) {
price += 4000;
}
// 피자 수량만큼 price에 곱하기
price *= amount;
// price = price * amount;
// JSP로 요청 위임(forward)
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/pizza_result.jsp");
// JSP로 전달하는 req에는 파라미터가 담겨 있음
// 하지만, Servlet에서 만든 변수 pizzaName, price는 없음!
// [해결 방법]
// req에서 속성(Attribute)으로 추가하면
// JSP에서 꺼내쓸 수 있음!
// (주의) forward 하기 전에 추가해줘야 함!
req.setAttribute("pizzaName", pizzaName);
req.setAttribute("price", price);
dispatcher.forward(req, resp);
}
}
- JSP
1) pizza_order
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>피자 주문 페이지</title>
<!-- 절대 경로 기준 == webapp == /JSPProject -->
<link rel="stylesheet" href="/JSPProject/resources/css/pizza.css">
</head>
<body>
<main>
<h1>피자 주문 페이지</h1>
<!-- /JSPProject/pizza/order 라는 같은 주소 요청을
처리하는 Servlet이 존재하지만
데이터 전달 방식이 Get / Post로 구분되기 때문에
doGet(), doPost()로 연결되어 처리되므로
충돌 문제 없음
-->
<form action="/JSPProject/pizza/order" method="POST">
<div class="row">
<label>피자 :</label>
<select name="pizza">
<option>치즈 피자-8000</option>
<option>콤비네이션 피자-9000</option>
<option>쉬림프 피자-15000</option>
<option>더블 포테이토 피자-14000</option>
<option>하와이안 피자-12000</option>
</select>
</div>
<div class="row">
<label>사이즈 : </label>
R <input type="radio" name="size" value="R" checked>
L(+4000) <input type="radio" name="size" value="L">
</div>
<div class="row">
<label>수량</label>
<button type="button">-</button>
<input type="number" name="amount" min="1" max="9" value="1">
<button type="button">+</button>
</div>
<button class="order-btn">주문하기</button>
</form>
</main>
<script src="/JSPProject/resources/js/pizza.js"></script>
</body>
</html>
2) pizza_result
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!--HTML 주석(개발자 도구에 노출 O)-->
<%--JSP 주석(개발자 도구에 노출 X)--%>
<%--
<%@ %> : 지시자 태그(페이지 정의)
"charset=UTF-8" : 현재 문서가 UTF-8 문자 인코딩 형식으로 작성되어 있음
"pageEncoding=UTF-8" : 현재 문서를 해석할 때 UTF-8 문자 인코딩을 이용해서 해석
<% %> : 스크립틀릿(scriptlet) : JSP에서 자바 코드를 작성할 수 있는 영역
<%= %> : 표현식(Expression) : 자바 코드의 값을 HTML 형식으로 표현(출력)
--%>
<% // 자바 코드 작성 영역 (Scriptlet)
String pizzaName = (String)request.getAttribute("pizzaName");
int price = (int)request.getAttribute("price");
// JSP에서도 요청 시 전달 받은 값(Parameter)을 얻어올 수 있다.
String amount = request.getParameter("amount");
String size = request.getParameter("size");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>피자 주문 결과</title>
</head>
<body>
<!-- webapp 폴더 내부 html/css/jsp 등은
서버를 끄지 않고도 수정 가능 -->
<h1>주문 결과</h1>
<ul>
<li>피자 : <%=pizzaName%></li>
<li>사이즈 :
<%if(size.equals("R")){%>
레귤러
<%}else{%>
라지
<%}%>
</li>
<li>수량 : <%=amount%></li>
<li>합계 : <%=price%></li>
</ul>
<h3>for문 작성 예시</h3>
<%for(int i=1; i<=6; i++){%>
<h<%=i%>><%=i%>번째 출력</h<%=i%>>
<%}%>
</body>
</html>
- 화면
1) 주문하기 화면
2) 클릭하여 이동한 피자 주문 페이지
3) 피자 주문 및 결과 화면
※ for문 작성 예시 결과(pizza_result.jsp에서 코드 확인 가능)
- JSP 기본 예제 - 2 : 회원가입 양식
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSP Project</title>
</head>
<body>
<h3>회원가입</h3>
<form action="/JSPProject/signUp" method="post">
<table>
<tr>
<th>아이디 : </th>
<td>
<input type="text" name="memberId">
</td>
</tr>
<tr>
<th>비밀번호 : </th>
<td>
<input type="text" name="memberPw">
</td>
</tr>
<tr>
<th>이름 : </th>
<td>
<input type="text" name="memberName">
</td>
</tr>
<tr>
<th>자기소개 </th>
<td>
<textarea name="intro" rows="3" cols="30"></textarea>
</td>
</tr>
</table>
<button>회원가입</button>
<button type="reset">초기화</button>
</form>
</body>
</html>
- Servlet Container
package edu.kh.jsp.controller;
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 : 웹 서비스(요청, 응답)를 위한 자바 클래스
// @WebServlet("요청주소") : Servlet 클래스 등록 + 요청 주소 매핑
@WebServlet("/signUp")
public class SignUpServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// ★ POST 방식으로 데이터를 전달 받을 경우
// 서버(Tomcat)의 기본 문자 인코딩을 따름
// -> UTF-8로 인코딩 변경해줘야 함!!(한글 깨짐 방지)
req.setCharacterEncoding("UTF-8");
String memberId = req.getParameter("memberId"); // 생략 가능
String memberPw = req.getParameter("memberPw"); // 생략 가능
String memberName = req.getParameter("memberName"); // 생략 가능
String intro = req.getParameter("intro"); // 생략 가능
String message = memberName + "님의 가입을 환영합니다.";
// 요청 -> Servlet -> RequestDispatcher -> forward(req, resp) -> JSP
// (요청 발송자) (전송)
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/signUp_result.jsp");
// JSP 경로는 webapp 폴더를 기준으로 작성함!!
// HttpServletRequest 객체에 message 변수 추가
req.setAttribute("message", message);
dispatcher.forward(req, resp);
}
}
- JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% // Dispatcher가 forward 할 때 req, resp를 매개변수로 보냄
// 따라서 JSP에서도 req, resp 사용 가능!
// 전달 받은 파라미터
String memberId = request.getParameter("memberId");
String memberPw = request.getParameter("memberPw");
String memberName = request.getParameter("memberName");
String intro = request.getParameter("intro");
String message = (String)request.getAttribute("message");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%=memberName%>님 가입 결과</title>
</head>
<body>
<ul>
<li>아이디 : <%=memberId%></li>
<li>비밀번호 : <%=memberPw%></li>
<li>이름 : <%=memberName%></li>
<li>자기소개 : <%=intro%></li>
</ul>
<h1><%=message%></h1>
</body>
</html>
- 화면
1) 회원가입 양식에 데이터 입력
2) 회원가입 버튼 누르면 결과 화면으로 이동
'Server > Servlet & JSP' 카테고리의 다른 글
JSP 기본 개념 - 3 ( JSTL - JSP Standard Tag Library ) (0) | 2025.01.02 |
---|---|
JSP 기본 개념 - 2 ( Expression Language, scope ) (0) | 2025.01.01 |
Servlet 기본 개념 (0) | 2024.12.31 |