AJAX
AJAX
기본 화면은 정적으로 특정 부분만 내용 변경 및 확장되는 비동기식 방식
AJAX(Asynchronous Javascript And Xml)
-
동기화 통신 방식(synchronous)
요청->서버 html태그를 포함한 새로운 화면으로 응답->요청2 ->서버 html태그를 포함한 새로운 화면으로 응답2
- 이같은 방식은 display 화면이 늘 새로 만들어져야 함
요청1 - 요청2 - 응답2 - 응답1의 방식이 가능하다면? Controller에게 결과를 받고, 그 결과만을 넣어줘 기존 화면에 확장만 할 수 있다면?
- 비동기방식, AJAX(Asynchronous Javascript And Xml)
- 화면 구성과 서버 요청 처리 결과가 구성되어있는 파일에 내용만 동적으로 바꾸는 방식
- display는 display대로, 요청은 요청대로 처리하는 방식. 요청의 결과물을 받아서 현재 응답화면을 변경한다.
- 이 경우 Controller에서 return하는 것은 view가 아닌 처리결과 태그, JSON이 된다.
JSON(JavaScriptObjectNotation)
Javascript가 Spring으로 넘어오는 경우 해당 언어가 JS인지 인지를 못한다. 이에 따라 다른 언어에서 호환성을 위해 약속한 것이 바로 JSON
-
JSON형태
{“valuename”:”value”, “valuename”: 10, }
javascript와 html이 단일따옴표와 이중따옴표 둘 다 사용 가능하다면, JSON은 반드시 이중따옴표로 구분한다. (int 타입은 제외)
- Controller는 return을 json 형태로 return
- Stringtype으로 return되기 때문에 JSON의 이중따옴표(“ “) 앞에\를 추가
- AJAX의 경우 클라이언트와 서버 양쪽 다 지원해야 그 결과를 볼 수 있다.
- 기존의 display내부에서 서버에서 처리된 결과를 AJAX로 보내면 화면에 추가한다.
- 이 때 주고받는 데이터는 이전에 xml방식을 사용하였으나, 이것이 JSON으로 변경된 것
- Controller는 return을 json 형태로 return
사용 환경설정
-
client
-
html태그 안에서는 AJAX의 요청방식을 받을 수 없다.
-
javascript/jquery를 통해 요청한다. (스크립트 태그 내부)
$.ajax({..});
-
-
server(Spring mvc의 경우)
-
json 인식, 적용하기 위한 라이브러리 설치(pom.xml)
<!-- ajax , json --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.3</version> </dependency>
- 위 라이브러리같은 경우 return타입으로 객체를 보내는 경우, 자동으로 JSON으로 변경해주는 기능이 있다. (ex. VO자바객체를 JSON으로 자동변경)
-
@ResponseBody/@RequestBody annotation 필수
@ResponseBody : 응답을 JSON으로 보내는 경우
@RequestBody : 요청을 JSON으로 보내는 경우
-
예제 살펴보기
Controller
ackage ajax;
import java.util.ArrayList;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginAjaxController {
@RequestMapping(value="/ajax/login", method=RequestMethod.GET)
public String loginform() {//form 출력(http요청)
return "/ajax/loginajax"; //뷰이름
}
@RequestMapping(value="/ajax/login", method=RequestMethod.POST, produces = {"application/json;charset=utf-8"})
@ResponseBody
//{"id":$("#id").val(), "pw":$("#pw").val()}
public String loginresult(String id, String pw) {//form 입력, 데이터 전송 ajax요청
String result=null;
if(id.equals("spring") && pw.equals("spring")) {
result = "{\"process\":\"정상로그인\", \"role\":\"admin\"}";
//변수명 process, 값 String"정상로그인"
}else {
result = "{\"process\":\"비정상로그인\", \"role\":\"user\"}";
}
return result;
}//loginresult end
/* @RequestMapping("/ajax/board")
@ResponseBody
public BoardDTO getBoardDTO(int seq) {
BoardDTO dto = new BoardDTO();
dto.setSeq(seq);
dto.setTitle("게시물제목");
dto.setContents("게시물내용");
dto.setWriter("작성자");
dto.setViewcount(100);
return dto;//json형태 변경하여 Return
}*/
// /ajax/board/1 - url 내부값 사용, 처리
@RequestMapping("/ajax/board/{seq}")//{seq}들어간 값을 seq라는 변수로 name
@ResponseBody //return : 뷰이름이 아닌 json, 자동으로 변환
public BoardDTO getBoardDTO(@PathVariable("seq") int seq) {//url의 변수를 int seq로 사용
BoardDTO dto = new BoardDTO();
dto.setSeq(seq);
dto.setTitle("게시물제목");
dto.setContents("게시물내용");
dto.setWriter("작성자");
dto.setViewcount(100);
return dto;//json형태 변경하여 Return
}
@RequestMapping("/ajax/boardlist")
@ResponseBody //return : 뷰이름이 아닌 json, 자동으로 변환
public ArrayList<BoardDTO> getBoardDTO() {
BoardDTO dto = new BoardDTO();
ArrayList<BoardDTO> list = new ArrayList<BoardDTO>();
dto.setSeq(1);
dto.setTitle("게시물제목");
dto.setContents("게시물내용");
dto.setWriter("작성자");
dto.setViewcount(100);
list.add(dto);
list.add(dto);
list.add(dto);
list.add(dto);
list.add(dto);
list.add(dto);
return list;//json형태 변경하여 Return
}
@RequestMapping(value="/ajax/login", method=RequestMethod.POST, produces = {"application/json;charset=utf-8"})
@ResponseBody
produces = {“application/json;charset=utf-8”}: jquery가 다시 요청을 보내기 때문에 한글 셋팅을 설정해준다.
@ResponseBody 어노테이션이 없다면 자동으로 view가 리턴된다.
@RequestMapping("/ajax/board/{seq}")//{seq}들어간 값을 seq라는 변수로 name
@ResponseBody
public BoardDTO getBoardDTO(@PathVariable("seq") int seq) {//url의 변수를 int seq로 사용
@RequestMapping(“/ajax/board/{seq}”): 해당 url에 들어간 값을 seq라는 변수이름으로 사용
@PathVariable(“seq”): url의 seq의 이름을 가진 변수값을 매개변수값으로 넣어준다 (이름이 모두 같아야 함)
: url에 들어가는 형식, 파라미터값으로 일치시킬 수 있음.(글번호 활용)
loginajax.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">
<title>Insert title here</title>
<script src = "<%=request.getContextPath() %>/resources/jquery-3.2.1.min.js"></script>
<script>
$(document).ready(function(){
$("#login").on('click', function(){
$.ajax({ //login을누르면 a.jax가 실행
url: "<%=request.getContextPath()%>/ajax/login",
data: {"id":$("#id").val(), "pw":$("#pw").val()}, //전송했던파라미터 이름이 id, data라는 변수에 들어감
type: 'post',
dataType: 'json',
//함수의매개변수는 server로부터 받아온 변수
success: function(server){ //server = "{\"process\":\"정상로그인\"}"
alert(server.process);
$("#result").html(server.role);
if(server.process == '정상로그인'){
$("#result").css("color", "blue");
}else{
$("#result").css("color", "red");
}
}
});//ajax 요청함
});//on end
<%--/* $("#board").on('click', function(){
// $("#result").html("테스트완료");
$.ajax({ //login을누르면 a.jax가 실행
url: "<%=request.getContextPath()%>/ajax/board",
data: {"seq":$("#seq").val()}, //전송했던파라미터 이름이 id, data라는 변수에 들어감
type: 'get',
dataType: 'json',
//함수의매개변수는 server로부터 받아온 변수
success: function(server){ //server = "BoardDTO를 JSON으로 변경 자동"
$("#result2").append(server.seq+"<br>");
$("#result2").append(server.title+"<br>");
$("#result2").append(server.contents+"<br>");
$("#result2").append(server.writer+"<br>");
$("#result2").append(server.viewcount+"<br>");
}
});//ajax 요청함
});//on end
*/--%>
$("#board").on('click', function(){
// $("#result").html("테스트완료");
$.ajax({ //login을누르면 a.jax가 실행
url: "<%=request.getContextPath()%>/ajax/board/" + $("#seq").val(),
type: 'get',
dataType: 'json',
success: function(server){
$("#result2").append(server.seq+"<br>");
$("#result2").append(server.title+"<br>");
$("#result2").append(server.contents+"<br>");
$("#result2").append(server.writer+"<br>");
$("#result2").append(server.viewcount+"<br>");
}
});//ajax 요청함
});//on end
$("#boardlist").on('click', function(){
// $("#result").html("테스트완료");
$.ajax({ //login을누르면 a.jax가 실행
url: "<%=request.getContextPath()%>/ajax/boardlist",
type: 'get',
dataType: 'json',
//함수의매개변수는 server로부터 받아온 변수
success: function(server){ //server = ArrayList<BoardDTO>를 Json은 배열로 자동 변경
// [{seq:1, title:"", }, {}, {}, {}, {}]
for(var i in server){
$("#result3").append("<div style='border:2px solid pink'>"+server[i].seq+"<br>");
$("#result3").append(server[i].title+"<br>");
$("#result3").append(server[i].contents+"<br>");
$("#result3").append(server[i].writer+"<br>");
$("#result3").append(server[i].viewcount+"<br></div>");
}
}
});//ajax 요청함
});//on end
});
</script>
</head>
<body>
<h1>ajax Login Form</h1>
<form>
<!-- 서버로 전송 - name속성= request.getParameter("id")
jquery 전송 - id속성 = $("#id")
-->
아이디<input type=text name="id" id="id"><br>
암호<input type=password name="pw" id="pw"><br>
</form>
<button id="login">ajax login</button>
<div id="result"></div>
<input type=text id="seq"><button id="board">번 글 요청</button>
<div id=result2></div>
<button id="boardlist">모든 글 요청</button>
<div id=result3></div>
</body>
</html>
$.ajax({
url: "<%=request.getContextPath()%>/ajax/login",
data: {"id":$("#id").val(), "pw":$("#pw").val()},
//전송했던파라미터 이름이 id, data라는 변수에 들어감
type: 'post',
dataType: 'json',
//함수의매개변수는 server로부터 받아온 변수
success: function(server){ //server = "{\"process\":\"정상로그인\"}"
alert(server.process);
$("#result").html(server.role);
if(server.process == '정상로그인'){
$("#result").css("color", "blue");
}else{
$("#result").css("color", "red");
}
}
});
Controller에서 받은 값을 처리해주는 ajax 요청문
$.ajax({
url: 매핑할 url정보,
data: {parameter이름:변수값, parameter이름:변수값},
//해당 변수값을 Controller의 동일 parameter이름 값으로 보냄
type: 메소드 타입(ex'post')
dataType:'json'
success: function(server){ //위의 값을 Controller로 전송시켜서 해당 처리 값을 가져왔을 경우
//function의 매개변수는 Controller(server)로부터 받아 온 변수
server.process //서버 값 받아오기, 호출
}
});
- 분리 ,(콤마) 필수
- function의 매개변수는 Controller(server)로부터 받아 온 변수
- 매개변수이름.Controller에서 보낸 변수값이름 (server.process)
-
ajax 전용 Controller 생성하기
-
AJAX 요청 처리 전용 컨트롤러 생성 가능
@RestController : /Ajax 요청 처리 전용 Controller
package ajax; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController//Ajax 요청 처리 전용 Controller public class AllAjaxController { @RequestMapping("/a") public BoardDTO a() { return new BoardDTO(); } @RequestMapping("/b") public String b() { return ""; } @RequestMapping("/c") public Integer c() { return 0; } }
-