프로그래밍

[HTML] jQuery, AJAX 활용

RainIron 2021. 6. 21. 15:38
반응형

* 동기식 통신

- 웹 브라우저가 요청 후 응답이 도착할 때까지는 이용자와 상호작용 불가

- 매우 소량의 데이터라도 웹 브라우저에 도달하면 전체 화면을 갱신

 

* 비동기식 통신

- 웹 페이지가 출력된 후라도 백그라운드로 서버에 요청이 가능

- 웹 브라우저가 이용자와 상호 작용하면서도 내부적으로 서버에 요청 및 응답을 처리

- 서버로부터 응답이 도착하면 개발자가 응답을 변수에 저장할 수 있다.

- 개발자는 필요시 화면의 일부분에 응답을 출력할 수 있다.

- Ajax


※ jQuery

* jQuery 라이브러리를 사용하나 AJAX 통신을 선호

* jQuery 라이브러리 설치 / 테스트

  1) https://code.jquery.com/ 이동

  2) minified에서 script 내용을 복사하여 html 파일의 <head> 안에 삽입한다.

  3) 테스트용 함수 입력

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>jQuery Test</title>
	<script
  src="https://code.jquery.com/jquery-3.6.0.min.js"
  integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
  crossorigin="anonymous"></script>
  <script>
 	 $(function(){
		alert('jQuery Ready!');
		})
  </script>
</head>
<body>
	
</body>
</html>

- $( ): jQuery 함수이며 Argument로 다른 함수를 정의하면 jQuery는 그 Argument로 전달된 함수를 특정 시기(jQuery가 로드되어 사용할 준비가 된 경우)에 호출한다. 객체 상태인 코드를 참조할 수 있을 때 실행.

웹 페이지를 구성하는 어떤 태그에도 jQuery를 사용하여 접근이 가능한 때에 이 함수(전달된 함수)가 호출된다.

- # : id selector

 

* 예제(계산기)

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>jQuery Test</title>
	<script
  src="https://code.jquery.com/jquery-3.6.0.min.js"
  integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
  crossorigin="anonymous"></script>
  
  <script>
 	 $(function(){
 		 console.log('jQuery Ready!');
 		 $('#btn1').click(function(){
 			 var sum = parseInt($('#a').val()) + parseInt($('#b').val());
 			 $('#sum').val(sum);
 		 });
		});
  </script>
</head>
<body>
	<h3>jQuery Test</h3>
	<p>Press Button!</p>
	<input id = 'a'>+
	<input id = 'b'>=
	<input id = 'sum'></div>
	<p><button type='button' id='btn1'>계산</button></p>
</body>
</html>

※ AJAX(Asynchronous Javascript And XML)

- 자바스크립트 비동기식 통신(HTTP 통신)

- 통신의 양 노드

  * HTTP Client: Web Brower

  * HTTP Server: Web Server

  * 통신의 수단: Java Script or jQuery

- 통신할 때 화면이 새로고침되지 않는다.(응답이 클라이언트에 도달하더라도 화면은 변하지 않는다.)

- Background에서 서버로 request, response(변수)를 보내고 받는다. 이 때, 받은 response를 참조하고 조작할 수 있다.

 

(예) 로그인 창에서 로그인 시도 후, 성공과 실패에 대한 결과를 알림창으로 사용자에게 알려준다. 성공 혹은 실패한 경우 로그인 창 자체에 변화가 생긴다면 낭비되는 자원이 많이 때문에, 변화를 주지 않고 alert를 사용해 알려준다.

-> HTML 문서로 성공 or 실패 알려주기 위해 필요한 자원 vs alert로 알려주기 위해 필요한 자원

 

* ajaxTest.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>AJAX 통신 테스트</title>
	<script
	  src="https://code.jquery.com/jquery-3.6.0.min.js"
	  integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
	  crossorigin="anonymous"></script>
	  
	<script>
		$(function(){
			$('#loginbtn').click(function(){
				// id, pwd를 서버로 전송하고 로그인 성공 여부를 리턴받는다.
				
				// 폼에서 id,pwd를 가져와서 JSON 오브젝트로 표현한다.
				var jsObj = {};
				jsObj.id = $('#id').val();
				jsObj.pwd = $('#pwd').val();

				// 파라미터를 서버로 전송하고 응답을 수신한다.
				$.ajax({
					// 데이터 송신 정의
					// url: url에 연결된 프로그램에게 송신(꼭 jsp가 아닐 수 있다.)
					url:'/MyWeb/loginAjax',
					method: 'post',
					data: jsObj,
					
					// 데이터 수신 정의
					dataType: 'json',
					// 요청이 성공할 때 실행되는 함수
					// function(res)의 Argument res는 jsp에서 보낸 응답이다.
					success: function(res){
						if(res.result){
							alert('로그인 성공');
							$('#userid').text('로그인 성공');
							$('#loginform').css('display', 'none');
						}
						else{
							alert('로그인 실패');
						}
						
					},
					// 요청이 실패할 때 실행되는 함수
					error: function(xhr, textStatus, errorThrown){
						alert(textStatus + ': '+errorThrown);
					}
				})
			});
		});
	</script>
	
	<style>
		#loginform{position: relative; border: 1px solid black; width: 300px; padding-top: 5px;}
		div {margin-bottom:5px; text-align: center;}
		input{position: relative; margin-left: 5px; width: 100px}
		label{display: inline-block;width: 80px; text-align:right;}
		button{text-align: center;}
	</style>
</head>
<body>
	<h3>로그인</h3>
	<div id = "userid"></div>
	<form id="loginform" action="/loginAjax" method="post">
		<div>
			<label>ID</label> <input type = "text" id = "id">
		</div>
		<div>
			<label>Password</label> <input type = "password" id = "pwd">
		</div>
		<div>
			<button type = "button" id="loginbtn">확인</button>
		</div>
	</form>
</body>
</html>

- input 태그 중 id는 클라이언트에서 참조하기 위해 필요한 속성이고, name은 서버에서 참조하기 위해 필요한 속성이다.

 

* ajaxResult.jsp

- dataType: 'json'일 경우 json 객체로 보내기 위한 라이브러리가 필요하다.

https://code.google.com/archive/p/json-simple/downloads

 

Google Code Archive - Long-term storage for Google Code Project Hosting.

 

code.google.com

json-simple-1.1.1.jar을 다운받고 eclispse에서 build-path로 외부 jar 참조

[에러메시지 발생!]

SEVERE: 서블릿 [jsp]을(를) 위한 Servlet.service() 호출이 예외를 발생시켰습니다.
org.apache.jasper.JasperException: JSP를 위한 클래스를 컴파일할 수 없습니다.: 

Only a type can be imported. org.json.simple.JSONObject resolves to a package

JSP 파일 [/ajaxResult.jsp]의 [9] 행에서 오류가 발생했습니다.
JSONObject cannot be resolved to a type

=> json-simple-1.1.1.jar 파일을 Tomcat/lib에 위치시켰다.

<%@page import="org.json.simple.JSONObject"%>
<%@ page contentType="application/json; charset=utf-8"
    pageEncoding="utf-8"%>
<%
	/* datatype: 'text'일 경우 테스트하기 위한 디버그용 코드
    response.getWriter().print("{'result': 'result'}");
	response.getWriter().flush();
	*/
	JSONObject jsObj = new JSONObject();
	jsObj.put("result", (boolean)request.getAttribute("result"));
	response.getWriter().write(jsObj.toJSONString());
	response.getWriter().flush();
%>

 

 

* loginAjax.java

package com.tjoeun.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

import com.tjoeun.Login;
@WebServlet("/loginAjax")
public class loginAjax extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html; charset=utf-8");
		System.out.println("loginAjax 실행 됨");
		
		// Business Logic
		// request를 가진 Login 객체 생성
		Login lg = new Login(request);
		
		// Presentation Logic
		request.setAttribute("result", lg.check());
		getServletContext().getRequestDispatcher("/ajaxResult.jsp").forward(request, response);
		
	}

}

- request를 받은 jsp에서 어떤 결과를 보낼 지 결정

- ajaxResult.jsp에서 보낼 내용이 ajaxTest.html의 jQuery 중 success 함수 안 Argument인 res로 dataType에 맞게 전달된다.

 

* 실행창

로그인이 성공할 경우
로그인 성공이라는 말이 출력된다.
로그인 실패할 경우

 

* Scope Object(영역 객체)

- page, request, session, application

- page: 한 개의 jsp 파일 내의 영역(영역의 최소 단위), 영역 객체의 이름(참조변수): pageContext

- request: 한 개의 요청이 전달되는 모든 jsp

- session: 한 이용자가 방문하는 모든 jsp, servlet 영역 ex) 장바구니(사용자에게 변수를 지정해놓고, 이동하는 url 저장)

- application: 한 사이트에 있는 모든 jsp, servlet 영역

 

- 로그인 성공 시, 로그인 유저의 session 변수를 활용하여 코딩하기(servlet에서 접근 가능, 이용자가 접속하면 생성)

  (허가하지 않은(로그인이 되지 않은 사용자) 사용자가 접근하면 차단하기)

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%
	String uid = (String)session.getAttribute("userid");
	if(uid == null){
		// 로그인 페이지로 강제 이동
		response.sendRedirect("/MyWeb/jQuery/ajaxTest.html");
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>메인 페이지</title>
</head>
<body>
	<h2>로그인을 거친 회원분들만 접근 가능한 페이지입니다.</h2>
</body>
</html>
반응형