GSJun
JSP & 데이터 전송 방식 본문
1. JSP
JSP 기술에서 웹 애플리케이션을 구현할 때 작성하는 코드를 'JSP 페이지'라고 함.
JSP 페이지는 HTML 문서 사이사이에 JSP 문법의 코드가 삽입되는 형태로 작성됨
JSP 페이지에 있는 HTML 코드는 웹 브라우저로 그대로 전송되지만 JSP 문법의 코드는 웹 컨테이너 쪽에서
실행 되고 결과만 브라우저로 전송 됨
(jsp는 브라우저로 안가고 결과만 줌)
실행 순서
JSP 페이지를 서블릿 클래스의 소스 코드로 변환 - 소스코드 컴파일 - 컴파일 결과로 객체를 만듦 - 서블릿 실행
(jsp를 서블릿 소스코드로 변환 후 서블릿 실행해 결과물을 보냄)
JSP의 기초 문법
JSP 코드 : <%....%>의 형태로 자바 코드를 스크립트 안에 넣을 수 있는 형태
EL(Expression Language) : ${...}의 형태로 MVC Model2 구조에 적합하게 스크립팅 요소를 없애기 위해 나옴
JSTL
- XML의 형태로 기술됨
- 액션이라고도 함.
- 표준화된 태그 라이브러리를 이용함으로써 JSP 페이지의 가독성을 높여줌 ex) <c:forEach>
JSP 코드 문법
<%@ 지시자 %>
- Directive 태그라고도 하며 지시하는 역할을 함
- 주로 페이지 내의 인코딩 방식이나 태그 라이브러리를 설정하는데 쓰임
<%! 맴버(변수, 메서드) 선언%>
- Declaration 태그
- JSP파일 내에서 변수 또는 메서드를 선언할 때 사용
<% 자바 코드 %>
- Scriptlet 태그
- 자바 코드를 작성할 때 사용한다
- 페이지 내에 여러 개의 블록이 존재 가능
<%=출력한 표현식 %>
- 변수 또는 표현식을 출력하기 위한 태그
- Expression 태그라고도 부름
<%-- --%>
- JSP 주석
* HTML 이나 Java 코드 주석도 활용 가능
(<!-- HTML Comments --!>, <% /* Java Comments */ %>)
<%@ page >
- 페이지 디렉티브
- 페이지 내의 언어, 상속받을 클래스
- 패키지 import, session, errorPage 인코딩 등의 속성을 지정할 수 있음
<%@ include file=>
- 해당 파일의 소스코드를 그대로 입력
- 유사한 문법으로 액션 태그의 <jsp:include page=>가 있음
예제
Example.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>1부터 200까지의 합</title>
</head>
<body>
<%
int total = 0;
for(int cnt=1;cnt<=100; cnt++) {
total += cnt;
}
%>
1부터 100까지의 합 = <%=total %> <br>
<%
for(int cnt = 101; cnt <= 200; cnt++) {
total += cnt;
}
%>
1부터 200까지의 합 = <%=total %> <br>
</body>
</html>
실행 결과
JSP 내장 객체
Request : 요청 객체, 서블릿과 동일하게 사용 가능
Response : 응답 객체, 서블릿과 동일하게 사용 가능
Out : 웹 브라우저로 HTML 코드 출력
Session : 세션 객체, 세션을 통해 클라이언트의 상태 정보를 저장 가능
- setAttribute(String Key, Object value) 객체 바인딩
- getAttribute(String Key) : Object 객체 바인딩
- removeAttribute(String Key) : 객체 바인딩
- getId() : String 세션의 아이디
- invalidate() : 세션 무효화(로그아웃 처리 시)
Application : 애플리케이션 객체, 서블릿의 컨텍스트 객체와 같음
pageContext : JSP 내장 객체를 참조할 수 있는 객체
Page : JSP 페이지 객체
Exception : 예외 객체, JSP에서 예외가 발생할 경우에만 생성
- getMessage() : String 예외 발생 원인에 해당하는 메시지 출력
- printStackTrace() : 예외 발생 경로를 추적해 줌
Config : 서블릿 마다 하나씩 생성되는 객체, 서블릿과 동일
예제
Hi.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>이름 입력</title>
</head>
<body>
이름을 입력하세요
<form action="./Yourname.jsp" method="get">
이름 : <input type="text" name="yourname">
<input type="submit" value="확인">
</form>
</body>
</html>
Yourname.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>인사하기</title>
</head>
<body>
<!-- 서블릿과 동일하게 Request객체를 사용할 수 있는 것을 확인 가능 -->
안녕하세요, <%=request.getParameter("yourname") %> 님
</body>
</html>
실행 결과
Move.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>
<!-- 서블릿과 동일하게 Response 객체를 사용할 수 있는 것을 확인 가능 -->
<% response.sendRedirect("http://www.naver.com"); %>
</body>
</html>
JspServlet.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>숫자 입력</title>
</head>
<body>
<form action="./Jsp.do" method="post">
<h1>입력하신 숫자부터 10번째 뒤 숫자까지의 합을 구해줍니다.</h1><br>
숫자를 입력해 주세요 : <input type="text" name="number">
<br><br><input type="submit" value="제출">
<input type="reset" value="취소">
</form>
</body>
</html>
JspServlet.java
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("/Jsp.do")
public class JspServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int number = Integer.parseInt(request.getParameter("number"));
int i = number+1;
int j = 0;
do {
number += i;
i++;
j++;
} while(j < 9);
String renumber = Integer.toString(number);
request.setAttribute("number", renumber);
RequestDispatcher disp = request.getRequestDispatcher("./result.jsp");
disp.forward(request, response);
}
}
result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>결과 출력</title>
</head>
<body>
<%String number = (String)request.getAttribute("number"); %>
입력하신 숫자에서 10번째 자리뒤까지의 합은 :
<%=number %>
</body>
</html>
2. response.sendRedirect() / RequestDispatcher.forward()
서블릿으로 데이터 처리 후 View로 데이터를 보내줄 때에는
대표적으로 response.sendRedirect() 메서드와 RequestDispatcher.forward() 메서드를 사용함
sendRedirect는 URL을 매개변수로, Dispatcher는 생성자에 URL을 파라미터로 받음
이 두 메서드가 중요한 이유는 서로의 전송 방식 차이 때문
간단하게는
요청 시에 들어온 데이터가 View에서 쓰이지 않는 경우 - response.sendRedirect() 사용
요청 시에 들어온 데이터가 View에서도 쓰여야 하는 경우 - RequestDispatcher.forward() 사용
response.sendRedirect()
리다이렉트 메서드는 인수로 전달 된 URL 홈페이지를 재전송 해 줌
사용자의 화면에서는
(Redirect 메서드 호출 - 곧바로 Redirect의 URL에 해당하는 화면을 표시) 로 보이지만 실제로는 그렇지 않음
서버가 서블릿의 응답을 브라우저 표시 - 브라우저는 Redirect(URL) 페이지를 새로 요청
Request와 response 객체는 클라이언트의 요청이 있을 시 생성되고 응답과 함께 소멸함
위와 같이 처음 클라이언트가 요청 - Redirect() 메서드 호출 - 브라우저가 다시 해당 URL 홈페이지 요청의
과정을 거친다면 처음 클라이언트 요청했을 시의 request와 response 객체는 없어짐 - 사용 불가!
RequestDispatcher.forward()
디스패처포워드 메서드는 생성자 파라미터로 전달 된 URL 홈페이지에 Request와 response 객체를 들고 갈 수 있게 해 줌
요청을 다시 하는 일이 없이 바로 URL 홈페이지 객체를 전달함 - request 객체 사용 가능
Request에 바인딩한 객체들도 그대로 사용 가능
클라이언트의 요청 시 입력 받은 데이터를 JSP에서 쓰고 싶다면
RequestDispatcher.forword() 메서드를 이용해야 함
예제
RedirectDispatcher.java
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("/go")
public class RedirectDispatcher extends HttpServlet {
private static final long serialVersionUID = 1L;
public RedirectDispatcher() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = "엄염범";
request.setAttribute("name", name);
response.sendRedirect("./Redirect.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = "엄염범";
request.setAttribute("name", name);
RequestDispatcher disp = request.getRequestDispatcher("./Dispatcher.jsp");
disp.forward(request, response);
}
}
Redirect.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Redirect</title>
</head>
<body>
<%String name = (String)request.getAttribute("name"); %>
<h1>기본 출력</h1>
<% if(name != null) {%>
<%= name %>
<%} %>
</body>
</html>
Dispatcher.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dispatcher</title>
</head>
<body>
<%String name = (String)request.getAttribute("name"); %>
<h1>기본 출력</h1>
<% if(name != null) {%>
<%= name %>
<%} %>
</body>
</html>
go.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>go</title>
</head>
<body>
<form action="./go" method="get">
<input type="submit" value="Redirect">
</form>
<form action="./go" method="post">
<input type="submit" value="Dispatcher">
</form>
</body>
</html>
실행 결과
Redirect로 요청할 때는 request 객체에 저장한 name이라는 객체가 전달되지 않는 것을 확인
RequestDispatcher로 요청할 때는 Request 객체에 저장한 name이라는 객체가 전달 되어 출력 됨
예제
input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>데이터입력</title>
</head>
<body>
<form action="./rd" method="post">
아이디 : <input type="text" name="id"><br>
비밀번호 : <input type="password" name="pw"><br>
이름 : <input type="text" name="name"><br>
<input type="submit" value="RE" name="rd">
<input type="submit" value="DI" name="rd">
<br><input type="reset" value="취소">
</form>
</body>
</html>
RdExample.java
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("/rd")
public class RdExample extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
String id = request.getParameter("id");
String pw = request.getParameter("pw");
String rd = request.getParameter("rd");
String url = "./RdExample.jsp";
if(rd.equals("RE")) {
request.setAttribute("id", id);
request.setAttribute("name", name);
request.setAttribute("pw", pw);
response.sendRedirect(url);
}else {
request.setAttribute("id", id);
request.setAttribute("name", name);
request.setAttribute("pw", pw);
RequestDispatcher disp = request.getRequestDispatcher(url);
disp.forward(request, response);
}
}
}
RdExample.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>입력 데이터 출력</title>
</head>
<body>
<% String id = (String)request.getAttribute("id");
String name = (String)request.getAttribute("name");
String pw = (String)request.getAttribute("pw");
%>
<h1>입력하신 정보가 아래와 같습니까?</h1>
<h3><%= id %></h3><h3><%= pw %></h3><h3><%= name %></h3>
</body>
</html>
전 예제와 같이 Redirect는 데이터를 받지 못하고 Dispatcher는 데이터를 받아서 출력하는 모습 확인 가능