본문 바로가기

STUDY/국비과정

[JAVA 웹 개발 공부] 국비지원 57일차 - JSP 연습, request, GET 방식, POST 방식, Stateless, Redirect

JSP 연습

 

1. 퀴즈 페이지 만들기

 

*quiz.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>퀴즈 페이지</title>
</head>
<body>
<p>Java Spec중 동적 페이지 구성은 어떤 걸로 가능?</p>
<form action="quizanswer.jsp">
	<label><input name="answer" type="radio" value="1" checked/>html</label>
	<label><input name="answer" type="radio" value="2"/>jsp</label>
	<label><input name="answer" type="radio" value="3"/>radio</label>
	<label><input name="answer" type="radio" value="4"/>quiz</label>
	<input type="submit"/>
</form>
</body>
</html>

*quizanswer.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 answer = request.getParameter("answer");
	if (answer == null) {
		out.println("<p>입력값이 없습니다.</p>");
	} else if (answer.equals("2")) {
		out.println("<p>정답입니다.</p>");
	} else {
		out.println("<p>오답입니다.</p>");
	}
%>
</body>
</html>

 

 

2. 취미생활 개수세기

*hobby.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>취미 선택하기</title>
</head>
<body>
<p>취미 선택</p>
<form action="hobbycount.jsp">
	<label><input name="hobby" type="checkbox" value="java"/>자바</label>
	<label><input name="hobby" type="checkbox" value="lol"/>리그 오브 레전드</label>
	<label><input name="hobby" type="checkbox" value="hots"/>히어로즈 오브 스톰</label>
	<label><input name="hobby" type="checkbox" value="dota"/>도타</label>
	<input type="submit"/>
</form>
</body>
</html>

*hobbycount.jsp

<%@page import="java.util.Arrays"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>취미생활 개수세기</title>
</head>
<body>
<%
	Map<String, String[]> map = request.getParameterMap();
	String[] values = map.get("hobby");
	if (values == null) {
		out.println("없음");
	} else {
		out.println(values.length);
		out.println(" 개 선택");
		out.println(Arrays.toString(values));
	}
%>
</body>
</html>

 

 

3. 랜덤퀴즈 만들기

*randomquiz.jsp

<%@page import="java.util.Random"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>랜덤한 퀴즈</title>
</head>
<body>
<%
	List<String> quiz = new ArrayList<>();
	quiz.add("더글로리 주요인물(송혜교)의 배역명?");
	quiz.add("더글로리 스트리밍 서비스?");
	quiz.add("고등학교 시절 문동은에게 학교폭력을 가해한 주동자?");
	
	Random r = new Random();
	int number = r.nextInt(3);
	String text = quiz.get(number);
%>
<p><%= text %></p>
<form action="randomanswer.jsp">
	<input type="text" name="answer" placeholder="정답을 입력하세요.">
	<input type="hidden" name="number" value="<%= number %>" readonly />
	<input type="submit"/>
</form>
</body>
</html>

*randomanswer.jsp

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ 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>
<%
	String answer = request.getParameter("answer");
	String number = request.getParameter("number");
	
	Map<String, String> map = new HashMap<>();
	map.put("0", "문동은");
	map.put("1", "넷플릭스");
	map.put("2", "박연진");
	
	String ox = map.get(number);
	if (answer == null) {
		out.println("입력값 없음");
	} else if (answer.equals(ox)) {
		out.println("<p>정답</p>");
	} else {
		out.println("<p>오답</p>");
	}
%>
<p><%= answer %></p>
<p><%= number %></p>
</body>
</html>

 

 

4. 로그인 페이지 만들기

id : admin / password : root
로그인 성공 → 메시지 출력
로그인 실패 → 실패 메시지와 로그인 페이지로 이동할 수 있는 링크 제공

*login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 정보 입력</title>
</head>
<body>
<form action="loginprogress.jsp" method="post">
	<label>아이디 <input type="text" name="id" placeholder="아이디 입력"/></label>
	<label>비밀번호 <input type="password" name="password" placeholder="비밀번호 입력"/></label>
	<input type="submit"/>
</form>
</body>
</html>

*loginprogress.jsp

<%@page import="java.io.BufferedReader"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 처리 페이지</title>
</head>
<body>
<%
	// id 파라미터값 : admin
	// password 파라미터값 : root
	// 로그인 성공 (메시지 출력)

	// 이외 실패
	// 실패 메시지와 로그인 페이지로 이동할 수 있는 링크 제공
	//out.println(request.getMethod());
	//out.println(request.getQueryString()); // get (url에 표현된 query param string을 반환)
	try (BufferedReader br = request.getReader()) {
		String line = br.readLine();
		//out.println("<p>바디에서 읽은 내용: " + line + "</p>");
	} 
	String id = request.getParameter("id");
	String password = request.getParameter("password");
	String adminId = "admin";
	String adminPw = "root";
	
	if (id == null || password == null) {
		out.println("입력값 없음");
		out.println("<a href=login.html>로그인 페이지로 이동</a>");
	} else {
		if (id.equals(adminId) && password.equals(adminPw)) {
			out.println("로그인 성공");
		} else {
			out.println("로그인 실패");
%>
			<a href="login.html">로그인 페이지로 이동</a>
<%
		}
	}
%>
</body>
</html>

 

 

5. 간단한 웹 계산기

*calcform.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="calcresult.jsp">
	<input type="number" name="first"/>
	<select name="operator">
		<option value="plus">+</option>
		<option value="minus">-</option>
		<option value="mul">*</option>
		<option value="div">/</option>
	</select>
	<input type="number" name="second"/>
	<input type="submit"/>
</form>
</body>
</html>

*calcresult.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 first = request.getParameter("first");
	String operator = request.getParameter("operator");
	String second = request.getParameter("second");
	
	Integer num1 = Integer.valueOf(first);
	Integer num2 = Integer.valueOf(second);
	
	if (operator.equals("div") && num2 == 0) {
		response.sendRedirect("./calcform.jsp");
	} else {
		int result = 0;
		if (operator.equals("plus")) {
			result = num1 + num2;
		} else if (operator.equals("minus")) {
			result = num1 - num2;
		} else if (operator.equals("mul")) {
			result = num1 * num2;
		} else if (operator.equals("div")) {
			result = num1 / num2;
		}
%>
	<p>연산 결과 <%= result %></p>
	</body>
	</html>
<%
	}
%>

 

 

request

 

1. request 기본 객체

request 기본 객체는 JSP 페이지에서 가장 많이 사용되는 기본 객체로서 웹 브라우저의 요청과 관련이 있다.

웹 브라우저에 웹 사이트의 주소를 입력하면, 웹 브라우저는 해당 웹 서버에 연결한 후 요청 정보를 전송하는데, 이 요청 정보를 제공하는 것이 바로 request 기본 객체이다.

 

2. request 기본 객체가 제공하는 기능

*클라이언트(웹 브라우저)와 관련된 정보 읽기 기능

*서버와 관련된 정보 읽기 기능

*클라이언트가 전송한 요청 파라미터 읽기 기능

*클라이언트가 전송한 쿠키 읽기 기능

*속성 처리 기능

 

3. request 기본 객체의 클라이언트 및 서버 정보 관련 메소드

메소드 리턴 타입 설명
getRemoteAddr() String 웹 서버에 연결한 클라이언트의 IP 주소를 구한다. 게시판이나 방명록 등에서 글 작성자의 IP 주소가 자동으로 입력되기도 하는데, 이때 입력되는 IP 주소가 바로 이 메소드를 사용하여 구한 것이다.
getContentLength() long 클라이언트가 전송한 요청 정보의 길이를 구한다. 전송된 데이터의 길이를 알 수 없는 경우 -1을 리턴한다.
getCharacterEncoding() String 클라이언트가 요청 정보를 전송할 때 사용한 캐릭터의 인코딩을 구한다.
getContentType() String 클라이언트가 요청 정보를 전송할 떄 사용한 컨텐츠의 타입을 구한다.
getProtocol() String 클라이언트가 요청한 프로토콜을 구한다.
getMethod() String 웹 브라우저가 정보를 전송할 때 사용한 방식을 구한다. (GET / POST)
getRequestURI() String 웹 브라우저가 요청한 URL에서 경로를 구한다.
getContextPath() String JSP 페이지가 속한 웹 어플리케이션의 컨텍스트 경로를 구한다.
getServerName() String 연결할 때 사용한 서버 이름을 구한다.
getServerPort() int 서버가 실행중인 포트 번호를 구한다.

 

4. request 기본 객체의 파라미터 읽기 메소드

메소드 리턴 타입 설명
getParameter(String name) String 이름이 name인 파라미터의 값을 구한다. 존재하지 않을 경우 null을 리턴한다.
getParameterValues(String name) String[] 이름이 name인 모든 파라미터의 값을 배열로 구한다. 존재하지 않을 경우 null을 리턴한다.
getParameterNames() java.util.Enumeration 웹 브라우저가 전송한 파라미터의 이름 목록을 구한다.
getParameterMap() java.util.Map 웹 브라우저가 전송한 파라미터의 맵을 구한다.
맵은 <파라미터 이름, 값> 쌍으로 구성된다.

 

 

GET 방식 vs POST 방식 

 

웹 브라우저는 GET 방식과 POST 방식의 두 가지 방식 중 한 가지를 이용해서 파라미터를 전송한다. 

 

GET 방식은 링크를 클릭하거나, 주소를 입력할 때 기본적으로 사용하는 방식이다.

http 프로토콜의 정의를 보면 사용자가 달라는 요청을 GET 방식으로 하자고 처음 약속이 되어있다.
물론 검색, 링크 클릭 등 대부분의 사용자의 요청은무엇인가를 달라는 요청이 대부분이기도 하다. 

 

POST 방식의 경우 내부 로직에 의해 정보의 처리 또는 추가가 필요할 때 사용하도록 약속이 되어있다. 
처음 인터넷은 GET 방식 밖에 없었고, 발전을 거치면서 메소드 방식이 추가된다면 더 수월하게 요청을 처리할 수 있겠다고 생각하여 POST 방식 등이 추가된 것이라고 생각한다면 더 쉽게 이해가 될 것이다. 

즉 사용자의 구체적인 요청을 처리할 수 있게 개발자를 위해서 메소드 방식을 여러가지로 정의한 것이다. 개발자가 메소드 방식을 살펴보고 요청에 대한 처리를 쉽게 할 수 있도록 한 것이다.

 

POST 방식으로 파라미터 데이터를 전송하려면 아래와 같이 form 태그의 method 속성값을 "post"로 지정한다.

<form action="loginprogress.jsp" method="post">

 

GET 방식과 POST 방식의 차이점은 전송 방식에 있다. GET 방식은 요청 URL에 파라미터를 붙여서 전송한다. 

GET 방식 → 주소에 적힘
POST 방식 → 주소에 안적힘

 

GET 방식은 URL의 경로 뒤에 물음표('?')와 함께 파라미터를 붙여 전송하는데, 이를 쿼리 문자열(query string)이라고 한다.

쿼리 문자열의 형식은 다음과 같다.

이름1=값1&이름2=값2&...&이름n=값n

 

GET 방식은 웹 브라우저, 웹 서버 또는 웹 컨테이너에 따라 전송할 수 있는 파라미터의 길이에 제한이 있을 수 있다.

반면에 POST 방식은 데이터 영역을 이용해서 데이터를 전송하기 때문에 웹 브라우저나 웹 서버 등에 상관없이 전송할 수 있는 파라미터의 길이에 제한이 없다.

 

 

*GET 방식 vs POST 방식

out.println(request.getMethod());
out.println(request.getQueryString()); // get (url에 표현된 query param string을 반환)
try (BufferedReader br = request.getReader()) {
	String line = br.readLine();
	out.println("<p>바디에서 읽은 내용: " + line + "</p>");
}

 

 

HTTP 무상태 프로토콜(Stateless)

 

무상태 프로토콜은 서버가 클라이언트의 상태를 보존하지 않는다는 것이다. HTTP는 무상태 프로토콜을 지향하는 것이 좋다. 

장점 : 서버 확장성 높음 (스케일 아웃)
단점 : 클라이언트가 추가 데이터 전송

상태유지는 특정 클라이언트를 특정 서버가 전담하는 식으로 대응된다. 예를 들어 요청을 처리하다가 서버 오류가 나면 처음부터 다시 해야한다. 그리고 동적으로 서버를 확장하기도 어렵다.

무상태는 그 때마다 놀고 있는 서버를 호출해도 아무 문제가 없다. 왜냐하면 클라이언트가 서버를 호출할 때, 현재의 상태를 서버에게 다 넘겨주기 때문이다. 이 경우 요청을 처리하던 서버에 문제가 발생해도, 클라이언트가 다른 서버를 호출해서 처리가 가능하다. 

 

하지만 서비스를 운영하려면 서버가 클라이언트를 기억해야 할 경우가 많이 있는데,  이 때 상태를 기록하는 방법은 아래와 같다. 

첫번째 방법은 클라이언트가 매요청마다 과거의 정보를 같이 담아서 보낸다.

두번째 방법은 클라이언트가 자기가 누구인지(해당사용자에 대한 식별자 역할을 하는 것)를 매요청마다 보내주면 서버는 과거의 정보를 기억하고 있어도 된다.

ex) 네이버에 로그인하면 로그인이되면 로그인이 되었다라는 정보를 클라이언트가 매번 보내게끔 만든다.

 

 

리다이렉트(Redirect)

 

Re(다시) + direct(요청하다/지시하다)이며, 구체적으로는 웹 브라우저가 웹 서버에 어떤 URL을 요청했을 때, 서버가 리다이렉트를 지시하는 특정 HTTP 응답을 통해 웹 브라우저로 하여금 지정된 다른 URL로 재요청하라고 지시하는 것을 말한다.

해당주소로 다시 요청 → 브라우저는 응답을 받고 해당 주소에 요청 → 서버는 주소 리턴 

페이지 이동이 일어난 것처럼 흐름이 이어진다.

 

리다이렉트는 해당주소를 다시 요청하라는 명령이며, 웹 서버가 웹 브라우저에게 다른 페이지로 이동하라고 응답하는 기능이다.

리다이렉트는 아래와 같이 작성한다.

response.sendRedirect("/hello/login.html");

 

 

키워드

 

query parameter string

http request post method
http request body

http redirect response

input[type="hidden"]
input[type="radio"]
input[type="checkbox"]
select option

url의 길이제한은 존재할까?