본문 바로가기

Java 웹 개발

21.11.12 - 웹 개발 입문 65일차

자바스크립트 - jQuery

 

ex) 태그 생성 예제

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>태그 생성 및 삭제</title>

    <!-- jquery cdn 또는 보유한 파일을 불러오는 코드를 작성 -->
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
    <script>
        $(function(){
            //생성 버튼을 누르면 h1태그를 만들고 Hello jQuery! 를 작성한 뒤 .target에 추가
            $(".create-btn").click(function(){
                //var h1 = document.createElement("h1");//VanillaJS
                var h1 = $("<h1>").text("Hello jQuery!");
                $(".target").append(h1);//.target에 h1을 append(안쪽 뒤에 추가) 하라!
                //$(".target").prepend(h1);//.target에 h1을 prepend(안쪽 앞에 추가) 하라!
                //$(".target").after(h1);//.target에 h1을 after(바깥쪽 뒤에 추가) 하라!
                //$(".target").before(h1);//.target에 h1을 before(바깥쪽 앞에 추가) 하라!
            });
        });
    </script>
</head>
<body>
    <button class="create-btn">생성</button>
    <hr>
    <div class="target"></div>
</body>
</html>

 

 

 

ex) 태그 생성 예제

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>설문조사 폼</title>
    <link rel="stylesheet" type="text/css" href="./css/commons.css">
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
    <script>
        $(function(){
            $(".create-btn").click(function(e){
                e.preventDefault();

                //.survey-contents에 추가한다(append)
                var template = $("#survey-content-template").html();
                $(".survey-contents").append(template);

            });
        });
    </script>

</head>
<body>
    <!-- 견본 태그 : 화면에 표시하지 않으면서 모양만 저장할 수 있는 <template> 태그 -->
    <template id="survey-content-template">
        <div class="row">
            <input type="text" name="surveyContent" placeholder="설문 항목 작성" required class="form-input">
        </div>
    </template>

       <form action="http://localhost:8080/web09/multi.txt" method="get">
        <div class="container-500 container-center">
            <div class="row center">
                <h1>설문 조사 생성</h1>
            </div>
            <div class="row">
                <input type="text" name="surveyTitle" placeholder="설문 제목" required
                                                        class="form-input">
            </div>
            <hr>
            <div class="row right">
                <button class="create-btn form-btn form-inline">항목 생성</button>
            </div>
            <hr>

            <!-- append를 수행할 수 있는 영역 생성 -->
            <div class="survey-contents">

            </div>

            <hr>
            <div class="row">
                <input type="submit" value="설문 등록" class="form-btn">
            </div>
        </div>

    </form>
</body>
</html>

 

 

추가) 같은 이름의 파라미터가 여러개 전송될 경우 서블릿 처리 하기

package web09.servlet;

import java.io.IOException;
import java.util.Arrays;

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(urlPatterns = "/multi.txt")
public class MultipleParameterServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			//다음 형태의 파라미터 수신
			//surveyTitle=a&surveyContent=b&surveyContent=c&surveyContent=d&surveyContent=e

			//-> surveyTitle은 기존 방식처럼 받으면 된다(파라미터 1개 고정) ---> String
			//-> surveyContent는 데이터 개수를 확정할 수 없다(파라미터 여러개) ---> String[]
			String surveyTitle = req.getParameter("surveyTitle");
			String[] surveyContent = req.getParameterValues("surveyContent");

			System.out.println("surveyTitle = " + surveyTitle);
			System.out.println("surveyContent = " + Arrays.toString(surveyContent));
		}
		catch(Exception e) {
			e.printStackTrace();
			resp.sendError(500);
		}
	}
}

등록

 

결과

 

다음 우편 API 사용법

- 우편 검색 페이지 구현

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>주소 검색 예제</title>

    <!-- daum 우편 api 관련 스크립트 -->
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    <!-- jquery cdn 또는 보유한 파일을 불러오는 코드를 작성 -->
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
    <script src="address.js"></script>
</head>
<body>
    <input type="text" name="postcode" placeholder="우편번호">
    <input type="button" value="우편번호 찾기" class="find-address-btn"><br>
    <input type="text" name="basicAddress" placeholder="주소"><br>
    <input type="text" name="extraAddress" placeholder="상세주소">
</body>
</html>

 

- 주소 검색 모듈 address.js 구현

/*
    주소 검색 모듈
    .find-address-btn을 누르면 자동으로 주소검색창이 나옴
    
    - input[name=postcode] 에 우편번호 작성
    - input[name=basicAddress] 에 기본주소 작성
    - input[name=extraAddress] 에 커서 이동
    작성자 : 피카츄
    작성일 : 2021-11-12
*/
$(function(){
    //.find-address-btn이 눌리면(태그 종류 무관) 무조건 주소 검색창 출력
    $(".find-address-btn").click(function(e){
        e.preventDefault();//a태그일 경우를 대비
        findAddress();
    });

    function findAddress() {
        new daum.Postcode({
            oncomplete: function(data) {
                console.log(data);
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다
                // (주의) jQuery로 처리하려면 jQuery CDN이 이 코드보다 위에 있어야 한다.

                document.querySelector("input[name=postcode]").value = data.zonecode;
                //$("input[name=postcode]").val(data.zonecode);
                document.querySelector("input[name=basicAddress]").value = addr;
                //$("input[name=basicAddress]").val(addr);
                // 커서를 상세주소 필드로 이동한다.
                document.querySelector("input[name=extraAddress]").focus();
                //$("input[name=extraAddress]").focus();
            }
        }).open();
    }
});

 

 

카카오 지도 API 사용법

https://apis.map.kakao.com/

카카오 api에 접속 하고 로그인 후 

 

키발급을 눌러 진행한다

 

앱이름, 사업자명 작성

 

키가 발급된다. (JavaScript키 사용)

키 생성

 

플랫폼을 등록한다.

플랫폼 등록

 

 

 

ex) 카카오 api 샘플 지도 생성하기

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<title>Kakao 지도 시작하기</title>
</head>
<body>
	<div id="map" style="width:500px;height:400px;"></div>
	<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 사용하세요"></script>
	<script>
		var container = document.getElementById('map');
		var options = {
			center: new kakao.maps.LatLng(33.450701, 126.570667),
			level: 3
		};

		var map = new kakao.maps.Map(container, options);
	</script>
</body>
</html>

 

 

 

ex) 카카오 api 샘플 지도 규칙적으로 코드 변경

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<title>Kakao 지도 시작하기</title>

	<style>
		#map {
			width:500px;
			height:400px;
		}
	</style>

	<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 사용하세요"></script>
	<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
	<script>
		$(function(){
			//지도 생성 준비 코드
			var container = document.querySelector("#map");
			var options = {
				center: new kakao.maps.LatLng(33.450701, 126.570667),
				level: 3
			};

			//지도 생성 코드
			var map = new kakao.maps.Map(container, options);
		});
	</script>
</head>
<body>
	<div id="map"></div>
</body>
</html>

 

 

 

ex) 카카오 api 샘플 지도 버튼누르면 이동하기 , 지도 확대/축소 기능 구현

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<title>Kakao 지도 시작하기</title>

	<style>
		#map {
			width:500px;
			height:400px;
		}
	</style>

	<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 사용하세요"></script>
	<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
	<script>
		$(function(){
			//지도 생성 준비 코드
			var container = document.querySelector("#map");
			var options = {
				center: new kakao.maps.LatLng(33.450701, 126.570667),
				level: 3
			};

			//지도 생성 코드
			var map = new kakao.maps.Map(container, options);

			//버튼을 누르면 해당 지역으로 이동하도록 처리
			$(".btn-move").click(function(){
				//var lat = $(this).attr("data-lat");
				var lat = $(this).data("lat");
				//var lng = $(this).attr("data-lng");
				var lng = $(this).data("lng");
				var location = new kakao.maps.LatLng(lat, lng);
				map.setCenter(location);


			$(".btn-level-increase").click(function(){
				map.setLevel(map.getLevel() + 1);
			});
			$(".btn-level-decrease").click(function(){
				map.setLevel(map.getLevel() - 1);
			});
			});
		}); 
	</script>
</head>
<body>
	<!-- 팁 : 태그에 정보를 보관해야 할 경우 data- 로 시작하는 속성을 만들어 저장할 것을 권장 -->
	<button class="btn-move" data-lat="37.566668" data-lng="126.977629">서울</button>
	<button class="btn-move" data-lat="35.180716" data-lng="129.074935">부산</button>
	<button class="btn-move" data-lat="37.456906" data-lng="126.705958">인천</button>
	<button class="btn-move" data-lat="36.351251" data-lng="127.384818">대전</button>
	<button class="btn-level-increase">+</button>
	<button class="btn-level-decrease">-</button>
	<div id="map"></div>
</body>
</html>

 

 

 

ex) 카카오 api 샘플 지도 마커, 인포윈도우 제어, 위치정보 변환

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<title>Kakao 지도 시작하기</title>

	<style>
		#map {
			width:500px;
			height:400px;
		}
	</style>

	<!-- 장소 정보 변환을 사용하려면 &libraries=services 가 src에 추가되어야 한다 -->
	<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=발급받은 APP KEY를 사용하세요"></script>
	<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
	<script>
		$(function(){
			//지도 생성 준비 코드
			var container = document.querySelector("#map");
			var options = {
				center: new kakao.maps.LatLng(33.450701, 126.570667),
				level: 3
			};

			//지도 생성 코드
			var map = new kakao.maps.Map(container, options);

			//주소 -> 좌표
			$(".convert").click(function(){
				//1. 변환할 주소를 준비
				var address = $("input[name=address]").val();

				//2. 카카오 장소변환 샘플 코드를 복사 후 일부 수정
				// 주소-좌표 변환 객체를 생성합니다
				var geocoder = new kakao.maps.services.Geocoder();

				// 주소로 좌표를 검색합니다
				geocoder.addressSearch(address, function(result, status) {

					// 정상적으로 검색이 완료됐으면 
					if (status === kakao.maps.services.Status.OK) {

						//위도 == result[0].y
						//경도 == result[0].x
						var coords = new kakao.maps.LatLng(result[0].y, result[0].x);

						$("input[name=latitude]").val(result[0].y);
						$("input[name=longitude]").val(result[0].x);

						// 결과값으로 받은 위치를 마커로 표시합니다
						var marker = new kakao.maps.Marker({
							map: map,
							position: coords
						});

						// 인포윈도우로 장소에 대한 설명을 표시합니다
						var infowindow = new kakao.maps.InfoWindow({
							content: '<div style="width:150px;text-align:center;padding:6px 0;">'+address+'</div>'
						});
						infowindow.open(map, marker);

						// 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
						map.setCenter(coords);
					} 
				});    
			});
		});
	</script>
</head>
<body>
	<div id="map"></div>
	<hr>
	주소 : <input type="text" name="address">
	<button class="convert">변환</button>
	<hr>
	위도 : <input type="text" name="latitude">
	<br>
	경도 : <input type="text" name="longitude">
</body>
</html>

 

 

ajax 기본 구조

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>동기요청 vs 비동기요청</title>
    <!-- jquery cdn 또는 보유한 파일을 불러오는 코드를 작성 -->
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
    <script>
        $(function(){

            //동기화
            $(".sync-btn").click(function(){
                //location.href = "https://httpbin.org/get";
                location.href = "http://localhost:8080/home/index.jsp";
            });

            //비동기화
            //$.ajax({옵션});
            $(".async-btn").click(function(){
                $.ajax({
                    url:"http://localhost:8080/home/index.jsp", //요청을 보낼 주소
                });
            });

        });
    </script>
</head>
<body>
    <button class="sync-btn">동기 요청</button>
    <button class="async-btn">비동기 요청</button>
</body>
</html>

 

 

- 동기 요청 : 동기화된 요청을 보내면 요청이 완료될 때까지 사용자는 할 수 있는 작업이 없다.

동기 요청

 

 

- 비동기 요청 : 비동기화된 요청을 보내면 화면은 유지되며 요청이 백그라운드 처리된다.

비동기요청

 

 

ajax 아이디 중복검사 및 CORS 처리

- web.xml cors filter 코드 추가하기 

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="4.0"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
       							 http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
 	
 	
 	<!-- 
		CORS 허용 설정 : 비동기 통신을 지정한 주소에서 보낼 수 있도록 처리하는 설정
	 -->
	<filter>
		<filter-name>CorsFilter</filter-name>
		<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
		<init-param>
			<param-name>cors.allowed.origins</param-name>
			<param-value>http://127.0.0.1:5500</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CorsFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>	
 	
 
 </web-app>

 

 

- 아이디 중복 검사 서블릿 (MemberAjaxIdCheckServlet.java) 만들기

package home.servlet.member;

import java.io.IOException;

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 home.beans.MemberDao;
import home.beans.MemberDto;

//비동기 통신을 위한 서블릿
@WebServlet(urlPatterns = "/member/ajax_id_check.txt")
public class MemberAjaxIdCheckServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			String memberId = req.getParameter("memberId");

			MemberDao memberDao = new MemberDao();
			MemberDto memberDto = memberDao.get(memberId);

			if(memberDto == null) {
				//아이디가 없다 => 사용이 가능하다 => NNNNY를 전송
				resp.getWriter().write("NNNNY");
			}
			else {
				//아이디가 있다 => 사용이 불가능하다 => NNNNN을 전송
				resp.getWriter().write("NNNNN");
			}
		}
		catch(Exception e) {
			e.printStackTrace();
			resp.sendError(500);
		}
	}
}

 

 

- 아이디 중복 페이지 만들기

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>아이디 중복 검사</title>

    <!-- jquery cdn 또는 보유한 파일을 불러오는 코드를 작성 -->
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
    <script>
        //목표 : 
        //= 입력이 발생하면 or 입력을 마친 후 사용자 몰래 아이디의 존재 여부를 서버에 질문
        //= 서버는 아이디가 존재하면 NNNNN , 존재하지 않으면 NNNNY를 반환
        //= 서버에서 돌아온 응답에 따라 메세지를 다르게 출력

        $(function(){
            $("input[name=memberId]").on("blur", function(){

                var inputId = $("input[name=memberId]").val();

                $.ajax({
                    //준비 설정
                    url:"http://localhost:8080/home/member/ajax_id_check.txt",
                    type:"get",//전송 방식
                    data:{//전송 시 첨부할 파라미터 정보
                        memberId : inputId
                    },
                    //완료 처리
                    success:function(resp){//NNNNN, NNNNY 중 하나가 돌아왔다(통신이 성공)
                        //console.log("성공");
                        //console.log(resp);
                        if(resp == "NNNNY"){
                            $("input[name=memberId]").next().text("아이디 사용 가능");
                        }
                        else if(resp == "NNNNN"){
                            $("input[name=memberId]").next().text("아이디가 이미 사용중입니다");
                        }
                    },
                    error:function(err){//통신이 실패했다.
                        //console.log("실패");
                        //console.log(err);
                    }
                });
            });
        });

    </script>
</head>
<body>
    아이디 : <input type="text" name="memberId">
    <span></span>
</body>
</html>