비동기는 화면 갱신 없이, 즉, 새로고침없이 응답을 페이지에 노출시킬 수 있다는 특징이 있다.
그리고 새로고침없이 응답을 view에 뿌려주는 작업을 해주는 대표적인 자바스크립트 라이브러리가 Ajax이다.
Ajax 는 Asynchronous Javascript And Xml의 약자이다.
튤립국 프로팀 아약스 아니다
JavaScript를 사용한 비동기 통신, 클라이언트와 서버간에 XML 데이터를 주고받는 기술인 셈이다.
이 Ajax를 사용하는 이유는 단순히 view단에 뿌려줄 때 화면 갱신이 없어서 그런 것은 아니다.
기본적으로 비동기라는 것은 아래와 같은 장점이 있다.
필요한 부분만 불러와 사용할 수 있어 불 필요한 리소스 낭비를 줄일 수 있다.
아무튼 오늘은 이 Ajax를 이용하여 DB에 접속 및 데이터를 추가/수정하는 방법을 알아보고
추가된/변경된 데이터를 새로고침(화면 깜빡임) 없이 부분 갱신하는 방법을 알아볼 것이다.
MyBatis, Thymeleaf 기준
아래는 샘플 Ajax 형식이다.
$.ajax({
// 추가 or 수정이기에 POST
type: 'POST',
url: '/컨트롤러 매핑 경로',
data: 보낼 데이터 변수,
success: function (data) {
//Ajax 통신이 성공했을 때 쓰고 싶은 로직은 여기에
}
});
우리는 여기서 ajax 요청이 제대로 통신만 됐다면 실행시킬 로직에 조건문을 달아줄 것이다.
그 조건은 data가 1일 경우이며 임의로 data가 1일 경우에만 로직을 실행하도록 만드는 것이다.
success: function (data) {
if(data === 1){
// Controller에서 응답한 값이 1이라면, 1번 조건일 경우, 실행시키는 로직
}
}
이렇게 되면 컨트롤러에서 한번 검증을 거치고 나서 원하는 로직이 올바르게 실행됐을 경우에만 1이라는 숫자를 응답하도록 할 수 있고 자바스크립트 라이브러리인 Ajax에서 추가 로직을 진행할 수 있는 것이다.
아래는 샘플 컨트롤러이다.
@ResponseBody
@PostMapping("/경로")
public Integer 함수명(@ModelAttribute Dto클래스명 Dto참조변수) {
// 서비스의 함수를 호출했을 때 리턴값이 1번인 경우 1을 응답
if(서비스 참조변수명.서비스 함수명(Dto참조변수) == 1){
return 1;
// 서비스의 함수를 호출했을 때 리턴값이 2번인 경우 2를 응답
}else if(서비스 참조변수명.서비스 함수명(Dto참조변수) == 2){
return 2;
}else{
return null;
}
}
기본적으로 Controller는 템플릿 엔진에 기반하여 resources 폴더 밑 view 파일을 띄우는 게 일반적이다.
하지만 view를 띄우는 것이 아니라 요청을 한 바로 그 곳으로 특정 데이터 타입의 값을 그대로 응답하길 바랄 때가 있을 것이다. 특정 view 를 다시 띄우는 것이 아니라 부분갱신을 하고 싶다거나, 자바스크립트 ajax에서 다른 view로 redirect 하고 싶을 때 유용할 것이다.
아무튼 @ResponseBody라는 애노테이션을 통해 원하는 값만 응답할 수 있다.
참고로 이는 @Controller 기준이며
@RestController에서는 기본적으로 @ResponseBody가 붙어있기 때문에 해당 애노테이션이 불필요하다.
컨트롤러는 응답받은 정수에 따라 다시 호출한 Ajax에 조건에 부합하는 정수를 return 한다.
그래서 궁극적으로 1번 조건에 부합한다는 가정하에 1이라는 숫자가 return 될 것이고
1이 응답됐다면 아래 코드가 동작하게 될 것이다.
success: function (data) {
if(data === 1){
// Controller에서 응답한 값이 1이라면, 1번 조건일 경우, 실행시키는 로직
}
}
이제 추가든 수정이든 DB에 데이터를 추가/조작하는 로직을 성공적으로 실행했고 페이지에서 비동기적으로
새로고침 혹은 리로드 없이 부분적으로 갱신하는 일만 남았다.
그 방법은 놀랍게도 Ajax 안에 Ajax를 넣는 것이다.
말 그대로 처음 추가 혹은 수정 작업을 할 때의 Ajax는 그저 DB에 침투하여 원하는 작업을 하는 것이었고
원하는 작업이 성공적이었다면? 이번에는 변경된 데이터를 긁어오는 작업을 하는 것이다.
아래는 샘플 Ajax 코드이다.
if (data === 1) {
$.ajax({
type: 'GET',
url: '/경로',
success: function (data) {
$('#부분 갱신하고 싶은 DIV의 ID').replaceWith(data);
}
});
}
이제 컨트롤러를 보자.
@GetMapping("/경로")
public String 함수명(Model model) {
model.addAttribute("담을 변수", 서비스 참조변수.변경된 데이터를 가져오는 서비스 함수);
return "/HTML 이름 :: #부분 갱신하고 싶은 DIV의 ID";
}
두번째 Ajax에서 Get으로 해당 경로에 호출을 했고 해당 컨트롤러에서 변경된 데이터를 긁어오는 함수를 호출했으니
그 함수가 올바르게 작동했다면 변경된 데이터를 응답받아
key:value로 동작하는 model.addAttribute라는 메소드를 통해
지정한 변수(key)에 가져온 데이터(value)를 삽입하고
그 변수를 return하는 HTML 의 선택된 부분으로 쏴주게 되고
그 부분에서 데이터를 모두 담은 변수를 반복문을 통해 순차적으로 풀어주면?
HTML 에 선택된 부분만 새로고침 없이 갱신되는 것이다.
눈여겨볼 것은 HTML 이름 다음 :: 인데 이렇게 return 할 경우 해당 html의 특정 부분으로만 return 되는 것을 알 수 있고 Ajax에서 그 data를 받아와서 추가적으로 그 데이터를 아래처럼 특정 DIV에 갈아끼우는 것이다.
$('#부분 갱신하고 싶은 DIV의 ID').replaceWith(data);
아래는 기본적인 부트스트랩 테이블을 기준으로 변경된 데이터가 담긴 변수를 어떻게 뿌려주는지와