본문 바로가기

Servlet&JSP

Step04_Final (fetch)

 

클라이언트가 웹브라우저에서 서버에 요청을 하는 방법

1. 링크를 누른다 (GET 방식 요청)

2. 폼을 제출(전송) (GET or POST)
3 javascript 로 페이지 전환없이 ajax 요청을 할수 있다.

 

참고할만한 기존 promise 및 fetch 학습

2022.07.19 - [javascript] - Step08_promise(setTimeout, promise) ecma6

2022.07.19 - [javascript] - Step09_fetch(동기, 비동기, json, fetch) ecma6

 

Ajax, Axios, fetch 참고자료

https://velog.io/@kysung95/%EA%B0%9C%EB%B0%9C%EC%83%81%EC%8B%9D-Ajax%EC%99%80-Axios-%EA%B7%B8%EB%A6%AC%EA%B3%A0-fetch

 

 

 

test01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/test_fetch/test01.jsp</title>
</head>
<body>
	<button id="requestBtn">요청하기</button>
	<button id="requestBtn2">요청하기2</button>
	<div id="one">
	
	</div>
	<script>
		document.querySelector("#requestBtn").addEventListener("click", ()=>{
			fetch("get_data.jsp?num=1")
			.then((res)=>{
				return res.json();
			})
			.then((data)=>{
				console.log(data);
				//서버에서 응답한 데이터를 이용해서 html 마크업을 구성한후 
				let info=`
					<p>번호:\${data.num}</p>
					<p>이름:\${data.name}</p>
					<p>남자여부:\${data.isMan}</p>
				`;
				//div 에 html 로 해석해 달라고 문자열을 넣어준다.
				document.querySelector("#one").innerHTML=info;
			});
		});
		
		document.querySelector("#requestBtn2").addEventListener("click", ()=>{
			fetch("get_data2.jsp?num=1")
			.then((res)=>{
				return res.text();
			})
			.then((data)=>{
				//data 는 문자열이다. 
				console.log(data);
				document.querySelector("#one").innerHTML=data;
			});
		});
	</script>
</body>
</html>

fetch를 활용하여 주소창이 바뀌지 않아도 정보를 받아올 수 있다.

 

 

get_data

<%@page import="org.json.JSONWriter"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//요청 파라미터 추출
	int num=Integer.parseInt(request.getParameter("num"));
	//num 에 해당하는 회원 정보를 DB 에서 읽어온다.
	
	Map<String, Object> map=new HashMap<>();
	map.put("num", 1);
	map.put("name", "김구라");
	map.put("isMan", true);
	
	//json 문자열 응답하기
%>
<%=JSONWriter.valueToString(map) %>

 

get_data2

<%@page import="org.json.JSONWriter"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//요청 파라미터 추출
	int num=Integer.parseInt(request.getParameter("num"));
	//num 에 해당하는 회원 정보를 DB 에서 읽어온다.
	
	Map<String, Object> map=new HashMap<>();
	map.put("num", 1);
	map.put("name", "김구라");
	map.put("isMan", true);
	
	//html 문자열 응답하기
%>
<p>번호:<%=(int)map.get("num")%></p>
<p>이름:<%=(String)map.get("name")%></p>
<p>남자여부:<%=(boolean)map.get("isMan")%></p>

 

test02.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/test_fetch/test02.jsp</title>
</head>
<body>
	<h1>폼 테스트</h1>
	<form action="insert.jsp" method="post" id="myForm">
		<input type="text" name="name" placeholder="이름..."/>
		<input type="text" name="addr" placeholder="주소..."/>
		<button type="submit">추가</button>
	</form>
	
	<h1>폼 테스트2</h1>
	<form action="insert.jsp" method="get" id="myForm2">
		<input type="text" name="name" placeholder="이름..."/>
		<input type="text" name="addr" placeholder="주소..."/>
		<button type="submit">추가</button>
	</form>
	
	<script>
		document.querySelector("#myForm").addEventListener("submit", (e)=>{
			//폼 제출 막기(페이지 전환 막기)
			e.preventDefault();
			
			//폼에 입력한 내용을 전송할 query 문자열로 만들기
			const form=document.querySelector("#myForm"); //폼의 참조값
			const qs=new URLSearchParams(new FormData(form)).toString(); //query string
			/*
				qs는 아래와 같은 형식의 문자열이다.
				name=김구라&addr=노량진
			*/
			
			//페이지 전환 없이 post 방식으로 insert.jsp 페이지로 전송하기 
			fetch("insert.jsp", {
				method:"POST",
				headers:{"Content-Type":"application/x-www-form-urlencoded; charset=utf-8"},
				body:qs
			})
			.then((res)=>{
				return res.json();
			})
			.then((data)=>{
				console.log(data);
			});
			
		});
		
		document.querySelector("#myForm2").addEventListener("submit", (e)=>{
			//폼 제출 막기(페이지 전환 막기)
			e.preventDefault();
			
			//폼에 입력한 내용을 전송할 query 문자열로 만들기
			const form=document.querySelector("#myForm2"); //폼의 참조값
			const qs=new URLSearchParams(new FormData(form)).toString(); //query string
			
			//페이지 전환 없이 get 방식으로 insert.jsp 페이지로 전송하기 
			fetch("insert.jsp?"+qs)
			.then((res)=>{
				return res.json();
			})
			.then((data)=>{
				console.log(data);
			});
			
		});
	</script>
</body>
</html>

 

 

insert.jsp

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	request.setCharacterEncoding("utf-8");
	//요청 파라미터 추출
	String name=request.getParameter("name");
	String addr=request.getParameter("addr");
	//DB 에 저장
	
	//응답
%>    
{"isSuccess":true}

 

test03.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/test_fetch/test03.jsp</title>
</head>
<body>
	<h1>gura_util.js 를 활용해서 폼전송</h1>
	<form action="insert.jsp" method="post" id="myForm">
		<input type="text" name="name" placeholder="이름..."/>
		<input type="text" name="addr" placeholder="주소..."/>
		<button type="submit">추가</button>
	</form>
	<br />
	<button id="sendBtn">전송하기</button>
	<br />
	<input type="text" name="name" placeholder="이름..." id="inputName"/>
	<button id="sendBtn2">전송</button>
	
	<!-- 외부 javascript 로딩 -->
	<script src="js/gura_util.js"></script>
	<script>
	
		document.querySelector("#sendBtn2").addEventListener("click", ()=>{
			//input 요소의 참조값
			const input=document.querySelector("#inputName");
			ajaxInputPromise("insert.jsp", input)
			.then(res => res.json())
			.then((data)=>{
				console.log(data);
			});
		});
	
		document.querySelector("#myForm").addEventListener("submit", (e)=>{
			//폼 전송 막기 
			e.preventDefault();
			//ajax 전송할 폼의 참조값
			const form=document.querySelector("#myForm");
			
			ajaxFormPromise(form)
			.then((res)=>{
				return res.json();
			})
			.then((data)=>{
				console.log(data);
			});
			
		});
		
		document.querySelector("#sendBtn").addEventListener("click", ()=>{
			//서버에 전송할 정보가 object 안에 있을때
			//const data={name:"원숭이", addr:"동물원"};
			//서버에 전송할 정보가 query string 안에 있을때
			const data="name=원숭이&addr=동물원";
			
			ajaxPromise("insert.jsp", "post", data)
			.then((res)=>{
				return res.json();
			})
			.then((data)=>{
				console.log(data);
			});
		});
	</script>
</body>
</html>

 

gura_util.js

	/*
		ajaxPromise("요청url", "요청메소드", query string or object)
		와 같은 형식으로 사용하고 
		Promise type 을 리턴해주는 함수 
	*/
	function ajaxPromise(url, method, data){
		//만일 필요한 값이 전달 되지 않으면 기본값을 method 와 data 에 넣어준다. 
		if(method == undefined || method == null){
			method="GET";
		}
		if(data == undefined || data == null){
			data={};
		}
		
		let queryString;
		if(typeof data == "string"){
			queryString=data;
		}else{
			queryString=toQueryString(data);
		}
		
		// Promise 객체를 담을 변수 만들기 
		let promise;
		if(method=="GET" || method=="get"){//만일 GET 방식 전송이면 
			//fetch() 함수를 호출하고 리턴되는 Promise 객체를 변수에 담는다. 
			promise=fetch(url+"?"+queryString);
		}else if(method=="POST" || method=="post"){//만일 POST 방식 전송이면
			//fetch() 함수를 호출하고 리턴되는 Promise 객체를 변수에 담는다. 
			promise=fetch(url,{
				method:"POST",
				headers:{"Content-Type":"application/x-www-form-urlencoded; charset=utf-8"},
				body:queryString
			});
		}
		return promise;
	}
	
	//함수의 인자로 ajax 전송할 폼의 참조값을 넣어주면 알아서 ajax 전송되도록 하는 함수 
	function ajaxFormPromise(form){
		const url=form.getAttribute("action");
		const method=form.getAttribute("method");
		
		// Promise 객체를 담을 변수 만들기 
		let promise;
		//파일 업로드 폼인지 확인해서
		if(form.getAttribute("enctype") == "multipart/form-data"){
			//폼에 입력한 데이터를 FormData 에 담고 
			let data=new FormData(form);
			// fetch() 함수가 리턴하는 Promise 객체를 
			promise=fetch(url,{
				method:"post",
				body:data
			});
			return promise;//리턴해 준다 (여기서 함수가 종료 된다.)			
		}
		
		const queryString=new URLSearchParams(new FormData(form)).toString();
		
		if(method=="GET" || method=="get"){//만일 GET 방식 전송이면 
			//fetch() 함수를 호출하고 리턴되는 Promise 객체를 변수에 담는다. 
			promise=fetch(url+"?"+queryString);
		}else if(method=="POST" || method=="post"){//만일 POST 방식 전송이면
			//fetch() 함수를 호출하고 리턴되는 Promise 객체를 변수에 담는다. 
			promise=fetch(url,{
				method:"POST",
				headers:{"Content-Type":"application/x-www-form-urlencoded; charset=utf-8"},
				body:queryString
			});
		}
		return promise;
	}
	
	//함수의 인자로 요청 url 과 ajax 전송할 내용이 있는 input 요소의 참조값을 전달하면 ajax 전송해주는 함수
	function ajaxInputPromise(url, input){
		const type=input.getAttribute("type");
		const name=input.getAttribute("name");
		
		let promise;
		if(type=="file"){ // input type="file" 인 경우 
			
			let data=new FormData();
			data.append(name, input.files[0]);
			
			promise=fetch(url,{
				method:"post",
				body:data
			});
		}else{ //아닌경우 
			
			//전송할 쿼리 문자열 구성
			const data=name+"="+encodeURIComponent(input.value);
			promise=fetch(url,{
				method:"POST",
				headers:{"Content-Type":"application/x-www-form-urlencoded; charset=utf-8"},
				body:data
			});
		}
		return promise;
	}
	
	//인자로 전달하는 object 를 이용해서 query  문자열을 만들어서 리턴해주는 함수
	function toQueryString(obj){
		//빈배열을 일단 만든다.
		let arr=[];
		//반복문 돌면서 obj 에 있는 정보를 "key=value" 형태로 만들어서 배열에 저장한다.
		for(let key in obj){
			//value 는 인코딩도 해준다. 
			let tmp=key+"="+encodeURIComponent(obj[key]);
			arr.push(tmp);
		}
		//query 문자열을 얻어낸다
		let queryString=arr.join("&");
		//결과를 리턴해준다.
		return queryString;
	}

 

'Servlet&JSP' 카테고리의 다른 글

Step04_Final (filter, login filter)  (0) 2022.08.22
Step04_Final (users, 회원가입, 로그인처리)  (0) 2022.08.22
Step04_Final(jstl)  (0) 2022.08.21
Step04_Final(cookie)  (0) 2022.08.21
Step04_Final (test_el)  (0) 2022.08.21