프로그래밍/JSP

JSP - 전송 방식의 차이 (GET / POST)

Heidong 2021. 10. 11. 21:40
반응형
<%@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);
	f.name.value = name; // form의 name에 인코딩된것으로 변경
	
	f.submit(); // 일반 버튼등에서 form의 정보를 서버로 전송
}
</script>
</head>

<body>

<h3>파라미터 인코딩 - GET 방식</h3>

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

<!-- a 태그를 이용하여 GET 방식으로 파라미터 전송 -->
<p>
	<!-- 한글을 인코딩하지 않고 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" method="get">
	<p> 이름 : <input type="text" name="name"></p>
	<p> 나이 : <input type="text" name="age"></p>
	<p>
		<button type="button" onclick="sendOk();">전송</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>

하나의 jsp 파일은 결과창을 보여주기 위해 만들었다.

GET 방식으로 넘어온 데이터를 받기위해서 request를 사용

 

폼 태그 안에서 전송 방식을 따로 설정 하지 않으면 GET 방식이 기본 값임.

항상 데이터 주고 받을때는 인코딩과 디코딩을 해야함

그리고 인코딩은 되도록 URIComponent()를 사용하는게 좋다.

 

<%@ 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 import="java.net.URLDecoder"%>
<%@ 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>

POST 방식의 전송 방법이다.

POST로 보내기 위해서 항상 폼 태그에 method 옵션을 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>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;"> |
		<button type="button">일반버튼</button>
	</p>
</form>

</body>
</html>
<%@page import="java.net.URLDecoder"%>
<%@ 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 타입의 버튼 태그

image 타입의 input 태그

버튼 태그의 타입이 일반 button 이면 서버로 보내는 기능은 없다 이 경우 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 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>

<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 import="java.net.URLDecoder"%>
<%@ 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>

submit 버튼을 다룰때 주의 할 점은

폼 태그에서 onsubmit 옵션으로 이미 이 폼에서 서브밋 버튼에 대해 어떤 함수를 실행 시키게 지정 해 놨는데

함수 쪽에서 함수가 끝날때 .submit() 메소드를 작성해두면 데이터가 2번 전송이 된다.

주의해야 함.

 

<%@ 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 이벤트(onsumbit)는 발생되지 않는다.
</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>
	</p>
</form>

</body>
</html>
<%@page import="java.net.URLDecoder"%>
<%@ 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 태그 안에 action이나 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=">
<script type="text/javascript">
function searchList() {
	var f = document.searchForm;
	
	if(! f.keyword.value) {
		alert("검색 값을 입력 하세요");
		f.keyword.focus();
		return;
	}
	
	f.submit();	
}
</script>
</head>
<body>

<h3>검색</h3>
<!-- [form 태그안에 input type="text"가 하나만 존재(textarea 도 없고)하는 경우]  -->
<!--   : input type="text"에서 엔터를 누르면 서버로 전송된다. -->
<!--   : 서버로 전송하지 못하게 하는 방법 -->
<!--     input type="text"를 하나 더 만들고 style="display: none;"로 설정한다. -->

<!-- [form 태그안에 input type="text"가 하나만 존재하는 경우]  -->
<!--   일반 버튼이 아닌 submit 버튼으로 처리하고 onsubmit에서 유효성 검사를 하면
       input type="text"에서 엔터를 눌러도 유효성 검사가 된다.
 -->

<form name="searchForm" action="ex06_ok.jsp" method="post">
<p>
	<select name="condition">
		<option value="all">제목+내용</option>
		<option value="name">이름</option>
		<option value="regDate">등록일</option>
	</select>
	<input type="text" name="keyword" placeholder="검색값 입력">
	<input type="text" style="display: none;">
	<button type="button" onclick="searchList()">검색</button>
</p>
</form>

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

	String condition = request.getParameter("condition");
	String keyword = request.getParameter("keyword");
%>
<!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>검색 컬럼 : <%= condition %></p>
<p>검색 값 : <%= keyword %></p>

</body>
</html>

form 태그 안에서 만약 text 타입의 input 박스가 하나 밖에 없다면 이 text창을 활성화하고 엔터를 눌러버리면 바로 서버로 전송이 되어 버린다.

이 경우 유효성 검사를 전혀 안하고 그냥 데이터를 쏘기 때문에 매우 좋지 않다.

 

이 현상을 막기 위한 방법이 2가지가 있다.

 

- 2개이상의 text박스가 존재하면 엔터를 눌러도 데이터 전송이 안된다. 그러니까 display를 none으로 안보이게해서 더미 text 박스를 만드는 것

 

- 아니면 일반 버튼이 아니라 submit 버튼으로 타입을 주고 onclick 옵션을 통해서 자바스크립트 함수를 불러와서

함수에서 유효성 검사를 하게 만들면 된다.

반응형