반응형
지난 포스트에 이어서 JSP를 사용하여 화면을 만들고 Jquery로 Ajax 통신을 구현하여 API와 CRUD 통신에 성공하는 것까지 정리하려 합니다.
전체 소스코드는 아래에 URL에 있습니다.
https://github.com/leeyoungseung/item-admin
1. 내장 Tomcat에서 JSP사용하기
Spring boot의 내장 Tomcat에서 JSP를 사용하기 위해서는 몇 가지 설정과 라이브러리를 추가해주어야 합니다.
※ 설정 방법
1) build.gradle의존성 추가
// JSP를 페이지로 인식하기 위한 라이브러리
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
// JSTL을 사용할 경우 추가해야하는 라이브러리
implementation 'javax.servlet:jstl:1.2'
2) build.gradle플러그인 추가
apply plugin: 'war'
2. JSP로 화면 구현하기
- index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script async src="/webjars/jquery/3.6.0/jquery.min.js"></script>
<script async src="/js/ajax-item-admin.js"></script>
<link href="/webjars/bootstrap/4.6.0/css/bootstrap.min.css"
rel="stylesheet" id="bootstrap-css">
<style type="text/css">
.container {
max-width: 960px;
}
.form-control-borderless {
border: none;
}
.form-control-borderless:hover, .form-control-borderless:active,
.form-control-borderless:focus {
border: none;
outline: none;
box-shadow: none;
}
#item-list {
border-style: outset;
}
</style>
</head>
<body class="bg-light">
<div class="container">
<div class="py-5 text-center">
<img class="d-block mx-auto mb-4"
src="/img/item-logo.png"
alt="" width="72" height="72">
<h1>Item Admin Page</h1>
<p class="lead">상품 검색, 등록, 정보수정, 삭제등의 관리를 할 수 있습니다.</p>
</div>
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8">
<form class="card card-sm">
<div class="card-body row no-gutters align-items-center">
<div class="col-auto">
<i class="fas fa-search h4 text-body"></i>
</div>
<div class="col">
<input
class="form-control form-control-lg form-control-borderless"
type="search"
placeholder="Please Iuput Item Number And Click Search Button!" id="search">
</div>
<div class="col-auto">
<button class="btn btn-lg btn-success" type="button" id="search-btn" >Search</button>
</div>
</div>
</form>
</div>
<!--end of col-->
<div class="card-body row no-gutters align-items-center">
<button class="btn btn-lg btn-info" type="button" id="create-form-btn">Apply Item Info</button>
</div>
</div>
<br />
<div id="item-list">
</div>
</div>
<!-- .container -->
</body>
</html>
3. 부트스트랩 + Jquery 의존성 추가
Jquery나 부트스트랩을 cdn으로 적용하는 방법도 있지만, 이 프로젝트에서는 Jar라이브러리를 추가하여 Jquery와 부트스트랩을 적용합니다.
※ 설정 방법
1) build.gradle의존성 추가
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
implementation group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
2) index.jsp에 Jquery와 부트스트랩 적용하기
index.jsp에 Jquery와 부트스트랩을 적용하기 위해서는. jar파일에서 정확한 경로를 먼저 확인해야 합니다.
Project and External Dependencies에서 Jquery와 부트스트랩 라이브러리를 확인합니다.
위의 사진을 보면 알 수 있는데 Jquery라이브러리의 경로는
'META-INF/resources/webjars/jquery/3.6.0/'인 것을 확인할 수 있습니다.
위의 캡처처럼 'META-INF/resources' 아래의 경로 /webjars/jquery/3.6.0/파일명을 js파일의 경우 <script>의 src속성 값으로 , css파일은 <link>의 href속성 값으로 넣어주면 됩니다.
4. JQuery Ajax 코드 작성
1) CRUD 코드
/**
* ajax-dev
*/
var itemApi = "http://localhost:8080/api/items";
$('#search-btn').on("click", function() {
var itemNo = $("#search").val();
getItemData(itemNo);
});
/* Get Item Data*/
function getItemData(itemNo) {
//alert(apiUrl+str);
$.ajax({
url: itemApi+'/'+itemNo,
method : 'GET',
success : function(item){
//alert(JSON.stringify(item))
makeItemView(item);
},
error: function(xhr, textStatus, error){
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
}
});
}
function clearItemInfo() {
$("#item-list").html('<div></div>');
}
/* Render Item Info */
function makeItemView(item) {
var view = '';
view = view + '<div class="row justify-content-center">';
view = view + '<div class="col-md-8 order-md-1">';
view = view + '<h4 class="mb-3">Item Number : '+item.itemId+'</h4>';
view = view + ' <form class="needs-validation" novalidate>';
view = view + ' <div class="row col-md-6 mb-3">';
view = view + ' <label for="itemName">ItemName</label> ';
view = view + ' <input type="text"class="form-control" id="itemName" value="'+item.itemName+'" readonly>';
view = view + ' </div>';
view = view + ' <div class="mb-3">';
view = view + ' <label for="itemDescription">itemDescription</label>';
view = view + ' <div class="input-group">';
view = view + ' <input type="text" class="form-control" id="itemDescription" value="'+item.itemDescription+'" >';
view = view + ' </div>';
view = view + ' </div>';
view = view + ' <div class="row col-md-6 mb-3">';
view = view + ' <label for="makerCode">makerCode </label> ';
view = view + ' <input type="text" class="form-control" id="makerCode" value="'+item.makerCode+'">';
view = view + ' </div>';
view = view + ' <div class="row col-md-6 mb-3">';
view = view + ' <label for="price">price</label> ';
view = view + ' <input type="text" class="form-control" id="price" value="'+item.price+'">';
view = view + ' </div>';
view = view + ' <div class="mb-3">';
view = view + ' <label for="saleStatus">saleStatus</label>';
view = view + ' <div class="input-group">';
var stopChecked = '';
var startChecked = '';
if (item.saleStatus === 0) {
stopChecked = ' checked=checked'
} else if (item.saleStatus === 1) {
startChecked = ' checked=checked'
}
view = view + ' <div class="form-check form-check-inline">';
view = view + ' <input class="form-check-input" type="radio" name="saleStatus" id="inlineRadio1" value="0" '+stopChecked+'>';
view = view + ' <label class="form-check-label" for="inlineRadio1">판매정지</label>';
view = view + ' </div>';
view = view + ' <div class="form-check form-check-inline">';
view = view + ' <input class="form-check-input" type="radio" name="saleStatus" id="inlineRadio2" value="1" '+startChecked+'>';
view = view + ' <label class="form-check-label" for="inlineRadio2">판매중</label>';
view = view + ' </div>';
view = view + ' </div>';
view = view + ' </div>';
// hidden value
view = view + '<input type="hidden" id="itemId" name="itemId" value="'+item.itemId+'">';
view = view + '<input type="hidden" id="old_itemName" name="old_itemName" value="'+item.itemName+'">';
view = view + '<input type="hidden" id="old_itemDescription" name="old_itemDescription" value="'+item.itemDescription+'">';
view = view + '<input type="hidden" id="old_makerCode" name="old_makerCode" value="'+item.makerCode+'">';
view = view + '<input type="hidden" id="old_price" name="old_price" value="'+item.price+'">';
view = view + '<input type="hidden" id="old_saleStatus" name="old_saleStatus" value="'+item.saleStatus+'">';
view = view + ' </form>';
view = view + '</div>';
view = view + '</div>';
view = view + '<div class="row form-row float-right mx-auto">';
view = view + '<button class="btn float-left btn-warning mr-3" type="button" id="update-btn">Item Update</button>';
view = view + '<button class="btn float-right btn-danger mr-3" type="button" id="delete-btn">Item Delete</button>';
view = view + '<button class="btn float-right btn-primary mr-3" type="button" id="clear-btn">Clear</button>';
view = view + '</div>';
$("#item-list").html(view);
}
/* Clear Item Info */
$(document).on("click", '#clear-btn',function() {
clearItemInfo();
});
/* Item Create Start*/
$('#create-form-btn').on("click", function() {
makeItemFormView();
});
/* Render Item Create Form */
function makeItemFormView() {
var view = '';
view = view + '<div class="row justify-content-center">';
view = view + '<div class="col-md-8 order-md-1">';
view = view + '<h4 class="mb-3">Please Input Item Infomation </h4>';
view = view + ' <form class="needs-validation" novalidate>';
view = view + ' <div class="row col-md-6 mb-3">';
view = view + ' <label for="itemName">ItemName</label> ';
view = view + ' <input type="text"class="form-control" id="itemName">';
view = view + ' </div>';
view = view + ' <div class="mb-3">';
view = view + ' <label for="itemDescription">itemDescription</label>';
view = view + ' <div class="input-group">';
view = view + ' <input type="text" class="form-control" id="itemDescription">';
view = view + ' </div>';
view = view + ' </div>';
view = view + ' <div class="row col-md-6 mb-3">';
view = view + ' <label for="makerCode">makerCode </label> ';
view = view + ' <input type="text" class="form-control" id="makerCode">';
view = view + ' </div>';
view = view + ' <div class="row col-md-6 mb-3">';
view = view + ' <label for="price">price</label> ';
view = view + ' <input type="text" class="form-control" id="price">';
view = view + ' </div>';
view = view + ' <div class="mb-3">';
view = view + ' <label for="saleStatus">saleStatus</label>';
view = view + ' <div class="input-group">';
view = view + ' <div class="form-check form-check-inline">';
view = view + ' <input class="form-check-input" type="radio" name="saleStatus" id="inlineRadio1" value="0" checked=checked>';
view = view + ' <label class="form-check-label" for="inlineRadio1">판매정지</label>';
view = view + ' </div>';
view = view + ' <div class="form-check form-check-inline">';
view = view + ' <input class="form-check-input" type="radio" name="saleStatus" id="inlineRadio2" value="1">';
view = view + ' <label class="form-check-label" for="inlineRadio2">판매중</label>';
view = view + ' </div>';
view = view + ' </div>';
view = view + ' </div>';
view = view + ' </form>';
view = view + '</div>';
view = view + '</div>';
view = view + '<div class="row form-row float-right mx-auto">';
view = view + '<button class="btn float-left btn-warning mr-3" type="button" id="create-process-btn">Create Item </button>';
view = view + '<button class="btn float-right btn-danger mr-3" type="button" id="create-cancel-btn">Cancel </button>';
view = view + '</div>';
$("#item-list").html(view);
}
$(document).on("click", '#create-process-btn' ,function() {
var itemName = $("#itemName").val();
var itemDescription = $("#itemDescription").val();
var makerCode = $("#makerCode").val();
var price = $("#price").val();
var saleStatus = $('input[name="saleStatus"]:checked').val();
var itemObj = {
"itemName":itemName,
"itemDescription":itemDescription,
"makerCode":makerCode,
"price":price,
"saleStatus":saleStatus
};
postItemData(JSON.stringify(itemObj));
});
/* Post Item Data*/
function postItemData(newItem) {
$.ajax({
url: itemApi,
method : 'POST',
contentType : 'application/json; charset=UTF-8',
data: newItem,
success : function(res){
alert(JSON.stringify(res));
clearItemInfo();
},
error: function(xhr, textStatus, error){
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
alert(error)
}
});
}
$(document).on("click", '#create-cancel-btn',function() {
clearItemInfo();
});
/* Item Update Start*/
$(document).on("click", '#update-btn' ,function() {
var itemId = $("#itemId").val();
//var itemName = $("#itemName").val();
var itemDescription = $("#itemDescription").val();
var makerCode = $("#makerCode").val();
var price = $("#price").val();
var saleStatus = $('input[name="saleStatus"]:checked').val();
// Is it change?
//var old_itemName = $("#old_itemName").val();
var old_itemDescription = $("#old_itemName").val();
var old_makerCode = $("#old_itemName").val();
var old_price = $("#old_itemName").val();
var old_saleStatus = $("#old_saleStatus").val();
if (itemName === old_itemName &&
itemDescription === old_itemDescription &&
makerCode === old_makerCode &&
price === old_price &&
saleStatus == old_saleStatus) {
return false;
}
var itemObj = {
//"itemName":itemName,
"itemDescription":itemDescription,
"makerCode":makerCode,
"price":price,
"saleStatus":saleStatus
};
putItemData(itemId, JSON.stringify(itemObj));
});
/* PUT Item Data*/
function putItemData(itemId, updateItem) {
$.ajax({
url: itemApi +'/'+itemId,
method : 'PUT',
contentType : 'application/json; charset=UTF-8',
data: updateItem,
success : function(res){
alert("Success Item Info Update "+res.itemId)
makeItemView(res);
},
error: function(xhr, textStatus, error){
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
alert(error)
}
});
}
/* Item Delete Start*/
$(document).on("click", '#delete-btn',function() {
var itemId = $("#itemId").val();
var itemName = $("#itemName").val();
var check = confirm('Do you want to delete Item info : [ '+itemName+' ]')
if (!check) {
alert('Item Delete Cancel');
return
}
deleteItemData(itemId);
});
/* PUT Item Data*/
function deleteItemData(itemId) {
$.ajax({
url: itemApi +'/'+itemId,
method : 'DELETE',
success : function(res){
alert("Success Item Info Delete "+itemId)
clearItemInfo();
},
error: function(xhr, textStatus, error){
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
alert(error)
}
});
}
2) index.jsp에 적용하기
위의 캡처처럼 <script> 태그의 src속성 값으로 Jquery코드의 경로를 기재해주면 됩니다.
5. 애플리케이션 동작확인
반응형
'프로그래밍 > Springboot-토이프로젝트' 카테고리의 다른 글
Springboot로 구현한 API의 Response 데이터를 XML로 받아오기 (0) | 2021.09.26 |
---|---|
Springboot + JQuery Ajax로 CRUD 어플리케이션 구현-05【AWS EC2에 배포 + AWS RDS(MariaDB) 연동】 (0) | 2021.06.07 |
Springboot + JQuery Ajax로 CRUD 어플리케이션 구현-03【CRUD API구현】 (0) | 2021.06.06 |
Springboot + JQuery Ajax로 CRUD 어플리케이션 구현-02【Spring boot프로젝트 설정】 (0) | 2021.06.06 |
Springboot + JQuery Ajax로 CRUD 어플리케이션 구현-01【설계】 (0) | 2021.06.05 |
댓글