[Ajax] 비동기 처리 - call back 함수
회원의 아이디가 존재하는지 확인하기 & 게시물의 인덱스 입력하면 게시물 정보 알림창에 띄우기
그동안 계속 헷갈렸던 동기와 비동기 확실히 정리하고 넘어가기!!!
동기 synchronous
서버에 요청을 보내면 그 응답이 올 때까지 다음 작업으로 넘어가지 못한다. 즉, 요청과 결과가 동시에 주어진다.
간단하고 직관적이지만, 응답이 올 때까지 아무것도 못하고 계속 대기해야 한다.
비동기 Asynchronous
한 요청에 대해 응답이 오지 않아도 다음 작업을 수행할 수 있다. 즉, 요청과 결과가 동시에 주어지지 않는다.
구조가 복잡하지만, 응답이 주어질 동안 다른 작업을 수행할 수 있다.
call back 함수 (ex success, error ...)
비동기 코드 안에 함수를 넣어 동기적으로 처리할 수 있게 한다.
비동기 처리로 인해 발생할 수 있는 문제들을 콜백 함수로 해결.
데이터를 받아오기 전에 먼저 return해버리는 것을 방지한다.
test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JS Test</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#btn_checkId').on('click', function() {
let user_id = $('#user_id').val();
$.ajax({
url: './checkID',
type: 'get',
data: {'user_id': user_id},
success: function(data) {
alert(data);
},
error: function() {
alert('error');
},
complete: function() {
alert('complete');
}
});
});
$('#btn_findBoard').on('click', function() {
let seq = $('#seq').val();
$.ajax({
url: './searchAjax.do',
type: 'get',
data: {'seq':seq},
success: function(data) {
let obj = JSON.stringify(data);
alert(obj);
alert(data.seq)
},
error: function() {
alert('error');
}
});
});
});
</script>
</head>
<body>
<input type='text' name='user_id' id='user_id'>
<button id='btn_checkId'>ID Check</button>
<br>
<input type='text' name='seq' id='seq'>
<button id='btn_findBoard'>Find Board</button>
</body>
</html>
btn_findBoard 버튼 (게시물 인덱스로 게시물 정보 띄우는 버튼) 의 ajax 코드를 보자.
텍스트창에 입력된 seq를 Controller에 data속성을 통해 보낸다.
그리고 JSON 형태로 받아온 vo 객체를 stringify 메소드를 통해 문자열로 변환하여 alert창에 띄운다.
*stringify() : JavaScript 값이나 객체를 문자열로 변환
*JSON: JavaScript Object Notation. 서버와 클라이언트 간 사용되는 데이터 교환 포맷.
BoardController.java
@ResponseBody // 페이지 이동 못하게. 비동기 통신시 사용
@RequestMapping(value="/checkID",method = RequestMethod.GET)
public String ajaxCheckID(@RequestParam("user_id") String id) {
String result = null;
//DB처리 (Service-DAO-Table)
boolean flag = boardService.findId(id);
result = String.valueOf(flag);
System.out.println(id);
return result;
}
@ResponseBody
@RequestMapping(value="/searchAjax.do", method=RequestMethod.GET)
public BoardVO search(@RequestParam("seq") int seq) {
System.out.println(seq);
// jackson-core, jackson-databind 의존성 추가하면 자동으로 json 변환
BoardVO board = boardService.findItem(seq);
return board;
}
@ResponseBody
비동기 통신 시 사용하는 어노테이션. 페이지가 아닌 리턴값 그대로를 리턴한다.
JAVA 객체를 JSON 객체로 변환하여 클라이언트로 넘겨준다.
BoardService.java -> 기존 코드에서 findId 메소드만 추가
public BoardVO findItem(int seq) {
// TODO Auto-generated method stub
BoardVO board = null;
try {
//조회수 증가 수정
boardDAO.updateCount(seq);
board = boardDAO.selectItem(seq);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return board;
}
public boolean findId(String id) {
boolean result = false;
result = boardDAO.selectId(id);
return result;
}
BoardDAO.java
public BoardVO selectItem(int seq) throws SQLException {
BoardVO board = null;
board = sqlSession.selectOne("mapper.board.findBoard", seq);
return board;
}
public boolean selectId(String id) {
boolean result = false;
MemberVO member = sqlSession.selectOne("mapper.member.selectId", id);
if(member != null) {
result = true;
}
return result;
}
modelConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="bitedu.lesson.simple.vo.BoardVO" alias="boardVO" />
<typeAlias type="bitedu.lesson.simple.vo.MemberVO" alias="memberVO" />
</typeAliases>
</configuration>
board.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.board">
<!---->
<resultMap id="boardResult" type="BoardVO">
<result property="seq" column="seq" />
<result property="title" column="title" />
<result property="content" column="content" />
<result property="writer" column="writer" />
<result property="readCount" column="read_count" />
<result property="createDate" column="create_date" />
<result property="attatchImg" column="attatch_img" />
<result property="attatchData" column="attatch_data" />
</resultMap>
<select id="findBoard" resultMap="boardResult" resultType="boardVO" parameterType="java.lang.Integer" >
<![CDATA[
select * from simple_board
where
seq=#{seq}
]]>
</select>
</mapper>
member.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.member">
<!---->
<resultMap id="memberResult" type="MemberVO">
<result property="id" column="id" />
<result property="pwd" column="pwd" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="registDate" column="regist_date" />
</resultMap>
<select id="selectId" resultMap="memberResult" parameterType="java.lang.String" resultType="memberVO">
<![CDATA[
select * from member where id=#{id}
]]>
</select>
</mapper>