views
폴더에 새 HTML 파일 member_form.html
생성<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입</title>
</head>
<body>
<form action="/servletMain/member" method="post">
이름 : <input type="text" name="name"><br>
나이 : <input type="text" name="age"><br>
직업 : <input type="text" name="job"><br>
전화번호 : <input type="text" name="phone" size=3 maxlength=3> -
<input type="text" name="phone" size=4 maxlength=4> -
<input type="text" name="phone" size=4 maxlength=4><br>
<input type="submit" value="전송">
</form>
</body>
</html>
kr.web.ch02
에 새 클래스 MemberServlet
생성package kr.web.ch02;
import java.io.IOException;
import java.io.PrintWriter;
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("/member")
public class MemberServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String age = request.getParameter("age");
String job = request.getParameter("job");
// 문서 타입 및 캐릭터셋 지정
response.setContentType("text/html;charset=UTF-8");
// HTML 출력을 위한 출력 스트림 생성
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>회원 가입</title></head>");
out.println("<body>");
out.println("회원 가입을 축하합니다.<br>====회원 정보====</br>");
out.println("이름 : " + name + "<br>");
out.println("나이 : " + age + "<br>");
out.println("직업 : " + job + "<br>");
String[] phones = request.getParameterValues("phone"); // <input> 태그 type 중 checkbox, radio는 선택하지 않으면 아예 파라미터가 전송되지 않지만(getParamterValeus() 메서드는 파라미터가 존재하지 않으면 null 반환), 그 외의 type은 입력하지 않아도 빈 문자열이 전송됨
if(!phones[0].equals("") && !phones[1].equals("") && !phones[2].equals("")) {
for(int i=0;i<phones.length;i++) {
if(i>0) out.println("-");
out.println(phones[i]);
}
}
else { // 전화번호 3개 칸 중 하나라도 입력하지 않은 경우
out.println("잘못 명시했습니다!");
}
out.println("</body>");
out.println("</html>");
out.close();
}
}
init()
service()
메서드 이전에 수행됨service()
doGet()
또는 doPost()
)를 호출service()
를 재정의하지만, 수동 작업시에는 doGet()
과 doPost()
를 재정의하는 것이 일반적destory()
kr.web.ch02
에 새 클래스 LifeCycle
생성package kr.web.ch02;
import java.io.IOException;
import java.io.PrintWriter;
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("/lifeCycle")
public class LifeCycle extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("init() 메서드 호출");
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("service() 메서드 호출");
// 문서 타입 및 캐릭터셋 지정
response.setContentType("text/html;charset=utf-8");
// HTML 출력을 위한 출력 스트림 생성
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Servlet Life Cycle</title></head>");
out.println("<body>");
out.println("서블릿 생명 주기 학습하기");
out.println("</body>");
out.println("</html>");
out.close();
}
@Override
public void destroy() {
System.out.println("destroy() 메서드 호출 : 본 메서드는 Servlet이 더 이상 사용되지 않을 때만 호출됨");
}
}
kr.web.ch01
의 클래스 HelloWorld
에서 @WebServlet
을 주석 처리WEB-INF
폴더의 web.xml
를 열고, 왼쪽 하단의 Source
탭 선택<?xml version="1.0" encoding="UTF-8"?> <!-- XML 선언 -->
<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>servletMain</display-name> <!-- 프로젝트명 -->
<servlet> <!-- 식별자와 서블릿 클래스를 매핑 -->
<servlet-name>HelloWorld</servlet-name> <!-- 서블릿명을 식별자로 사용 -->
<servlet-class>kr.web.ch01.HelloWorld</servlet-class> <!-- 패키지명을 포함한 실제 클래스명 -->
</servlet>
<servlet-mapping> <!-- 식별자와 URL 주소를 매핑 -->
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern> <!-- Context Root 이후의 상세 경로 -->
</servlet-mapping>
<welcome-file-list> <!-- 웹 사이트의 최상위 경로("/")로 접속시 불러올 메인 페이지 후보; 호출 실패시 순차적으로 목록의 다음 파일을 호출 -->
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
jspMain
입력 후 Next-Next-Generate web.xml depolyment descriptor 선택 후 Finishsrc/main/webapp
폴더 오른쪽 클릭하고 새 JSP 파일 index.jsp
생성<!-- JSP 설정 정보 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- HTML -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>First JSP</title>
</head>
<body>
Hello JSP!
</body>
</html>
src/main/webapp
폴더 오른쪽 클릭하고 새 폴더 ch01-basic
생성 후 새 JSP 파일 s01_now.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>오늘의 날짜와 시간</title>
</head>
<body>
<%
// 객체 생성
Date nowTime = new Date();
%>
현재 날짜와 시간은 <%= nowTime %>입니다.
<br>--------<br>
<%
// 객체 생성
SimpleDateFormat sf = new SimpleDateFormat("yyyy년 MM월 DD일 a hh:mm:ss");
%>
현재 날짜와 시간은 <%= sf.format(nowTime) %>입니다.
</body>
</html>
s02_hundred.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>1부터 100까지의 합</title>
</head>
<body>
<h1>1부터 100까지의 합</h1>
<%
int total = 0;
for(int i=1;i<=100;i++) {
total += i;
}
// 출력
out.println("1부터 100까지의 합 : " + total);
%>
</body>
</html>
s03_gugudan.jsp
생성><%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>구구단 - 5단</title>
</head>
<body>
<%
for(int i=1;i<=9;i++) {
// 출력
out.println("5 * " + i + " = " + 5 * i + "<br>");
}
%>
</body>
</html>
<% %>
<%= %>
<%! %>
ch02-script
생성하고 새 JSP 파일 s01_script.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>
<h2>배열의 내용 출력 : 선언부, 스크립트릿</h2>
<%!
// 선언부 : 변수 선언, 메서드 선언
String[] str = {"JSP가", "정말", "재미", "있다"};
%>
<table border="1">
<tr>
<th>배열의 인덱스</th>
<th>배열의 내용</th>
</tr>
<%
// 스크립트릿 : 변수 선언, 연산, 제어문, 출력
for(int i=0;i<str.length;i++) {
out.println("<tr>"); // 스크립트릿에서 출력하는 것은 서블릿과 같은 방식으로, 문자열로 태그를 작성하기 때문에 속성 지정이나 JavaScript, CSS 등을 활용하기 불편해서 권장되지 않음
out.println("<td>" + i + "</td>");
out.println("<td>" + str[i] + "</td>");
out.println("</tr>");
}
%>
</table>
<br>
<h2>배열의 내용 출력 - 선언부, 스크립트릿, 표현식</h2>
<table border="1">
<tr>
<th>배열의 인덱스</th>
<th>배열의 내용</th>
</tr>
<%
for(int i=0;i<str.length;i++) { // 스크립트릿 내부에는 표현식을 사용할 수 없으므로, 스크립트릿 영역을 분할 후 스크립트릿 영역 바깥에 표현식을 사용해야 함
%>
<tr>
<!-- 표현식 : 변수의 값 출력, 메서드의 결과 값 출력, 연산의 결과 값 출력 -->
<%-- JSP 주석 : Java 주석과 마찬가지로 컴파일시 제외되어 HTML 페이지 원본 보기에 나타나지 않음 --%>
<td><%= i %></td>
<td><%= str[i] %></td>
</tr>
<%
} // for문 시작과 끝 영역을 분할한 경우, 두 영역 사이에 오는 HTML 영역은 for문에 의해 반복됨
%>
</table>
<br>
<h2>배열의 내용 출력 : 확장 for문</h2>
<table border="1">
<tr>
<th>배열의 내용</th>
</tr>
<%
for(String s : str) {
%>
<tr>
<td><%= s %></td>
</tr>
<%
}
%>
</table>
<style type="text/css"> /* 테이블의 행과 열을 pivot */
table {border-collapse: collapse;}
tbody {display: flex; flex-direction: row;}
tr {display: flex; flex-direction: column;}
</style>
</body>
</html>
s02_script.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>
<%--
[실습 문제]
배열 생성(score) 국어, 수학, 영어
[출력 예시]
국어 : 88
수학 : 99
영어 : 86
총점 : 273
평균 : 91
--%>
<%!
String[] subject = {"국어", "수학", "영어"};
int[] score = {88, 99, 86};
// int sum = 0, avg = 0; // 변수를 선언부에서 선언하면 서블릿에서 멤버 변수로 만들어져 HTML 요청(새로고침 등)이 반복될 때 변수의 값이 계속 유지됨; 즉, 두 번째 요청시 sum의 값이 273인 상태에서 다시 한 번 for문을 수행하므로 요청시마다 값이 계속해서 증가
%>
<%
int sum = 0, avg = 0; // 변수를 스크립트릿에서 선언하면 서블릿에서 service() 메서드의 지역 변수로 만들어져 HTML 요청시마다 변수가 새로 생성 및 초기화됨
for(int i=0;i<score.length;i++) {
sum += score[i]; // 총점 구하기
%>
<%= subject[i] %> : <%= score[i] %><br> <%-- 과목명과 점수 출력 --%>
<%
}
avg = sum/score.length; // 평균 구하기
%>
<%--
국어 : <%= score[0] %><br>
수학 : <%= score[1] %><br>
영어 : <%= score[2] %><br>
--%>
총점 : <%= sum %><br>
평균 : <%= avg %>
</body>
</html>
C:\javaWork\workspace_jsp\.metadata\.plugins\org.eclipse.wst.server.core
temp0
에 Tomcat과 거의 같은 디렉토리 구조가 있음
C:\javaWork\workspace_jsp\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\jspMain\org\apache\jsp\ch02_002dscript
기본 객체 | 자료형 | 설명 |
---|---|---|
request | javax.servlet.HttpServletRequest |
클라이언트의 요청 정보를 저장 |
response | javax.servlet.HttpServletResponse |
응답 정보를 저장 |
pageContext | javax.servlet.jsp.PageContext |
JSP 페이지에 대한 정보를 저장 |
session | javax.servlet.HttpSession |
HTTP 세션 정보를 저장 |
application | javax.servlet.ServletContext |
웹 어플리케이션에 대한 정보를 저장 |
out | javax.servlet.jsp.JspWriter |
JSP 페이지가 생성하는 결과를 출력할 때 사용되는 출력 스트림 |
config | javax.servlet.ServletConfig |
JSP 페이지에 대한 설정 정보를 저장 |
page | java.lang.Object |
JSP 페이지를 구현한 자바 클래스 인스턴스 |
exception | java.lang.Throwable |
예외 객체(에러 페이지에서만 사용) |
웹 브라우저가 웹 서버에 전송한 요청 관련 정보 제공
주요 기능
URL(=전체 주소=절대 주소)
URI(=부분 주소=상대 주소)
ch03-nestedObject
생성하고 새 JSP 파일 s01_requestInfo.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는 HttpServletRequest 객체의 참조 변수 --%>
클라이언트의 IP : <%= request.getRemoteAddr() %><br> <%-- getRemoteAddr() 메서드는 요청을 보낸 클라이언트 혹은 마지막 프록시의 IP 주소를 IPv6 형식으로 반환하며, localhost로 접속시에는 실제 IP 주소가 아닌 0:0:0:0:0:0:0:1을 반환 --%>
요청 정보 프로토콜 : <%= request.getProtocol() %><br>
요청 정보 전송 방식 : <%= request.getMethod() %><br> <%-- URL로 요청했으므로 GET 방식 --%>
요청 URL(Uniform Resource Locator) : <%= request.getRequestURL() %><br> <%-- 전체 주소(=절대 주소) --%>
요청 URI(Uniform Resource Identifier) : <%= request.getRequestURI() %><br> <%-- Root를 생략한(=Context Root부터 시작하는) 부분 주소(=상대 주소) --%>
컨텍스트 경로 : <%= request.getContextPath() %><br>
서버 이름 : <%= request.getServerName() %><br>
서버 포트 : <%= request.getServerPort() %> <%-- 상용 서비스는 80이 기본이지만, Tomcat의 경우 테스트용으로 8080이 설정되어 있음 --%>
</body>
</html>
s02_viewHeaderList.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>헤더 목록 출력</title>
</head>
<body>
<%
Enumeration headerEnum = request.getHeaderNames();
while(headerEnum.hasMoreElements()) { // while 시작
// 헤더명 구하기
String headerName = (String)headerEnum.nextElement();
// 헤더 값 구하기
String headerValue = request.getHeader(headerName);
%>
<%= headerName %> = <%= headerValue %><br>
<%
} // while 끝
%>
</body>
</html>
s03_makeTestForm.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="s04_viewParameter.jsp" method="post">
이름 : <input type="text" name="name" size="10"><br>
주소 : <input type="text" name="address" size="30"><br>
좋아하는 동물 :
<label><input type="checkbox" name="pet" value="dog">강아지</label>
<label><input type="checkbox" name="pet" value="cat">고양이</label>
<label><input type="checkbox" name="pet" value="bird">새</label><br>
<input type="submit" value="전송">
</form>
</body>
</html>
s04_viewParameter.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>요청 파라미터 출력</title>
</head>
<body>
<h3>request.getParameter() 메서드 사용</h3>
name 파라미터 = <%= request.getParameter("name") %><br>
address 파라미터 = <%= request.getParameter("address") %><br>
<h3>request.getParameterValues() 메서드 사용</h3>
<%
String[] values = request.getParameterValues("pet");
if(values!=null) { // 체크박스의 경우 선택하지 않으면 파라미터가 아예 전송되지 않으므로 배열로 처리시 NPE가 발생할 수 있음
for(int i=0;i<values.length;i++) { // for 시작
%>
<%= values[i] %>
<%
} // for 끝
}
%>
</body>
</html>