Programming/Spring

[Spring] REST API: Client 구축

Isaac S. Lee 2023. 11. 30. 12:37

🌿REST API를 이용한 Client 구축


 

[Spring] REST API, RESTful API (CSR: Client Side Rendering)

🌿REST REST(Representational State Transfer)는 웹 상의 자원(문서, 이미지, 영상 등)을 자원명으로 표시해서 상태를 주고받는 규칙을 의미한다. HTTP URI를 통해서 자원을 명시하고, HTTP Method를 통해서 자원

isaac-christian.tistory.com

이전의 REST API 글에서 이어진다.

 

REST Server의 기능을 이용한 주소록 관리 프로그램을 만들어 보도록 하자.

내가 필요한 기능을 입출력할 수 있는 Open API가 있다고 생각하고, 해당 Open API만을 이용해서 화면을 만들 예정이다.

부가적으로 만들 화면을 모바일이라고 생각하고 작게 구축하도록 한다.

 

프로젝트 설정

1. pom.xml

Java/Spring 버전 설정

Java는 11, Spring은 5.0.7.RELEASE로 설정을 바꿔준다

 

파일 추가

com.test.controller

  • ClientController.java

views

  • list.jsp
  • add.jsp
  • view.jsp
  • edit.jsp (X)
  • del.jsp (X)

views > inc

  • header.jsp
  • asset.jsp

webapp > resources > css

  • main.css

공통적으로 적용할 css가 있기 때문에 css파일을 생성하였다.

 

viewport

<meta name="viewport" content="width=device-width, initial-scale=1">

https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag

 

Viewport meta tag - HTML: HyperText Markup Language | MDN

This article describes how to use the "viewport" <meta> tag to control the viewport's size and shape.

developer.mozilla.org

물리적인 장치는 480px인데 그 안에 960px을 넣은 것이다.

그래서 글자가 화면에서 작게 보이는데 이 meta 태그를 넣으면 해당 viewport를 물리적인 장치 너비에 맞춰서 재조정을 하고, scale을 1:1 정사이즈로 출력하게 하는 것이다. 이제 해당 장치에 적합한 크기로 나타나게 세팅이 된다.

 

Google fonts

https://fonts.google.com/icons?selected=Material+Symbols+Outlined:woman:FILL@0;wght@400;GRAD@0;opsz@24&icon.query=man

 

Material Symbols and Icons - Google Fonts

Material Symbols are our newest icons consolidating over 2,500 glyphs in a single font file with a wide range of design variants.

fonts.google.com

 

🌿전체 코드


🍃ClientController.java

package com.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ClientController {

	@GetMapping(value = "/list.do")
	public String list(Model model) {

		return "list";
	}
	
	@GetMapping(value = "/add.do")
	public String add(Model model) {

		return "add";
	}
	
	@GetMapping(value = "/view.do")
	public String view(Model model, String seq) {

		model.addAttribute("seq", seq);
		
		return "view";
	}
	
}

 

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Address</title>
<%@ include file="/WEB-INF/views/inc/asset.jsp" %>
<style>
	
</style>
</head>
<body>
	<!-- list.jsp -->
	<%@ include file="/WEB-INF/views/inc/header.jsp" %>

	<!-- 목록 -->	
	<div class="list full">
		<!--
		<div class="item">
			<div class="name">
			Isaac<span class="male_2 material-symbols-outlined">man_2</span>
			</div>
			<div class="address">서울시 강남구 역삼동</div>
		</div>
		-->
	</div>
	
	<div>
		<button type="button" class="add" onclick="location.href='/client/add.do';">등록하기</button>
	</div>
	
	<script>
		$.ajax({
			type: 'GET',
			url: 'http://localhost:8090/rest/address',
			dataType: 'json',
			success: list => {
				//console.log(list);
				$(list).each((index, item) => {
					
					let gender = item.gender == 'm' ? 'man_2' : 'woman';
					
					$('.list').append(`
						<div class="item" onclick="view(\${item.seq});">
							<div class="name">\${item.name}<span class="\${gender} material-symbols-outlined">\${gender}</span>
							</div>
							<div class="address">\${item.address}</div>
						</div>
					`);
				});
			},
			error: (a,b,c) => {
				console.log(a,b,c)
			}
		});

		function view(seq) {
			//alert(seq);
			location.href = '/client/view.do?seq=' + seq;
		}
	</script>
</body>
</html>

REST API Server를 이용하는 클라이언트는 Ajax를 사용한다. 그래서 결과적으로 CSR 방식으로 페이지를 만들게 된다.

상세보기로 넘어갈 때 seq를 가지고 넘어가도록 onclick을 설정한다.

 

add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Address</title>
<%@ include file="/WEB-INF/views/inc/asset.jsp" %>
<style>

</style>
</head>
<body>
	<!-- add.jsp -->
	<%@ include file="/WEB-INF/views/inc/header.jsp" %>
	
	<table>
		<tr>
			<td><input type="text" name="name" placeholder="이름" class="full" required></td>
		</tr>
		<tr>
			<td><input type="text" name="age" placeholder="나이" class="full" required></td>
		</tr>
		<tr>
			<td>
				<select name="gender">
					<option value="m">남자</option>
					<option value="f">여자</option>
				</select>
			</td>
		</tr>
		<tr>
			<td><input type="text" name="address" placeholder="주소" class="full" required></td>
		</tr>
	</table>
	<div>
		<button type="button" class="add" onclick="add();">등록하기</button>
		<button type="button" class="list" onclick="location.href='/client/list.do';">목록보기</button>
	</div>
	
	<script>
		
		function add() {
			
			//전송할 데이터
			let obj = {
				name: $('input[name=name]').val(),
				age: $('input[name=age]').val(),
				gender: $('select[name=gender]').val(),
				address: $('input[name=address]').val()
			};
			
			//alert(JSON.stringify(obj));
			
			$.ajax({
				type: 'POST',
				url: 'http://localhost:8090/rest/address',
				headers: {'Content-Type': 'application/json'},
				data: JSON.stringify(obj),
				dataType: 'json',
				success: result => {
					//alert(result);
					if (result == 1) {
						location.href = '/client/list.do';
					} else {
						alert('failed');
					}
				},
				error: (a,b,c) => {
					console.log(a,b,c);
				}
			});
		}
	
	</script>
</body>
</html>

JSON.stringify

obj 객체를 만들고, 여기에 전송할 데이터를 넣는다.

자바스크립트 객체를 JSON으로 표기하는 방법으로 JSON.stringify를 사용하는 게 있다.

보내는 데이터 헤더에서 서버가 받는 게 JSON이라는 것을 알려 주어야 한다.

 

view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Address</title>
<%@ include file="/WEB-INF/views/inc/asset.jsp" %>
<style>

</style>
</head>
<body>
	<!-- view.jsp -->
	<%@ include file="/WEB-INF/views/inc/header.jsp" %>
	
	<div class="list full">
		<div>이름</div>
		<div>나이</div>
		<div>성별</div>
		<div>주소</div>
	</div>
	
	<div>
		<button type="button" class="del" onclick="del();">삭제하기</button>
		<button type="button" class="list" onclick="location.href='/client/list.do';">목록보기</button>
	</div>
	
	<script>
	
		$.ajax({
			type: 'GET',
			url: 'http://localhost:8090/rest/address/${seq}',
			dataType: 'json',
			success: item => {
				$('.list > div:nth-child(1)').text(item.name);
				$('.list > div:nth-child(2)').text(item.age);
				$('.list > div:nth-child(3)').text(item.gender);
				$('.list > div:nth-child(4)').text(item.address);
			},
			error: (a,b,c) => {
				console.log(a,b,c);
			}
		});
	
		function del() {
			
			$.ajax({
				type: 'DELETE',
				url: 'http://localhost:8090/rest/address/${seq}',
				dataType: 'json',
				success: result => {
					if (result == 1) {
						location.href = '/client/list.do';
					} else {
						alert('failed');
					}
				},
				error: (a,b,c) => {
					console.log(a,b,c)
				}
			});
		}
		
	</script>
</body>
</html>

 

header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- inc > header.jsp -->
<h1 class="main">
	Address <small>REST</small>
    <span class="material-symbols-outlined" data-sidebar-button="sidebar">menu</span>
</h1>

<div data-sidebar-window="sidebar" data-sidebar-title="Menu" data-sidebar-direction="right">
    <ul>
    	<li>Home</li>
    	<li>Address</li>
    	<li>Board</li>
    </ul>
</div>

 

asset.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- inc > asset.jsp -->
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<link rel="stylesheet" href="/client/resources/css/main.css">

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://pinnpublic.dothome.co.kr/cdn/example-min.js"></script>

 

main.css

html, body {
	display: block !important;
	width: 100% !important;
	height: 100% !important;
}

body > h1 {
	margin: 0 !important;
	padding-top: 1rem !important;
}

.main > span {
	font-size: 1.7rem !important;
	float: right;
	margin-right: 5px;
}

.list .item .name {
	font-size: 1.3rem;
}

.list .item span.man_2 {
	color: cornflowerblue;
	transform: translate(0, 4px);
}

.list .item span.woman {
	color: tomato;
	transform: translate(0, 4px);
}

.list .item .address {
	font-style: italic;
}