본문 바로가기
Lecture/JSP & Java

[본격 게시판짜기 Part3.1 Spring MVC] Ajax란?

by cusmaker 2012. 7. 31.
반응형

2012/06/13 - [Lecture/HTML] - [본격 게시판짜기 Part1.1 - 게시판도 HTML부터] 게시글 리스트

2012/06/13 - [Lecture/HTML] - [본격 게시판짜기 Part1.2 - 게시판도 HTML부터] 글입력폼

2012/06/13 - [Lecture/Javascript-기초] - [본격 게시판짜기 Part1.3 - Dom 맛보기 ] 글입력폼 검사

2012/06/13 - [Lecture/Jsp] - [본격 게시판짜기 Part1.4 - HTML-> JSP] form 파라미터 받기

2012/06/26 - [Lecture/SQL / Oracle] - [본격 게시판짜기 Part1.5 JSP > Oracle] 게시판 DB 테이블 생성

2012/06/26 - [Lecture/Jsp] - [본격 게시판짜기 Part1.6 Oracle > JSP] Database 접속 및 Select

2012/07/05 - [Lecture/Jsp] - [본격 게시판짜기 Part1.7 JSP, SQLDeveloper] 게시글 입력 및 리스트조회기능

2012/07/08 - [Lecture/Jsp] - [본격 게시판짜기 Part1.8 JSP 게시글 조회] 게시글 조회기능 및 게시글 삭제

2012/07/10 - [Lecture/Jsp] - [본격 게시판짜기 Part2.1 Model2 MVC패턴] 뷰(View) 코드 분리

2012/07/10 - [Lecture/Jsp] - [본격 게시판짜기 Part2.2 Model2 MVC패턴] Entity Beans의 사용

2012/07/12 - [Lecture/Jsp] - [본격 게시판짜기 Part2.3 Model2 MVC패턴] Controller구성

2012/07/13 - [Lecture/Jsp] - [본격 게시판짜기 Part2.4 Model2 MVC패턴] Model 구성

2012/07/16 - [Lecture/Mybatis] - [본격 게시판짜기 Part2.5 Model2 MVC패턴] Model 구성2 - i-batis의 사용

2012/07/17 - [Lecture/Mybatis] - [본격 게시판짜기 Part2.6 Model2 MVC패턴] Model 구성2 - i-batis의 사용2

2012/07/21 - [Lecture/Mybatis] - [본격 게시판짜기 Part2.7 Model2 MVC패턴] i-batis의 queryForList 활용 Paging기능구현

2012/07/22 - [Lecture/Jsp] - [본격 게시판짜기 Part2.8 Model2 MVC패턴] count기능추가

2012/07/28 - [Lecture/Jsp] - [본격 게시판짜기 Part2.9 Model2 MVC패턴] 파일업로드 기능추가

2012/07/28 - [Lecture/Jsp] - [본격 게시판짜기 Part2.10 Model2 MVC패턴] 파일다운로드/삭제 기능추가


안녕하세요 cocy입니다.

어느덧 포스팅도 이제 마지막 파트로 접어들었는데요,

이번 파트에서는 지금껏 짜온 게시판을 좀더 품격있는 게시판으로 업그레이드 하고,

퀄리티를 높여보도록 하겠습니다.

지금까지 작업하신 소스는 네이버 개발자센터 svn 주소

https://dev.naver.com/svn/board1/board2/board2

id/pw : anonsvn / anonsvn

에서 받으실 수 있습니다.


네이버 SVN서비스가 종료되어 늦었지만 지금이라도 github으로 대체합니다. 

github : https://github.com/zuhthebeg/board2


게시판의 테이블 스키마도 올려드립니다. 



준비가 되셨으면 기능구현에 앞서,

어떻게 무엇을 구현할 것인지 간략히 설명드리겠습니다.

저희가 mvc로 여지껏 개발한 게시판은 각 기능들이 동작하기위해서는 페이지의 전환이 필요했습니다.

리스트에서 글쓰기를 하려면 페이지가 이동되었고,

게시글을 조회하려해도 조회페이지로 이동해야했습니다.

하지만 이것들을 한페이지내에서 동적으로 작동하게 할 순 없을까요?


게시글 리스트에서 글쓰기를 할때, 페이지전환없이 글쓰기 폼이 나오고,

해당 게시글을 누르면 밑에 게시글 내용이 펼쳐지고,

펼쳐진 게시글에서 수정이나 삭제가 그자리에서 바로 이루어질수있게,,,

마치 웹프로그램이 아닌 일반 어플리케이션을 보는것과같은 사용자경험

바로 RIA(Rich Internet Application)의 시작입니다.


이러한 기술들이 가능하기 위해서 사용되는 것이 바로 AJAX(Asynchronous Javascript and XML) 입니다.

풀어 설명하면 Javascript를 사용한 비동기 통신, 클라이언트(브라우저)와 서버(웹서버)간에 XML 데이터를 주고 받는 기술입니다.


기존의 방식과의 차이점을 그림을 통해 설명해보자면,


그림1. 기존 MVC패턴의 웹페이지 동작방식 


기존의 MVC패턴의 동장방식은 그림과같이 

요청페이지에서 요청을 날리면 

웹서버가 그에맞는 데이터와 jsp페이지를 

재구성하여 요청이 끝나고 결과페이지를 리턴하면

사용자측에서는 페이지가 전환되면서 요청에대한 응답페이지를 보게됩니다.


이에반해 Ajax기술을 사용하면


그림2. AJAX 기술을 사용한 비동기식 요청


그림과같이 요청페이지에서 자바스크립트를 활용하여 

웹서버에 비동기요청을 날립니다.

그리하면 웹서버에서는 이요청을 토대로 필요한 데이터들을 응답하는데

이때 자바스크립트에서 해당응답을 다시 받아서 돌아온 데이터들을

XML형태, Json형태나 일반 텍스트형식의 데이터로 받아서

요청페이지의 DOM을 조작하여 데이터를 추가하는것으로

요청페이지의 전환없이 요청/응답이 끝나게 됩니다.


쉽게말해서 Ajax란 페이지전환없는 웹 동작방식 이라는 겁니다.


저희가 응답받을 텍스트는 XML이나 JSON을 제외하고 

우선 일반텍스트를 활용하여 구현하겠습니다.

그리고 간단한 구현을 위해 jQuery를 활용하도록 하겠습니다.

jQuery에 관한 내용은 다른 포스팅을 참고하세요.


그럼 이제 본격적으로 코딩에 들어가기 앞서,

수정할 기능을 정의해보겠습니다.


우선 리스트에서 페이징방식을 바꿔보도록 하겠습니다.

다음페이지의 게시글을 불러올때,

다음게시글페이지를 표시하는게 아니라,

기존의 게시글 밑에 붙이는(append) 방식으로 진행해 보도록 하겠습니다.

보실 부분은 list.jsp페이지입니다.

일단 jquery를 사용하기위해

상단에 해드태그 끝나기전에 다음 구문을 추가해주세요

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>

.

.

.

  </table>

<div id="append_article">

</div>

<c:if test="${page > 0}"> 

<a href="list.do?page=${page-10}">이전페이지</a> 

</c:if>

<c:if test="${page == 0}"> 

<a href="#">이전페이지</a> 

</c:if>

<fmt:parseNumber value="${page/10+1 }" type="number"  integerOnly="True" /> 페이지 

<c:if test="${fn:length( articleList ) == 10}"> 

<a href="#" onclick="loadNextPage('${page+10}')">다음페이지</a>

</c:if>

<script>

function loadNextPage(page){

var param = "page="+page;

$('#append_article').load("list.do", param, function(data){

alert(data);

});

}

</script>

<br/><a href="write.jsp">글쓰기</a>


이후 결과를 넣을 div태그를 넣어주시고 id를 적습니다.

다음페이지를 호출하는 a태그 부분의 href를 #으로 넣고 

스크립트 함수를 걸어 해당 함수가 실행되게 합니다.

해당 함수에서는 페이지를 파라미터로 받고 

jquery의 selector를 이용해 위에 만든 div태그를 선택한뒤 load함수를 실행합니다.

load함수의 인자값은 다음과같습니다.

1 : 요청 URL

2 : 파라미터 - ?을 제외한 get방식을 취합니다. ex) page=page&idx=idx

3 : 응답 function - 응답이 완료된뒤에 실행될 함수를 등록합니다.


세번째 인자값으로 응답 함수에

요청이 완료되어 돌아온 값을 alert함수를 통해 출력하고 있습니다.

한번 실행해보시고 잘 돌아가는지 확인해보시기바랍니다.



그림 3. jquery load함수 실행결과


load함수는 jquery에서 내부적으로 ajax요청이 구현되어있는 함수입니다.

보시는바와같이 결과값은 해당 url의 요청이 끝나고 반환되는 jsp페이지의 내용이 그대로 출력되는걸 보실 수가 있는데요,

저희가 원하는 결과는 이런것이 아니죠?


jsp전체 페이지 소스가 아니라 데이터만 가져오면,

요청에 부하도 덜할테고 깔끔해지겠습니다.

테이블도 하나가 더생기는것이 아니라 

한 테이블 내에 데이터만 추가하도록 하죠.


이를위해 ajax 요청에 대비한 Action을 따로 만들도록 하겠습니다.

url 이름은 ajaxList.do 

클래스명은 AjaxLIstAction으로 하겠습니다.



그림 4. AjaxListAction.java, ajaxList.jsp 추가 

먼저 Command.properties에 맵핑정보를 기술해주고,

AjaxListAction.java를 추가해 주었습니다. ListAction과 매우 유사하기에 복사한뒤 수정하였는데요, 차이점을 한번 보세요

그리고 데이터를 리턴할 페이지 ajaxList.jsp를 추가해주었습니다.

기존에 list.jsp페이지에 append 될 내용이기때문에 내용은 매우 심플하게 작성되었습니다.


이제 list.jsp를 보시면 기존의 소스와 많이 달라졌는데요,

기존의 페이징기능 대신 밑에 게시글이 달리는 형식이므로 "더보기" 라고 바꿔보았습니다.

페이징기능도 더이상 없기때문에 지저분했던 c:if 구문들과 이전페이지 기능이 사라졌구요,

그 대신에 주목해야하실부분이 

<input type="hidden" name="page" id="page" value="${page}" />

이 부분입니다.

페이지값을 저장할 input태그를 선언하고 히든값으로 준 이유는,

페이지가 불러와졋을때 페이지에 살아있는 page값은 페이지가 최초 로딩될때의 값입니다.

그러므로 ajax요청이 끝나면 페이지값의 변화가 필요한데 

요청시에는 jquery를 통해 page input태그에 접근하여 해당 input태그로부터 값을 불러와 요청을 하고, 

페이지가 로드되고 게시글들이 테이블에 append된 이후에 이때 page의 값을

마찬가지로 jquery를 통해 page input태그에 접근하여 값을 갱신해줍니다.

이로써 다음 게시글을 계속하여 불러올때도 page의 값이 10이 더해져 정상적인 리스트를 출력하게 됩니다.


그리고 이번에 사용된 함수는 load함수가 아닌 jquery 에서 ajax를 쉽게 사용할 수 있도록 구현된 ajax함수인데요,

사용법은 load함수와 거의 동일합니다.



그림5. jquery의 ajax를 활용한 비동기식 더보기기능 구현 완료


이번 포스팅은 아무래도 기술적인 부분이 많이 들어가다보니,

설명이 시원치 않은 부분이 있습니다.

따라하시다가 궁금하신 사항이 있으면 바로바로 질문주시고,

jquery나 javascript의 문법에 관해서는 이쪽에서는 깊게 들어가지않으니,

타 포스팅을 참고해주세요 :)


수고하셨습니다.


다음장으로 >> http://cusmaker.tistory.com/122