세션이란 ? 

- 둘 이상의 page request에서 사용자를 식별하거나, 웹 사이트를 방문하고 해당 사용자에 대한 정보를 저장하는 방법을 제공한다.

- Servlet container는 HttpSession을 사용하여 Http client - HTTP server간의 세션을 생성한다.

- 세션은 한 명의 사용자에 해당한다. (브라우저 당 하나의 세션 객체가 생성된다.)

- 서버는 Cookie, rewriting URL과 같은 방법으로 세션을 유지하면서 관리할 수 있다.

- 객체를 세션에 바인딩하여 사용자 정보를 유지할 수 있다.

 

톰캣의 세션 동작 원리

- session.isNew() 메소드는 세션이 생성된 곳에서 아직 클라이언트가 세션 ID를 모르는 상태(최초 접속 상태)의 경우 "true"를 반환한다.

- 이 경우 아직 클라이언트 정보가 서버에 유지되지 않기 때문에, 서버는 Response Headers에 JSESSIONID 이라는 이름으로 쿠키 정보를 client로 전달한다.

- session.isNew() 메소드는 "false"를 반환하면 이미 세션이 설정되어있는 경우이며, 이 경우 client브라우저는 로컬에 저장되어 있는 JSESSIONID 쿠키 값을 request header에 담아 서버로 전송한다.

- 서버는 client로 부터 JSESSJIONID 쿠키 값을 전달 받으면 response로 JSESSIONIS 쿠키 값을 client로 보내지 않는다.

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> 세션 동작 원리 </h3>

<!-- isNew() :  클라이언트가 세션 ID를 모르는 상태(최초 접속)인 경우 true를 반환 --%>
<!-- isNew()가 true를 반환하면 클라이언트 정보가 서버에 저장되지 않은 상태이다. -->
<p> isNew() : <%= session.isNew() %></p>
<hr>

<h4>쿠키 내용</h4>
<%
	Cookie[] cc = request.getCookies();
	if(cc != null) {
		for(Cookie c : cc) {
			String name = c.getName();
			String value = c.getValue();
			out.print("<p>"+name+" : "+ value + "</p>");
		}
	}
%>

</body>
</html>

 

쿠키를 사용하지 않는 세션 ID의 관리

- 휴대 기기 등 모든 단말이 쿠키를 사용할 수 있는 것은 아니다.

- 쿠키를 사용할 수 없는 경우 URL에 직접 세션 ID를 작성하여 세션 ID를 클라이언트 측에 유지시킨다.

구체적으로는 HttpServletResponse의 encodeURL (String url) 메소드를 사용한다.

PrintWriter writer = response.getWriter();

String link = "/main";

link = response.encodeURL(link);

writer.println("<a href = '"+link+"'>메인</a>");

encodeURL() 메소드를 사용하면 지정된 인수에 대해 다음의 값을 추가하며, 쿠키를 사용 못해도 클라이언트측에서 세션 ID를 보유할 수 있다.

jsessionid = 세션id

 

예제

더보기

sessionEx2

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>session : 클라이언트의 정보를 서버에 저장</h3>
<!-- 세션은 일반적으로 로그인 처리 등에서 이용된다. -->

<p>
  <a href="sessionSet.jsp">세션 설정</a> |
  <a href="sessionInfo.jsp">세션 확인</a> |
  <a href="sessionRemove.jsp">세션 제거</a>
</p>
</body>
</html>

sessionSet

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	// session : 세션을 나타내는 JSP 내장 객체(HttpSession)
	// 서블릿에서 세션 객체 구하기 : HttpSession sess = request.getSession();
	// EL에서의 세션 객체 : sessionScope
	
	// 세션 유지시간 설정(톰캣 기본 세션 유지시간 : 30분)
	session.setMaxInactiveInterval(60*20); // 단위 : 초
	
	session.setAttribute("name", "홍자바");
	session.setAttribute("age", 20);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>session 설정</h3>

<p>
	<a href="sessionEx2.jsp">돌아가기</a>
</p>

</body>
</html>

sessionInfo

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	String name = "";
	int age = 0;
	
	try {
		// 세션에 설정한 값 가져오기
		name = (String)session.getAttribute("name");
		age = (Integer)session.getAttribute("age");
	} catch(Exception e) {
	}
	
	// 세션 유지시간
	int interval = session.getMaxInactiveInterval();
	
	// 세션 아이디
	String id = session.getId();
	
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	
	// 세션 생성 시간
	Date date1 = new Date(session.getCreationTime());
	String create_date = sdf.format(date1);
	
	// 세션 마지막 접속 시간
	Date date2 = new Date(session.getLastAccessedTime());
	String last_date = sdf.format(date2);
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>session 정보</h3>

<p> 이름과 나이 : <%=name%>, <%=age%> </p>
<p> EL을 이용하여 세션 값 가져오기 : ${sessionScope.name}, ${sessionScope.age}</p>
<p> 세션 최대 유지시간 : <%=interval / 60 %>분 </p>
<p> 세션 아이디 : <%=id%></p>
<p> 세션 생성 시간 : <%=create_date %></p>
<p> 세션 마지막 접속 시간 : <%=last_date %></p>
<hr>

<p>
	<a href="sessionEx2.jsp">돌아가기</a>
</p>

</body>
</html>

sessionRemove

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	// 세션에 저장된 속성값 지우기
	session.removeAttribute("name");
	session.removeAttribute("age");
	
	// 세션에 저장된 모든 속성값을 지우고 세션을 초기화
	session.invalidate();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> session 지우기</h3>

<p>
	<a href="sessionEx2.jsp">돌아가기</a>
</p>

</body>
</html>

 

 

 

쿠키란?

- 쿠키는 클라이언트에 대한 정보를 클라이언트의 하드디스크에 저장한 text파일

- 쿠키는 텍스트 형태로 저장되기 때문에 변조, 복사 가능하여 보안성이 없다.

- 쿠키는 서버에서 사용자에게 편리한 기능을 제공하기 위해 많이 사용되고, 웹 브라우저에 의해 관리된다.

- 일반적으로 브라우저는 각 웹 서버 당 20개의 쿠키와 총 300개의 쿠키를 지원하며 쿠키 크기는 각각 4kb로 제한될 수 있다.

- 쿠키 정보는 javax.servlet.http.Cookie클래에 의해 관리 된다.

 

쿠키 설정하기

1) Cookie 객체를 생성한다. 생성자에 문자열로 쿠키이름과 값을 설정한다.

- 형식

 Cookie cookie = ew Cookie("key", "value");

- 이름과 값은 영수자와. 공백이나 다음 문자를 포함할 수 있다.

[] () = , " / ? @ : ;

2) setMaxAge(초) 메소드를 이용하여 쿠키 유효 기간을 초단위로 설정한다.

- 유료 기간을 설정하지 않으면 브라우저가 종료될 때까지 쿠키가 지속됨을 나타내는 -1 이다.

- 다음은 쿠키 유효시간을 24시간으로 설정한 예이다.

cookie.setMaxAge(60*60*24);

3) HTTP응답 헤더에 쿠키를 보낸다.

- HttpServletResponse 인터페이스의 addCookie() 메소드에 의해 HTTP 응답 헤더에 쿠키를 보낸다.

- JSP에서 쿠키를 설정하는 방법은 다음과 같다.

response.addCookie(cookie);

 

Cookie 유효 시간 설정

- setMaxAge(int expiry)메소드를 이요하여 유효시간 초 단위로 설정한다.

- expiry

음수 : 브라우저가 종료되면 쿠키가 제거된다.

0: 생성과 동시에 제거

양수 : 초 단위로 해당 시간만큼 유지된다.

설정하지 않은 경우 : 디폴트로 -1이 설정되어 브라우저가 종료할 때 까지 유효하다.

 

Cookie 설정 시 주의 사항

- 쿠키의 이름이나 값에 한글 등이 포함되는 경우 다음과 같이 java.net 패키지의 URLEncoder.encode()메소드를 이용하여 주소 형식으로 인코딩해야한다.

Cookie cookie = new Cookie("key", URLEncoder.encode("값", "utf-8");

- Cookie의 유효범위를 설정하지 않는 경우. 쿠키를 설정하는 페이지의 경로와 하위 경로에서만 접근가능하다. 

따라서 모든 경로에서 쿠키의 값을 반환 받을 경우에는 다음과 같이 유효 범위를 "/"로 설정한다.

cookie.setPath("/");

 

Cookie 가져오기 및 제거

- Cookie 가져오기

1) 쿠키를 가져오기 위해서는 HttpServletRequest 인터페이스의 getCookies()메소드를 이용해서 가져온다.

- getCookies() 메소드는 javax.servlet.http.Cookie객체의 배열을 반환한다.

- JSP 에서 쿠키 가져오기

Cookie []ck = request.getCookies();

2) 반환 받은 Cookie객체의 getName() 과 getValue() 메소드를 이용하여 쿠키를 가져 온다.

String name, value;
	if( ck!=null) {
		for(Cookie c : ck) {
			name = c.getName();
			value = c.getValue();
            			:
		}
	}

 

- Cookie 제거하기

쿠키 값을 제거하기 위해서는 쿠키에 대한 값을 지우고 유효기간을 만료시킨다.

JSP 에서 쿠키 제거 방법

Cookie cookie = new Cookie("제거할쿠키이름",null) // 쿠키 값 지우기

cookie.setMaxAge(0); // 유효시간 만료

response.addCookie(cookie): // HTTP 응답 헤더에 제거할 쿠키를 보낸다.

 

확인용 예제

더보기

cookieEx

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>cookie 예제</h3>

<p>
	<a href="setCookie.jsp">쿠키설정</a>
	<a href="getCookie.jsp">쿠키확인</a>
	<a href="removeCookie.jsp">쿠키제거</a>
</p>

</body>
</html>

setCookie

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	// 쿠키 설정 : 서버가 클라이언트 컴퓨터에 정보를 저장
	// 쿠키의 유효시간을 설정하지 않으면(life cycle), 브라우저가 종료되면 쿠키도 제거된다.
	Cookie c1 = new Cookie("subject", "java"); // 쿠키이름, 쿠키값 생성자를 이용해서 객체생성. 쿠키는 String만 가능
	response.addCookie(c1);
	
	Cookie c2 = new Cookie("subject2", "spring");
	c2.setMaxAge(60 * 60); // 1시간 : 쿠키 유효시간(단위 : 초)
	response.addCookie(c2);
	
	// 한글을 쿠키로 설정할 경우에는 반드시 인코딩
	Cookie c3 = new Cookie("subject3", URLEncoder.encode("오라클", "utf-8") );
	c3.setMaxAge(-1); // -1 : 브라우저가 종료되면 쿠키도 제거
	response.addCookie(c3);
	
	// 쿠키는 기본적으로 쿠키를 설정한 경로에서만 접근할 수 있다.
	Cookie c4 = new Cookie("tel", "010-1111-1111");
	c4.setPath("/"); // 모든 경로에서 쿠키를 접근 할 수 있도록 설정
	response.addCookie(c4);
	
	Cookie c5 = new Cookie("age", "20"); // 쿠키는 문자열만 가능하다. 숫자도 따옴표형식으로 넣어야함.
	c5.setMaxAge(0); // 쿠키 생성과 동시에 제거(일반적으로 쿠키를 제거할 때 사용)
	response.addCookie(c5);
	
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> 쿠키 설정 </h3>
<p>
	<a href="cookieEx.jsp">돌아가기</a>
</p>

</body>
</html>

getCookie

<%@page import="java.net.URLDecoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>쿠키 가져오기 : 클라이언트 컴퓨터에 저장된 쿠키를 서버로 가져오기</h3>
<%
	Cookie[] cc = request.getCookies(); // 쿠키는 배열로 가져올 수 있따.
	if( cc != null ) {
		for(Cookie c:cc){
			String name = c.getName(); // 쿠키 이름
			String value = c.getValue(); // 쿠키 값
			if(name.equals("subject3")) {
				value = URLDecoder.decode(value, "utf-8");
			}
			
			out.print("<p>" + name + " : " + value + "</p>");
		}
	}
%>
<hr>

<p>
	<a href="cookieEx.jsp">돌아가기</a>
</p>

</body>
</html>

 

p1

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	Cookie c = new Cookie("sname1", URLEncoder.encode("컴퓨터", "utf-8") );
	response.addCookie(c);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>컴퓨터</h3>
<p> 컴퓨터중 최고의 성능</p>
<p> 제조사 : 삼성 </p>
<p> 가격 : 1,000,000 </p>
<hr>
<p><a href="shop.jsp">돌아가기</a></p>
</body>
</html>

p2

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	Cookie c = new Cookie("sname2", URLEncoder.encode("핸드폰", "utf-8") );
	response.addCookie(c);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>핸드폰</h3>
<p> 핸드폰중 최고의 성능</p>
<p> 제조사 : 삼성 </p>
<p> 가격 : 1,200,000 </p>
<hr>
<p><a href="shop.jsp">돌아가기</a></p>
</body>
</html>

p3

<%@page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	Cookie c = new Cookie("sname3", URLEncoder.encode("노트북", "utf-8") );
	response.addCookie(c);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>노트북</h3>
<p> 노트북중 최고의 성능</p>
<p> 제조사 : 삼성 </p>
<p> 가격 : 1,500,000 </p>
<hr>
<p><a href="shop.jsp">돌아가기</a></p>
</body>
</html>

게시판 URI 및 JSP 생각하기

 

1. URI 및 JSP
  1) 리스트
 uri : /cp/bbs/list.do
 jsp : /WEB-INF/views/bbs/list.jsp
 
  2) 글쓰기 폼
 uri : /cp/bbs/write.do
 jsp : /WEB-INF/views/bbs/write.jsp

  3) 글쓰기 완료
 uri : /cp/bbs/write_ok.do -> list.do 로 리다이렉트

  4) 글보기
 uri : /cp/bbs/article.do
 jsp : /WEB-INF/views/bbs/article.jsp
 
  5) 글수정 폼
 uri : /cp/bbs/update.do
 jsp : /WEB-INF/views/bbs/write.jsp  

  6) 글수정 완료
 uri : /cp/bbs/update_ok.do -> list.do 로 리다이렉트

  7) 글삭제
 uri : /cp/bbs/delete.do -> list.do 로 리다이렉트

 

2. 흐름도와 파라미터(클라이언트가 서버에 보내는 값)
  1) 리스트

- 리스트 --> 리스트 : 페이지번호클릭(페이지번호[, 검색컬럼, 검색값])
- 리스트 --> 리스트 : 검색(검색컬럼, 검색값)
- 리스트 --> 리스트 : 초기화(검색 해제)
- 리스트 --> 글쓰기폼 : 등록하기 버튼
- 리스트 --> 글보기 : 제목클릭(글번호, 페이지번호[, 검색컬럼, 검색값])

  2) 글쓰기폼
- 글쓰기폼 --> 등록하기 : 글저장 --> 리스트로 리다이렉트
                |
           (폼 데이터 : 제목, 작성자, 내용, 패스워드)
- 글쓰기폼 --> 등록취소 : 리스트로 가기

  3) 글보기
- 글보기 --> 리스트 : 리스트버튼(페이지번호[, 검색컬럼, 검색값])
- 글보기 --> 글보기 : 이전글/다음글(이전글/다음글번호, 페이지번호[, 검색컬럼, 검색값])
- 글보기 --> 수정폼 : 수정버튼(글번호, 페이지번호)
- 글보기 --> 글삭제 : 삭제버튼(페이지번호[, 검색컬럼, 검색값])

  4) 글수정폼
- 글수정폼 --> 수정완료 : 글수정버튼--> 리스트로 리다이렉트(글보기로 리다이렉트)
                |
         (폼 데이터 : 제목, 작성자, 내용, 패스워드, 글번호, 페이지번호) // 수정할게시글번호!!
- 글수정폼 --> 수정취소 : 리스트로 가기

  5) 글삭제 --> 리스트로 리다이렉트(페이지번호[, 검색컬럼, 검색값])

 

 

자유게시판으로 사용할 DB table

더보기

-- 게시판 테이블
CREATE TABLE bbs (
num NUMBER NOT NULL,
name VARCHAR2(30) NOT NULL,
pwd VARCHAR2(50) NOT NULL,
subject VARCHAR2(255) NOT NULL,
content VARCHAR2(4000) NOT NULL, -- 1300자 이상 저장을 위해서는 CLOB
ipAddr VARCHAR2(50) NOT NULL,
hitCount NUMBER DEFAULT 0,
reg_date DATE DEFAULT SYSDATE,
CONSTRAINT pk_bbs_num PRIMARY KEY(num)
);

-- 게시판 시퀀스
CREATE SEQUENCE bbs_seq
INCREMENT BY 1;
START WITH 1
NOMAXVALUE
NOCYCLE
NOCACHE;

 

페이징 처리에 사용하는 쿼리 Query

더보기

-- ORACLE :

 

아래 쿼리는 오라클에서 성능이 우수함
SELECT * FROM (
    SELECT ROWNUM rnum, tb.* FROM (
        SELECT num, name, subject, hitCount, 
            TO_CHAR(reg_date, 'YYYY-MM-DD') reg_date
        FROM bbs
        ORDER BY num DESC
    ) tb WHERE ROWNUM <= 끝
) WHERE rnum >= 시작;
-- 수정/삭제가 빈번히 일어나는 경우 index의 성능이 좋지 않음.

-- ORACLE 12C 이상 : 위 쿼리보다 성능이 좋지 않음
SELECT num, name, subject, hitCount,
    TO_CHAR(reg_date, 'YYYY-MM-DD') reg_date
FROM bbs
ORDER BY num DESC
OFFSET 30 ROWS FETCH FIRST 10 ROWS ONLY;
---------------------------------
-- MySQL
SELECT num, name, subject, hitCount,
    DATE_FORMAT(reg_date, '%Y-%m-%d') AS reg_date
FROM bbs
ORDER BY num DESC
LIMIT 건너뛸개수, 가져올개수;

 

페이징 처리 로직

 

Example

페이지당 게시글 10개

전체 데이터 개수 965개

-> 전체 페이지 개수는 97개

페이지당 게시글 10개

전체 데이터 개수 960개

-> 전체 페이지 개수는 96개

 

즉, (전체 데이터 개수 / 페이지당 게시글) 에서 소수점이하가 없으면 ( 나머지가 없으면) 몫만큼의 개수가 전체페이지 개수이고, 그렇지 않을경우는 +1을 해줘야 한다.

 

전체데이터개수/페이지당게시글 + (전체데이터개수%페이지당게시글== 0 ? 0 : 1);

// 자바에서 int는 정수형만 취급하므로 나누었을 때 소수가 표현되지 않음.

 

1페이지에는 1~10까지의 자료가 나온다.

2페이지는 11~20

3페이지는 21~30

:

n페이지 1+(n-1*10)~n*10 

 

package com.util;

public class MyUtil {
	/**
	 * 전체 페이지수 구하기
	 * @param rows			한화면에 출력할 목록 수
	 * @param dataCount		총 데이터 수
	 * @return				전체 페이지 수
	 */
	public int pageCount(int rows, int dataCount) {
		if(dataCount <= 0) {
			return 0;
		}
		
		return dataCount / rows +(dataCount % rows > 0 ? 1 : 0);
	}
	
	/**
	 * 페이징 처리(GET 방식)
	 * @param current_page	현재 표시되는 페이지 번호
	 * @param total_page	전체 페이지 수
	 * @param list_url		링크를 설정할 주소
	 * @return				페이지 처리 결과
	 */
	public String paging(int current_page, int total_page, String list_url) {
		StringBuilder sb = new StringBuilder();
		
		int numPerBlock = 10;
		int currentPageSetup;
		int n, page;
		
		if(current_page < 1 || total_page < 1) {
			return "";
		} // 데이터가 없으면 설정할 필요가 없음
		
		if(list_url.indexOf("?") != -1) {
			list_url += "&";
		} else {
			list_url += "?";
		}
		
		// currentPageSetup : 표시할 첫 페이지-1
		currentPageSetup = (current_page / numPerBlock) * numPerBlock;
		if(current_page % numPerBlock == 0) {
			currentPageSetup = currentPageSetup - numPerBlock;
		}
		
		sb.append("<div class='paginate'>");
		
		// 처음페이지, 이전(10페이지 전)
		n = current_page - numPerBlock;
		if(total_page > numPerBlock && currentPageSetup > 0) {
			sb.append("<a href='"+list_url+"page=1'>처음</a>");
			sb.append("<a href='"+list_url+"page="+n+"'>이전</a>");
		}
		
		// 페이징 처리
		page = currentPageSetup + 1;
		while(page <= total_page && page <= (currentPageSetup+numPerBlock)) {
			if(page == current_page) {
				sb.append("<span>"+page+"</span>");
			} else {
				sb.append("<a href='"+list_url+"page="+page+"'>"+page+"</a>");				
			}
			page++;
		}
		
		// 다음(10페이지 후), 마지막페이지
		n = current_page + numPerBlock;
		if(n > total_page) n = total_page;
		if(total_page - currentPageSetup > numPerBlock) {
			sb.append("<a href='"+list_url+"page="+n+"'>다음</a>");
			sb.append("<a href='"+list_url+"page="+total_page+"'>끝</a>");
		}
		
		sb.append("</div>");
		
		return sb.toString();
	}
	
}

 

 

테스트

더보기
<%@page import="com.util.MyUtil"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");

	// 파라미터로 넘어온 페이지번호(JSP에서 page는 예약어로 변수명으로 사용 불가)
	String pageNum = request.getParameter("page");
	int current_page = 1;
	if(pageNum != null) {
		current_page = Integer.parseInt(pageNum);
	}
	
	MyUtil util = new MyUtil();
	
	int dataCount = 965;
	int rows = 10;
	int total_page = util.pageCount(rows, dataCount);
	if(current_page > total_page) {
		current_page = total_page;
	}
	
	String listUrl = "list.jsp";
	String paging = util.paging(current_page, total_page, listUrl);
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<style type="text/css">
* {
	margin: 0; padding: 0;
	box-sizing: border-box;
}

body {
	font-size: 14px;
	font-family: 맑은 고딕, 나눔고딕, 돋움, sans-serif;
}

.paginate {
	text-align: center;
	font-size: 14px;
}

.paginate a {
	border: 1px solid #ccc;
	color: #000;
	font-weight: 600;
	text-decoration: none;
	padding: 3px 7px;
	margin-left: 3px;
	vertical-align: middle;
}

.paginate a:hover, .paginate a:active {
	color: #6771ff;
}

.paginate span {
	border: 1px solid #e28d8d;
	color: #cb3536;
	font-weight: 600;
	padding: 3px 7px;
	margin-left: 3px;
	vertical-align: middle;
}

.paginate :first-child {
	margin-left: 0;
}

.container {
	width: 700px;
	margin: 30px auto;
}

</style>


</head>
<body>

<div class="container">
	<h3>페이징 처리 테스트</h3>
	
	<div style="padding-top: 10px;">
		<%= paging %>
	</div>
</div>


</body>
</html>

${pageContext.request.contextPath} 를 이용해서 cp의 이름을 가져온 후, 

원하는 주소창의 주소로 

여기서는 form 태그 안에 <%=cp>/insa/write.do 넣어준다. 그러면 서블릿을 통해 이 주소와 같으면 알아서 서버에서 클라이언트로 forward해준다.

 

서블릿에서 @WebServlet 이라는 annotation을 통해서 주소와 서블릿을 매핑시켜 /insa/* 라고 주면 주소창에 insa 밑에 뭐라고 주든(뭐든지) 이 서블릿 안으로 들어온다. GET방식이든 POST방식이든 process라는 메소드를 실행하고, 그 안에서 주소창에 준 주소에 따라서 jsp를 실행한다. 

 

더보기

insa.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<form action="<%=cp%>/insa/write_ok.do" method="post">
	<p> 이름 : <input type="text" name="name" required="required"> </p>
	<p> 생년월일 : <input type="date" name="birth" required="required"> </p>
	<p> 전화번호 : <input type="text" name="phone" required="required"> </p>
	<p> 기본급 : <input type="text" name="salary" required="required" pattern="\d+"> </p>
	<p> 수당 : <input type="text" name="bonus" required="required" pattern="\d+"> </p>
	<p>
		<button type="submit">등록하기</button> <%-- required가 먹으려면 button=submit 사용 --%>
		<button type="reset">다시입력</button>
	</p>
</form>

</body>
</html>

 

result.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>인사관리</h3>

<p> 이름 : ${name}</p>
<p> 이름 : <%=request.getAttribute("name") %></p>
<p> 생년월일 : ${birth}</p>
<p> 전화번호 : ${phone}</p>
<p> 기본급 : ${salary}</p>
<p> 수당 : ${bonus}</p>
<p> 세금 : ${tax}</p>
<p> 실수령액 : ${pay}</p>
<p> 나이 : ${age}</p>
<p> 띠 : ${tti}</p>
</body>
</html>

EL을 이용해서 표현식보다 더 쉽게 attribute를 받아서 쓸 수 있다.

 

 

insaServlet

package ch02.insa;

import java.io.IOException;
import java.text.NumberFormat;

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 com.util.DateUtil;

// insa 밑에 뭐가 오든 InsaServlet으로 와라. 서블릿이 우선순위가 높음
// 들어올 때는 GET 방식으로 들어옴
@WebServlet("/insa/*") // 주소와 서블릿 매핑
public class InsaServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		process(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		process(req, resp);
	}
	
	protected void process(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		
		String uri = req.getRequestURI();
		
		if(uri.indexOf("write.do") != -1) {
			// 입력 폼 출력
			writeForm(req, resp);
		} else if(uri.indexOf("write_ok.do") != -1) {
			// 전송 받은 파라미터를 이용하여 연산
			writeSubmit(req, resp);
		}
	}
	
	protected void forward(HttpServletRequest req, HttpServletResponse resp, String path) throws ServletException, IOException {
		RequestDispatcher rd = req.getRequestDispatcher(path);
		rd.forward(req, resp);
	}

	protected void writeForm(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 입력 폼 출력
		forward(req, resp, "/WEB-INF/views/insa/insa.jsp");
	}
	
	protected void writeSubmit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 클라이언트가 보낸 파라미터 정보
		
		String name = req.getParameter("name");
		String birth = req.getParameter("birth");
		String phone = req.getParameter("phone");
		int salary = Integer.parseInt(req.getParameter("salary")); 
		int bonus = Integer.parseInt(req.getParameter("bonus")); 
		
		DateUtil util = new DateUtil();
		int age = util.toAge(birth);
		String t = util.toTti(Integer.parseInt(birth.substring(0,4)));
		
		int total = salary+bonus;
		int tax = 0;
		if(total>=3000000)
			tax = (int)(total*0.03);
		else if(total>=2000000)
			tax = (int)(total*0.02);
		int pay = total-tax;
		
		NumberFormat nf = NumberFormat.getCurrencyInstance();
		
		// JSP에 보낼 속성
		
		req.setAttribute("name", name);
		req.setAttribute("birth", birth);
		req.setAttribute("phone", phone);
		req.setAttribute("age", age);
		req.setAttribute("tti", t);
		
		req.setAttribute("salary", nf.format(salary) );
		req.setAttribute("bonus", nf.format(bonus) );
		req.setAttribute("tax", nf.format(tax) );
		req.setAttribute("pay", nf.format(pay) );
		
		forward(req, resp, "/WEB-INF/views/insa/result.jsp");
	}


	
}

 

Deployment Descriptor

- Deployment Descriptor(배치 기술서)는 보통 Web Document Root 디렉토리에 WEB-INF 폴더 아래 web.xml 파일로 존재한다.

- Servlet 설정, Error Page 설정, Listener 및 Filter 설정, 보안 설정 등을 위한 Web Application의 설정 파일이다.

- URL과 실제 서블릿의 매핑 정보를 설정한다.

- 서버 자원(DB 설정) 등도 설정할 수 있으며, 설정된 서버 자원은 소스 코드 변경 없이 수정이 가능하다.

- 하나의 웹 어플리케이션에 하나만 존재한다.

- Servlet 3.0(jsp 2.2, Tomcat 7.0)부터는 web.xml 파일은 선택 사항으로 변경 되었다.

 

web.xml 에서의 서블릿 설정

- url-pattern의 유형

(1) Exactly matching

- 해당 URL 요청만 지정한 서블릿으로 처리하며, 반드시 "/"로 시작해야 한다.

- 형식 : /[경로/]이름

- 사용 예 : /bbs/list

(2) Directory matching

- "/경로/*" 형식으로 설정하며, "*" 부분은 모든 경로가 가능한 패턴이다.

- 사용 예 : /board/* -> /board/list, /board/article 처럼 * 자리에는 모든 경로가 가능하다.

(3) Extension matching

- 해당 확장자 요청을 지정한 서블릿으로 처리하며, "/"로 시작할 수 없고 확장자로 끝나야 한다.

- 형식 : *.확장자

- 사용 예 : *.do

(4) /

DefaultServlet에 대한 URL 패턴으로 DefaultServlet은 정적 리소스를 처리하는 톰캣의 기본 서블릿이다.

 

서블릿 실행과정 및 서블릿 작성

실행과정

1. 사용자가 URL로 요청하면 HTTP Request를 Servlet Container에 보낸다.

2. Servlet Container는 HttpServletRequest, HtttpServletResponse 두 객체를 생성한다.

3. 사용자가 요청한 URL을 분석하여 어느 서블릿에 대한 요청인지 찾는다. Deployment Descriptor파일인 web.xml을 분석하여 해당 서블릿을 찾는다.

4. 컨테이너는 해당 서블릿의 service() 메소드를 호출하며, HttpServlet클래스를 상속 받은 경우 POST, GET 여부에 따라 doGet() 또는 doPost()가 호출된다.

5. service()메소드는 클라이언트 요청을 처리 한 후 HttpServletResponse 객체에 응답을 보낸다. HttpServlet 클래스를 상속 받은 경우에는 doGet() 또는 doPost() 메소드가 클라이언트 요청을 처리한 후 HttpServletResponse 객체에 응답을 보낸다.

6. 응답이 완료되면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킨다. 

 

Servlet Architecture

개요

- 서블릿 아키텍처는 javax.servlet 과 javax.servlet.http의 패키지로 구성된다.

- javax.servlet 패키지는 모든 서블릿이 상속하거나 구현하는 일반적인 인터페이스와 클래스로 구성되어 있다.

- javax.servlet.http 패키지는 HTTP 프로토콜에 맞춘 클래스 및 인터페이스로 구성되어 있다.

 

Servlet 인터페이스

개요

- javax.servlet.Servlet 인터페이스는 서블릿이 구현해야 하는 메소드가 선언된 인터페이스이다.

- Servlet 인터페이스의 구현은 javax.servlet.GenericServlet 또는 GenericServlet 클래스를 상속 받은 javax.servlet.http.HttpServlet 클래스를 상속 받아 서블릿 클래스를 작성할 수 있다.

- Servlet 인터페이스는 서블릿을 초기화하고 클라이언트 요청을 처리하며 서블릿을 서버에서 제거하는 메소드를 가지고 있다. 이러한 메소드는 라이프 사이클 메소드라고 하며 다음 순서로 호출된다.

(1) 서블릿이 생성된 다음 init() 메소드로 초기화 한다.

(2) 클라이언트의 요청은 service() 메소드에서 처리한다.

(3) 서블릿을 제거해야 하는 경우에는 컨테이너는 destroy() 메소드를 호출한 다음 garvage collected 후 종료한다.

 

GenericServlet 추상 클래스

개요

- javax.servlet.GenericServlet 추상 클래스는 Servlet 과 ServletConfig 인터페이스를 구현한 클래스이다.

- 서블릿을 작성하기 위해서 GenericServlet 클래스를 상속 받아 쉽게 작성할 수 있지만, HttpServlet과 같은 프로토콜 별 하위 클래스를 작성하는 것이 더 일반적이다.

- 웹에서 사용하는 HTTP 서블릿은 일반적으로 GenericServlet 대신 HttpServlet을 상속 받아 작성한다.

- GenericServlet을 상속받아 서블릿 클래스를 작성하기 위해서는 추상 메소드인 service() 메소드만 재정의 하면 된다.

 

HttpServlet 추상 클래스

개요

- javax.servlet.http.HttpServlet 추상 클래스는 GenericServlet 클래스를 상속받은 하위클래스로 웹사이트에 적합한 HTTP 서블릿을 만들기 위해 상속 받는다.

- HttpServlet 의 하위 클래스는 최소한 하나의 메소드를 재정의하며, 재정의하는 메소드는 일반적으로 다음 중 하나의 메소드이다.

: 서블릿이 HTTP GET 요청을 처리하는 경우 doGet()

: 서블릿이 HTTP POST 요청을 처리하는 경우 doPost()

: 서블릿이 HTTP PUT 요청을 처리하는 경우 doPut()

: 서블릿이 HTTP DELETE 요청을 처리하는 경우 doDelete()

doOptions() 및 doTrace() 메소드도 있지만 재정의할 이유가 거의 없으며, 일반적으로 웹 서비스는 doGet()메소드와 doPost() 메소드를 재정의하여 개발한다.

- 서블릿은 일반적으로 멀티 스레드 서버에서 실행되므로 서블릿은 동시 요청을 처리하고 공유 리소스에 대한 액세스를 동기화하는 데 주의 해야한다. 공유 리소스에는 인스턴스 또는 클래스 변수와 같은 메모리 내 데이터와 파일, 데이터베이스 연결 및 네트워크 연결과 같은 외부 개체가 포함된다.

 

ex12 - POST 방식으로 파라미터를 서버에 넘길 때

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>폼 예제</h3>

<form method='post' action="ex12_ok.jsp">
	<p>이름 : <input type='text' name='name'></p>
	<p>학번 : <input type='text' name='studentId'></p>
	<p>성별 :
		남자 <input  type='radio' name='gender' value='M' checked="checked">
		여자 <input type='radio' name='gender' value='F'>
	</p>
	<p>좋아하는 과목 :
		<input type="text" name="subject">
		<input type="text" name="subject">
		<input type="text" name="subject">
	</p>
	<p>출신도 :
		<select name="city">
			<option value="">::선택::</option>
			<option value="서울">서울</option>
			<option value="경기">경기</option>
			<option value="인천">인천</option>
			<option value="기타">기타</option>
		</select>
	</p>
	<p>취미 :
		<select name="hobby" multiple="multiple" size="5">
			<option value="운동">운동하기</option>
			<option value="영화">영화보기</option>
			<option value="등산">등산가기</option>
			<option value="여행">여행하기</option>
			<option value="게임">게임하기</option>
		</select>
	</p>
	<p>
		<button type="submit">등록하기</button>
	</p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");
	
	String name = request.getParameter("name");
	String studentId = request.getParameter("studentId");
	String gender = request.getParameter("gender");
	
	String[] sub = request.getParameterValues("subject");
	String subject = "";
	for(String s : sub) {
		if(s.length() != 0) {
			subject += s + "  ";
		}
	}

	String city = request.getParameter("city");
	
	String[] hob = request.getParameterValues("hobby");
	String hobby = "";
	if(hob != null) {
		for(String h : hob) {
			hobby += h + "  ";
		}
	}

%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>서버에서 넘겨 받은 파라미터</h3>

<p>이름 : <%=name %></p>
<p>학번 : <%=studentId %></p>
<p>성별 : <%=gender %></p>
<p>좋아하는 과목 : <%=subject %></p>
<p>출신도 : <%=city %></p>
<p>취미 : <%=hobby %></p>

</body>
</html>

 

ex13 - hidden 객체 : 화면에 출력되지 않지만 서버에 전송해야 하는 경우 (하지만 많으면 프로그래밍이 어려워짐)

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script type="text/javascript">
function send(operator) {
	var f = document.myForm;
	
	if(! /^\d+/.test(f.num1.value) ) {
		f.num1.focus();
		return;
	}
	
	if(! /^\d+/.test(f.num2.value) ) {
		f.num2.focus();
		return;
	}
	
	f.operator.value = operator;
	
	f.submit();
}
</script>

</head>
<body>

<h3>hidden 객체 : 화면에 출력되지 않지만 서버에 전송해야 하는 경우에 사용 </h3>

<form name="myForm" action="ex13_ok.jsp" method="post">
<p>
	<input type="text" name="num1" placeholder="첫번째 수">
	<input type="text" name="num2" placeholder="두번째 수">
	<input type="hidden" name="operator">
</p>
<p>
	<button type="button" onclick="send('+')">더하기</button>
	<button type="button" onclick="send('-')">빼기</button>
	<button type="button" onclick="send('*')">곱하기</button>
	<button type="button" onclick="send('/')">나누기</button>
</p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	int num1 = Integer.parseInt( request.getParameter("num1") );
	int num2 = Integer.parseInt( request.getParameter("num2") );
	
	String op = request.getParameter("operator");
	String s = "";
	
	// if(op.equals("+")) String.format("%d + %d = %d", num1, num2, num1+num2);
	
	switch(op) {
	case "+" : s = String.format("%d + %d = %d", num1, num2, num1+num2); break;
	case "-" : s = String.format("%d - %d = %d", num1, num2, num1-num2); break;
	case "*" : s = String.format("%d * %d = %d", num1, num2, num1*num2); break;
	case "/" : s = String.format("%d / %d = %d", num1, num2, num1/num2); break;
	}
	
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>결과</h3>
<p> <%= s %> </p>

</body>
</html>

 

ex14 - 폼태그 안의 disabled 속성의 객체는 서버로 전송되지 않는다.

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>폼예제 : disabled 속성의 객체는 서버로 전송되지 않는다.</h3>

<form action="ex14_ok.jsp" method="post">
	<p>번호 : <input type="text" name="num" value="1111" readonly="readonly"></p>
	<p>이름 : <input type="text" name="name"></p>
	<p>나이 : <input type="text" name="age" value="20" disabled="disabled"></p>
	<p>
		<button type="submit">보내기</button>
	</p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	String num = request.getParameter("num");
	String name = request.getParameter("name");
	String age = request.getParameter("age");
	
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<p>번호 : <%=num %></p>
<p>이름 : <%=name %></p>
<p>나이 : <%=age %></p>
</body>
</html>

나이는 null로 나옴.

 

 

ex17 - redirect : 웹 컨테이너는 웹 브라우저에게 주어진 페이지로 이동하라고 명령을 내림. request, response는 초기화된다.

★ 로그인 후, 로그아웃 후, DB의 INSERT, UPDATE, DELETE 작업 후에 실시

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3> response 객체 : 요청에 대한 응답 정보를 담고 있는 객체</h3>

<%
	response.sendRedirect("ex17_ok.jsp");
%>

<%--
	- redirect
	  : 웹 컨테이너는 웹 브라우저에게 주어진 페이지로 이동하라고 명령을 내림(302 응답 코드를 보냄)
	    -> 웹브라우저는 주어진 주소의 새로운페이지 접속
	  : request, response는 초기화 됨
	  : 로그인 후, 로그아웃 후, DB의 INSERT, UPDATE, DELETE 작업 후 
 --%>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>정보</h3>
<p>
  안녕하세요. redirect된 페이지입니다.
</p>

</body>
</html>

 

ch05

 

ex01 - 계산 : 자바클래스를 이용해서, 스크립릿을 이용해 자바 클래스 생성해서, 스크립릿만을 이용해서

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<form action="ex01_ok.jsp" method="post">
<p>
	<input type="text" name="num1" required="required" placeholder="수" pattern="\d+">
	<select name="operator">
		<option value="+">더하기</option>
		<option value="-">뻬기</option>
		<option value="*">곱하기</option>
		<option value="/">나누기</option>
	</select>
	<input type="text" name="num2" required="required" placeholder="수" pattern="\d+">
<button type="submit">확인</button>
</form>

</body>
</html>

 

JSP 액션 태그(자바 빈즈)

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");
%>
<%-- JSP 액션 태그 --%>
<%--
	Calculator vo = new Calculator(); 와 유사
 --%>
<jsp:useBean id="vo" class="ch05.Calculator"/>

<%-- 
	클래스 안의 동일한 이름을 찾아감 
	vo.setNum1( Integer.parseInt( request.getParameter("num1")) );
	vo.setNum2( Integer.parseInt( request.getParameter("num2")) );
	vo.setOperator( request.getParameter("operator") );
	역할을 함
	
	form 태그 input 요소의 name 속성과 동일한 Calculator 클래스의 필드에 값을 전달
--%>
<jsp:setProperty name="vo" property="*"/>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>액션 태그(자바 빈즈)를 이용한 연산</h3>
<p> <%=vo.toString() %> </p>

</body>
</html>
package ch05;

public class Calculator {
	private int num1;
	private int num2;
	private String operator;

	public int getNum1() {
		return num1;
	}

	public void setNum1(int num1) {
		this.num1 = num1;
	}

	public int getNum2() {
		return num2;
	}

	public void setNum2(int num2) {
		this.num2 = num2;
	}

	public String getOperator() {
		return operator;
	}

	public void setOperator(String operator) {
		this.operator = operator;
	}

	@Override
	public String toString() {
		String s = null;
		
		if(operator == null) return s;
		
		switch(operator) {
		case "+" : s = String.format("%d + %d = %d", num1, num2, num1+num2); break;
		case "-" : s = String.format("%d - %d = %d", num1, num2, num1-num2); break;
		case "*" : s = String.format("%d * %d = %d", num1, num2, num1*num2); break;
		case "/" : s = String.format("%d / %d = %d", num1, num2, num1/num2); break;
		}
		
		return s;
	}
}

 

스크립릿을 이용해서 자바 객체 생성

<%@page import="ch05.Calculator"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	Calculator vo = new Calculator();
	vo.setNum1( Integer.parseInt( request.getParameter("num1")) );
	vo.setNum2( Integer.parseInt( request.getParameter("num2")) );
	vo.setOperator( request.getParameter("operator") );
	
	String s = vo.toString();
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>자바 객체를 이용한 연산</h3>
<p> <%= s %> </p>

</body>
</html>

 

스크립릿만을 이용해서

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	int num1 = Integer.parseInt( request.getParameter("num1") );
	int num2 = Integer.parseInt( request.getParameter("num2") );
	
	String op = request.getParameter("operator");
	String s = "";
	
	// if(op.equals("+")) String.format("%d + %d = %d", num1, num2, num1+num2);
	
	switch(op) {
	case "+" : s = String.format("%d + %d = %d", num1, num2, num1+num2); break;
	case "-" : s = String.format("%d - %d = %d", num1, num2, num1-num2); break;
	case "*" : s = String.format("%d * %d = %d", num1, num2, num1*num2); break;
	case "/" : s = String.format("%d / %d = %d", num1, num2, num1/num2); break;
	}
	
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>결과</h3>
<p> <%= s %> </p>

</body>
</html>

 

ex02 - 자바 필드의 이름이 다를 경우 자바빈즈를 이용해서 속성값 이름 변경

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<form action="ex02_ok.jsp" method="post">
 <p> 번호 : <input type="text" name="no"> </p>
 <p> 이름 : <input type="text" name="name"> </p>
 <p> 좋아하는 과목 : <input type="text" name="subject"> </p>
 <p>
 	<button type="submit">등록하기</button>
 </p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");
%>

<%-- 빈 생성 --%>
<jsp:useBean id="vo" class="ch05.User"/>

<%-- 생성된 빈에 속성 값(파라미터) 값 설정 --%>
<%-- property="*" 는 form안의 input 요소의 name과 User클래스의 필드가 동일한 경우만 설정--%>
<jsp:setProperty property="*" name="vo"/>

<%-- form input요소의 name과 User 클래스의 필드가 다른 경우 --%>
<jsp:setProperty name="vo" property="num" param="no"/>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<p> 번호 : <%= vo.getNum() %></p>
<p> 이름 : <%= vo.getName() %></p>
<p> 좋아하는 과목 : <%= vo.getSubject() %></p>

</body>
</html>

 

forward

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>forward</h3>
<%--
  - 클라이언트로부터 요청 받은 서블릿(JSP)은 서버의 다른 자원(서블릿, JSP)으로 요청 정보를 전달하여 처리
  - 포워딩은 서블릿 컨테이너에서 이루어 지므로 클라이언트는 알 수 없다.(브라우저 주소줄이 변하지 않음)
  - 요청 받은 페이지는 포워딩 페이지에 request, response 객체를 그대로 전달한다.
  - 요청 받은 페이지가 포워딩 페이지에 새로운 정보를 전달하기 위해서는 request.setAttribute()를 이용한다.
 --%>

<form action="ex03_ok.jsp" method="post">
	<p>이름 : <input type="text" name="name" required="required"></p>
	<p>나이 : <input type="text" name="age" required="required" pattern="\d+"></p>
	<p> <button type="submit">등록하기</button> </p>
</form>
 

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	int age = Integer.parseInt( request.getParameter("age") );
	String s = age >= 19? "성인" : "미성년자";

	
	// 포워딩하는 페이지에 state 전달
	request.setAttribute("state", s); // request.setAttribute(String, Object);
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>포워딩하면 이 페이지는 클라이언트 화면에 보이지 않는다.</h3>

<%-- JSP 액션 태그를 이용한 forward --%>
<jsp:forward page="ex03_result.jsp"/>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8");

	// 포워딩된 페이지는 포워딩한 페이지에서 request, response 객체가 전달되므로 클라이언트가 보낸
	// 파라미터를 받을 수 있다.
	String name = request.getParameter("name");
	int age = Integer.parseInt(request.getParameter("age"));
	
	// 포워딩한 페이지에서 설정한 속성 값 받기
	// request.getAttribute()의 리턴 타입은 Object 이므로 반드시 다운 캐스팅이 필요
	String s = (String)request.getAttribute("state");
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<p> <%=name %>님의 나이는 <%=age %>이므로 <%=s %>입니다.</p>

</body>
</html>

 

ex04 - 자바 클래스를 활용한 forward

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	String cp = request.getContextPath(); // 프로젝트명
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>서블릿 forward</h3>

<form action="<%=cp%>/ch05/demo" method="post">
	<p>이름 : <input type="text" name="name" required="required"></p>
	<p>나이 : <input type="text" name="age" required="required" pattern="\d+"></p>
	<p> <button type="submit">등록하기</button> </p>
</form>

</body>
</html>
package ch05.demo;

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("/ch05/demo")
public class DemoServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// GET 방식으로 요청한 경우
		
		// /study2/ch05/ex04.jsp 로 포워딩
		// forward 할 때 /는 Context Path를 나타낸다.
		forward(req, resp, "/ch05/ex04.jsp");
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// POST 방식으로 요청한 경우
		req.setCharacterEncoding("utf-8"); // POST방식은 필수!
		
		String name = req.getParameter("name");
		int age = Integer.parseInt( req.getParameter("age") );
		
		String state = age >= 19 ? "성인" : "미성년자";
		String msg = name + "님의 나이는 " +age +"입니다. 따라서 " + state + "입니다.";
		
		req.setAttribute("message", msg);
		
		forward(req, resp, "/ch05/ex04_ok.jsp");
	}
	
	protected void forward(HttpServletRequest req, HttpServletResponse resp, String path) throws ServletException, IOException {
		// 서블릿 포워딩 방법
		RequestDispatcher rd = req.getRequestDispatcher(path);
		rd.forward(req, resp);
	}
	
}
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>결과</h3>

<p>
	<%=request.getAttribute("message") %>
</p>


</body>
</html>

인코딩과 디코딩

- 문자를 컴퓨터에 저장하거나 통신에 사용할 목적으로 부호화하는 것을 인코딩(encoding)이라 하며, 반대로 문자를 원래대로 되돌리는 것을 디코딩(decoding)이라 한다.

- HTTP와 같은 통신 프로토콜은 ASCII 문자만을 지원하며, ASCII 문자로 표현할 수 없는 영어 이외의 언어는 전송할 수 없다. 따라서 MIME은 ASCII가 아닌 문자를 인코딩을 이용해 영어가 아닌 다른 언어를 전송할 수 있는 방식을 정의한다.

- HTML 폼은 method="post"인 경우 기본적으로 문자열을 application/x-www-form-urlencoded MIME 형식(enctype 속성을 생략한 경우)으로 인코딩하여 전송한다.

- application/x-www-form-urlencoded MIME 형식 인코딩

공백은 +, 영숫자가 아닌 문자는%HH(문자코드의 16진수 2자리)로 인코딩 된다.

 

파라미터 값의 인코딩 및 디코딩

- 파라미터 값의 인코딩

웹브라우저 : 웹 서버에 파라미터를 전송할 때 알맞은 캐릭터 셋(charset)을 이용해서 파라미터 값을 인코딩

웹 서버 : 알맞은 캐릭터 셋(charset)을 이용해 웹 브라우저가 전송한 파라미터 데이터를 디코딩

캐릭터 셋(charset)종류 : ISO-8859-1(기본), UTF-8, euc-kr 등...

- 웹 브라우저가 'UTF-8'을 이용해 인코딩 했다면 웹 서버는 ;UTF-8'을 이용해 파라미터 값을 디코딩 해야 올바른 파라미터 값을 사용할 수 있다.

- 웹 브라우저가 인코딩 할 때 사용할 캐릭터 셋과 웹 서버가 디코딩 할 때 사용한 캐릭터 셋이 다를 경우 웹 서버가 잘못된 파라미터 값을 사용한다.

 

GET 방식의 파라미터 전송

- a 태그를 이용한 파라미터 전송

<a href="URL키1=값1&키2=값2">텍스트</a>

더보기
<%@ page import="java.net.URLEncoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
function send() {
	var name = "자&바";
	var age = 20;
	
	// name을 인코딩하지 않으면 IE는 400에러가 발생하고, 크롬은 '자' 만 전달된다.
	// 자바스크립트를 이용한 인코딩
	name = encodeURIComponent(name); // 주소 형식으로 인코딩 // 매우 중요한 함수!
	
	// GET방식 파라미터(절대로 중간에 공백이 있으면 안됨) : 이름1=값&이름2&값&이름3=값
	var query = "name=" + name + "&age=" + age; // 따옴표 안에는 절대 띄어쓰기 하면 안됌!
	
	// 자바스크립트를 이용하여 GET 방식으로 파라미터 전송
	var url = "ex01_ok.jsp?"+query;
	location.href= url;
}

function sendOk() {
	var f = document.myForm;
	
	// 이름에 "홍%김" 으로 인코딩 안하고 보내면 500 에러
	var name = f.name.value;
	name = encodeURIComponent(name); // name을 인코딩한 것을 
	f.name.value = name; // 다시 form.name 에 넣어줌
	// form의 name에 인코딩된 것으로 변경
	
	f.submit(); // 일반 버튼 등에서 form의 정보를 서버로 전송
}

</script>

</head>
<body>

<h3>파라미터 전송 - GET 방식</h3>

<p>
  - 기본적으로 클라이언트가 서버에 접속하는 경우 파라미터 전송 방식은 GET 방식이다.<br>
  - Query String : GET 방식으로 전송되는 파라미터<br>
  - 주소줄에 파라미터를 실어서 보냄<br>
    <%-- 형식 : 주소?이름=값&이름=값 --%>
  - GET 방식으로 정보를 보낼 때 한글 등은 반드시 인코딩해서 보낸다.<br>
</p>
<hr>

<!-- a 태그를 이용하여 GET방식으로 파라미터 전송 -->
<p>
	<!-- ex01_ok.jsp?name=%ED%99%8D%EA%B8%B8%EB%8F%99&age=20 -->
	<!-- 한글을 인코딩하지 않고 GET방식으로 전공하면 IE에서는 400에러가 발생한다. -->
	<a href="ex01_ok.jsp?name=홍길동&age=20">확인</a> |
	
	<!-- 자바를 이용하여 한글 인코딩 -->
	<a href="ex01_ok.jsp?name=<%=URLEncoder.encode("홍길동", "utf-8")%>&age=20">확인</a>
</p>
<hr>

<!-- 자바스크립트를 이용하여 GET방식으로 파라미터 전송 -->
<p>
	<button type="button" onclick="send();">확인</button>
</p>
<hr>

<!-- form 태그를 이용한 GET 방식 전송 : form 태그를 이용한 GET 방식 전송은 거의 사용하지 않는다. -->
<!-- form 태그를 이용하여 GET 방식으로 전송할 때 method를 생략하면 GET 방식으로 전송된다. -->
<form name="myForm" action="ex01_ok.jsp">
	<p> 이름 : <input type="text" name="name"></p>
	<p> 나이 : <input type="text" name="age"></p>
	<p>
		<button type="button" onclick="sendOk();">전송</button>
		<!-- type="button"은 전송이 되지 않음 -->
	</p>
</form>

</body>
</html>
<%@page import="java.net.URLDecoder"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	// request : 클라이언트가 보낸 요청 정보를 담고 있는 내장 객체
	
	// 클라이언트가 보낸 파라미터 받기
	// GET 방식으로 넘어온 인코딩된 데이터를 디코딩하지 않으면 WAS 따라 한글이 깨질 수 있다.
	String name= request.getParameter("name");
	// 자바에서 인코딩된 정보를 디코딩
	name = URLDecoder.decode(name, "utf-8");
	
	int age = Integer.parseInt(request.getParameter("age"));
	String state = age >= 19? "성인" : "미성년자";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>GET 방식으로 전달받은 파라미터를 이용한 처리 결과</h3>

<p>
	<%=name %>님의 나이는 <%=age %>세 이므로 <%=state %>입니다.
</p>

</body>
</html>

 

- JavaScript의 location.href 속성을 이용한 파라미터 전송

lovation.href="URL?키1=값1&키2=값2";

- form태그를 이용한 전송

form 태그는 method 속성을 지정하지 않으면 기본으로 GET 방식으로 파라미터를 전송한다.

- GET 방식은 개발자가 직접 인코딩과 디코딩 작업을 해야한다.

 

 

POST 방식의 파라미터 전송

- 일반적으로 POST 방식으로 파라미터를 전송하기 위해서는 form 태그를 이용하여 전송한다.

- form 태그의 method 속성을 method="post"로 지정하면 POST 방식으로 파라미터를 전송한다.

- POST 방식에 의해 전달받은 파라미터 값을 디코딩 할 때 사용할 캐릭터 셋을 지정

request.setCharacterEncoding("utf-8"); 

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>파라미터 전송 - POST방식</h3>
<p>
  - POST 방식으로 파라미터를 전송하면 body에 정보를 실어서 보냄<br>
  - POST 방식은 용량에 제한이 없음<br>
  - POST 방식은 form 태그의 method="post"를 통해 전송됨<br>
  - form 태그의 method="post"에서 기본 enctype 설정은
  	enctype="application/x-www-form-urlencoded" 이다.<br>
  	enctype은 문자의 인코딩 방식을 지정하며, 
  	x-www-form-urlencoded는 주소 형식으로 데이터를 인코딩해서 정보를 보낸다.
</p>
<hr>

<form action="ex02_ok.jsp" method="post" >
	<p> 이름 : <input type="text" name="name"></p>
	<p> 나이 : <input type="text" name="age"></p>
	<p>
		<button type="submit">보내기</button>
	</p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	// POST 방식으로 넘어온 파라미터의 인코딩 설정
	// POST 방식에서는 파라미터를 받기 전 반드시 아래처럼 문자 인코딩 파라미터를 설정해야 하며
	// 		설정하지 않는 경우에는 한글이 깨진다.
	request.setCharacterEncoding("utf-8"); // 위치가 바뀌면 안됨!
	
	String name= request.getParameter("name");
	int age = Integer.parseInt(request.getParameter("age"));
	String state = age >= 19? "성인" : "미성년자";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>POST 방식으로 전달받은 파라미터를 이용한 처리 결과</h3>
<p>
	<%=name %>님의 나이는 <%=age %>세 이므로 <%=state %>입니다.
</p>


</body>
</html>

 

form 태그 안에 있는 submit 버튼의 종류

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>form 데이터 서버로 전송 - submit 버튼</h3>
<p>
  - form 태그 안에 있는 submit 버튼은 서버로 전송할 수 있는 기능이 있다.<br>
  <!-- [submit 버튼 종류] -->
  <!--  1. <button>확인</button> -->
  <!--  2. <button type="submit">확인</button> -->
  <!--  3. <input type="submit" value="확인"> -->
  <!--  4. <input type="image" src="이미지"> -->
  
  <!-- [input 태그의 required 속성] -->
  <!--  input 태그가 form 안에 있어야 하고 submit 버튼을 누를 때만 반응함 -->
</p>
<hr>

<form action="ex03_ok.jsp" method="post">
	<p>이름 : <input type="text" name="name" required="required"></p>
	<p>나이 : <input type="text" name="age" required="required"></p>
	<p>
		<button>확인</button> |
		<button type="submit">확인</button> |
		<input type="submit" value="확인"> |
		<input type="image" src="btn_submit.gif" style="vertical-align: bottom;"> | 
		<!-- inline 태그 안에서만 vertical-align 사용가능 -->
		<button type="button">일반버튼</button>
	</p>
	
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8"); // 위치가 바뀌면 안됨!
	
	String name= request.getParameter("name");
	int age = Integer.parseInt(request.getParameter("age"));
	String state = age >= 19? "성인" : "미성년자";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>처리 결과</h3>
<p>
	<%=name %>님의 나이는 <%=age %>세 이므로 <%=state %>입니다.
</p>


</body>
</html>

form 태그안의 submit 버튼을 이용해 서버로 데이터를 보내기 전에 form 태그의 onsubmit 속성을 이용해 유효성 검사하기

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
function check() {
	var f = document.myForm;

	if(! /^[가-힣]{2,5}$/.test(f.name.value) ) {
		alert("이름을 입력 하세요");
		f.name.focus();
		return false;
	}
	
	if(! /^(\d){1,3}$/.test(f.age.value) ) {
		alert("나이를 입력 하세요");
		f.age.focus();
		return false;
	}
	
	// 주의!!!
	// submit 버튼에서 f.submit(); 처럼 form의 submit() 함수를 호출하면 서버에 두 번 전송된다.
	
	return true;


}

</script>

</head>
<body>

<h3>form 데이터 서버로 전송 - submit 버튼 : 유효성 검사</h3>
<p>
  - form 태그 안의 submit 버튼을 클릭하면 submit 이벤트가 발생한다. <br>
  - submit 버튼을 사용하는 경우 유효성 검사는 submit 이벤트 핸들러에서 한다.<br>
  - submit 이벤트 핸들러에 false를 반환하면 서버로 전송되지 않는다.
</p>
<hr>

- 이름 한글 2~5자
- 나이는 한자 이상의 숫자

<form name="myForm" action="ex04_ok.jsp" method="post" onsubmit="return check();">
	<p>이름 : <input type="text" name="name"></p>
	<p>나이 : <input type="text" name="age"></p>
	<p>
		<button type="submit">확인</button>
		<button type="reset">다시 입력</button>
		<!-- reset 버튼은 form 태그 안에서만 동작한다. -->
	</p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8"); // 위치가 바뀌면 안됨!
	
	String name= request.getParameter("name");
	int age = Integer.parseInt(request.getParameter("age"));
	String state = age >= 19? "성인" : "미성년자";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>처리 결과</h3>
<p>
	<%=name %>님의 나이는 <%=age %>세 이므로 <%=state %>입니다.
</p>


</body>
</html>

 

form 태그안에 일반 버튼을 이용해 서버로 데이터를 보내기 전에 onclick으로 유효성 검사

더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
function sendOk() {
	var f = document.myForm;

	if(! /^[가-힣]{2,5}$/.test(f.name.value) ) {
		alert("이름을 입력 하세요");
		f.name.focus();
		return;
	}
	
	if(! /^(\d){1,3}$/.test(f.age.value) ) {
		alert("나이를 입력 하세요");
		f.age.focus();
		return;
	}

	f.action = "ex05_ok.jsp"; //서버 주소
	f.submit(); // 일반 버튼 등에서 form의 내용을 서버로 전송

}

</script>

</head>
<body>

<h3>form 데이터 서버로 전송 - 일반 버튼 : 유효성 검사</h3>
<p>
  - form 태그 안의 내용을 일반 버튼을 이용하여 서버로 전송하기 위해서는 
    form 객체의 submit() 함수를 호출한다. <br>
  - submit() 함수를 이용하여 서버로 전송하는 경우 submit 이벤트는 발생되지 않는다.<br>
</p>
<hr>

<form name="myForm" method="post">
	<p>이름 : <input type="text" name="name"></p>
	<p>나이 : <input type="text" name="age"></p>
	<p>
		<button type="button" onclick="sendOk();">확인</button>
		<button type="reset">다시 입력</button>
		<!-- reset 버튼은 form 태그 안에서만 동작한다. -->
	</p>
</form>

</body>
</html>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
	request.setCharacterEncoding("utf-8"); // 위치가 바뀌면 안됨!
	
	String name= request.getParameter("name");
	int age = Integer.parseInt(request.getParameter("age"));
	String state = age >= 19? "성인" : "미성년자";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
</head>
<body>

<h3>처리 결과</h3>
<p>
	<%=name %>님의 나이는 <%=age %>세 이므로 <%=state %>입니다.
</p>


</body>
</html>

+ Recent posts