AJAX(Asynchronous JavaScript and XML)์ ์ฌ๋ฌ ์ํฉ์์ ์ฌ์ฉ๋๋๋ฐ... ๋งค๋ฒ ์ฌ์ฉํ ๋๋ง๋ค ์ด๋ป๊ฒํ๋์ง ๊ฒ์ํ๊ณ ์ ๋จน๋๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
๊ทธ๋์, ์ด ๊ธ๋ง ๋ณด๊ณ ์๋ฒฝํ๊ฒ ๋ค์ ์ฌ์ฉํ ์ ์๋๋ก ์ ๋ฆฌํด๋ณผ๋ ค๊ณ ํ๋ค.
AJAX๋ ๋จ์ํ ํ ์คํธ๊ฐ๋ง ๋๊ธธ์๋ ์๊ณ , form์ ๋๊ธธ์๋ ์๊ณ , ํ์ผ ์ ๋ก๋์ ๊ฐ์ด ์น๊ฐ๋ฐ์์ ์ค์ํ ์ญํ ์ ํด์ฃผ๊ธฐ๋๋ฌธ์....
AJAX๋ง ์ ์์๋ ๊ฐ๋ฐํ๋๋ฐ ์๊ฐ๋จ์ถ์ด ๋๋ค.
AJAX๋ ๋น๋๊ธฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฑฐ๋ผ๊ณ ํ๋ค.
์ฝ๊ฒ ๋งํ๋ฉด ๊ทธ๋ฅ ๋ธ๋ผ์ฐ์ ์์ ์๋ก๊ณ ์นจํ์ง ์๊ณ ๋ ๋ฐ์ดํฐ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ๊ฒ์ด๋ค.
๋ํ์ ์ผ๋ก AJAX๊ฐ ์ฌ์ฉ๋ ์ฌ๋ก๋ ๊ฐ์ข ํฌํธ์ฌ์ดํธ์ ์ธ๊ธฐ๊ฒ์์ด ํน์ ์ฐ๊ด๊ฒ์์ด์ด๋ค.
๊ทธ๋ผ ์ ํ๋ณ๋ก ํ๋์ฉ ์จ๋ณด์.
AJAX๋ฐ์ดํฐ๋ฅผ ๋ด์ Jamong DTO ํด๋์ค
public class Jamong {
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
1. ๊ธฐ๋ณธ
AJAX์ ์ต์ํ ํํ์ด๋ค.
data๋ฅผ ์ ์กํด์ ํ์ํ ๋ก์ง๋ค์ ์ฒ๋ฆฌํ๊ณ ๊ฐ์ returnํ๋ค.
์ฌ๊ธฐ์ @ResponseBody์ ์ญํ ์ ์์์ผํ๋๋ฐ,
@RequestMapping์ผ๋ก String type์ ๋ฐํํด์ฃผ๋ฉด, ViewResolver์์ ์ ์ํ prefix์ suffix๊ฐ return๊ฐ์ ์ถ๊ฐ๋์ด view๋ก ์ด๋์ด ๋๋ค.
@ResponseBody๋ฅผ ์ฌ์ฉํด์ฃผ๋ฉด view๋ฅผ ์์ฑํด์ฃผ๋๊ฒ์ด ์๋๋ผ, JSON ํน์ Object ํํ๋ก ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ค๋ค.
-Client
$('#btn1').on('click', function(){
var form = {
name: "jamong",
age: 23
}
$.ajax({
url: "requestObject",
type: "POST",
data: form,
success: function(data){
$('#result').text(data);
},
error: function(){
alert("simpleWithObject err");
}
});
});
-Server
@RequestMapping(value="/requestObject", method=RequestMethod.POST)
@ResponseBody
public String simpleWithObject(Jamong jamong) {
//ํ์ํ ๋ก์ง ์ฒ๋ฆฌ
return jamong.getName() + jamong.getAge();
}
-View
<body>
<button id="btn1">simpleAJAX</button>
<div id="result"></div>
</body>
2. ํผ ํ๋ผ๋ฏธํฐ ๋๊ธฐ๊ธฐ
ํผ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋๊ธฐ๊ธฐ ์ํด serialize() ํจ์๋ฅผ ์ฌ์ฉํ๋ค.
ํ์ํ ๋ก์ง ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ๋ง์ฐฌ๊ฐ์ง๋ก @ResponseBody Annotation์ ์ฌ์ฉํ์ฌ Objectํํ๋ก ๋๊ธด๋ค.
-Client
$('#btn2').on('click', function(){
$.ajax({
url: "serialize",
type: "POST",
data: $("#frm").serialize(),
success: function(data){
$('#result').text(data);
},
error: function(){
alert("serialize err");
}
});
});
-Server
@RequestMapping(value="/serialize", method=RequestMethod.POST)
@ResponseBody
public String serialize(Jamong jamong) {
//ํ์ํ ๋ก์ง ์ฒ๋ฆฌ
return jamong.getName() + jamong.getAge();
}
-View
<body>
<form id="frm">
name : <input type="text" name="name" id="name"><br>
age : <input type="text" name="age" id="age">
</form>
<button id="btn2">serialize</button>
<div id="result"></div>
</body>
3. JSON.stringify()
AJAX์๋ dataType์ด๋ผ๋ ์ต์ ์ด ์๋ค. ์ค์ ์ ์ํด์ฃผ๋ฉด MIMEํ์ ์ ์ํด ์๋์ผ๋ก ์ค์ ์ด๋๋ค.
๊ทธ๋ฐ๋ฐ ๋๋ JSONํํ๋ก ๋ณด๋ด๊ณ ์ถ๋ค.
AJAX๋ฅผ ์ฌ์ฉํ๋ ์์๋ฅผ ๋ณด๋ฉด JSON.stringify() ํจ์๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค.
์ด ํจ์๋ JSONํ์ ์ String ๊ฐ์ฒด๋ก ๋ณํ์์ผ์ฃผ๋ ์ญํ ์ ํ๋ค.
์๋ฒ์ชฝ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋๊ธธ๋, String๊ฐ์ฒด๋ก ๋ณํ์์ผ์ฃผ๊ธฐ ์์ผ๋ฉด URL์ get ํ๋ผ๋ฏธํฐ ํ์(?a=1&b=2)์ฒ๋ผ ๋๊ฒจ๋ฒ๋ฆฐ๋ค.
์... ๊ทผ๋ฐ... stringifyํจ์๋ฅผ ๊ทธ๋ฅ ์ฌ์ฉํ๊ฒ๋๋ฉด 415์๋ฌ๊ฐ๋ฌ๋ค.
์ด๋ถ๋ถ์์ ํ์๋ ๊ต์ฅํ ์ฝ์ง์ ํ๋๋ฐ.... jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ค์ผํ๋ค.
์๋ฒ์ชฝ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐ๋ฉด์ ๋ฌด์จ ๋ณํ์์ ์ ํด์ฃผ๋๊ฒ ๊ฐ์๋ฐ, ์ถ๊ฐ์ํด์ฃผ๋ฉด 415์๋ฌ๊ฐ ๋ฌ๋ค.
pom.xmlํ์ผ์ ์ถ๊ฐํด์ค๋ค.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
์ฝ๋๋ฅผ ๋ณด๊ธฐ ์ด์ ์ ์ด๋ฒ์๋ @RequestBody์ ๋ํด์ ์์์ผํ๋ค.
ํด๋ผ์ด์ธํธ์ชฝ์์ ๋ฐ์ดํฐ ํํ๋ฅผ JSON์ผ๋ก ๋ณด๋ด์ฃผ๋ฉด, ์๋ฒ์ชฝ์์๋ JSON์ผ๋ก ๋ฐ์์ค์ผํ๋ค.
JSONํํ๋ก ๋ฐ๊ฒํด์ฃผ๋ Annotation์ด @RequestBody์ด๋ค.
-Client
$('#btn3').on('click', function(){
var form = {
name: "jamong",
age: 23
}
$.ajax({
url: " stringify",
type: "POST",
data: JSON.stringify(form),
contentType: "application/json; charset=utf-8;",
dataType: "json",
success: function(data){
var txt = data.name + data.age;
$('#result').text(txt);
},
error: function(){
alert("stringify err");
}
});
});
-Server
@RequestMapping(value="/stringify", method=RequestMethod.POST)
@ResponseBody
public Object stringify(@RequestBody Jamong jamong) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name", jamong.getName());
map.put("age", jamong.getAge());
return map;
}
-View
<body>
<button id="btn3">stringify</button>
<div id="result"></div>
</body>
4. @RestController
๋ค์์ @Controller๊ฐ ์๋ @RestController์์ JSONํ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์๊ฑฐ๋ค.
@RestController Annotation์ ์ฌ์ฉํ๋ฉด, @ResponseBody Annotation์ ๋นผ๊ณ ์ฌ์ฉํ๋ฉด๋๋ค.
@RestController๊ฐ ์์์ JSONํํ๋ก returnํด์ค๋ค.
-Client
$('#btn4').on('click', function(){
var form = {
name: "jamong",
age: 23
}
$.ajax({
url: " restController",
type: "POST",
data: JSON.stringify(form),
contentType: "application/json; charset=utf-8;",
dataType: "json",
success: function(data){
for(var i=0; i<data.length; i++){
$('#result').append(data[i] + "<br>");
}
},
error: function(){
alert("restController err");
}
});
});
-Server
@RestController
public class AjaxRestController {
@PostMapping("/restController")
public Object restController(@RequestBody Jamong jamong) {
ArrayList<String> arrList = new ArrayList<String>();
for(int i=0; i<5; i++) {
arrList.add(jamong.getName() + i);
}
return arrList;
}
}
-View
<body>
<button id="btn4">restController</button>
<div id="result"></div>
</body>
5. ํ์ผ ์ ๋ก๋๊ฐ AJAX ์ฒ๋ฆฌ
์ง๊ธ๊น์ง AJAX์ ์ ๋ง ๊ธฐ๋ณธ์ ์ธ๊ฑด ๋ค ์ค๋ช ํ๊ฒ๊ฐ๋ค.
๋ฐ์ดํฐ ํํ๋ง ์ ๋ง์ถฐ์ ๋๊ฒจ์ฃผ๊ณ , DB์ ์ ์ํ๋ , API์ฐ๋์ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ , ์ฒ๋ฆฌ๋ก์ง๋ง ์ ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋๋ค.
์ด์ AJAX๋ก ๋ญ๋ ์ง ๋ค ํ ์ ์์๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์ง๋ง.... ํผ์ input type์ด file๋ก ๋์ด์๋ ํ์ผ๋ค์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ์ง?๋ผ๋ ์๋ฌธ์ด ์๊ธธ ๊ฒ์ด๋ค.
์๋์ ๊ฐ์ด ์ ๋ฐ๋ผํ๋ฉด ๋๋ค.
ํ์๋ ํ์ผ ์ ํจ์ฑ๊ฒ์ฌ๋ ์ ๋ก๋ํ๋ ์์ ์ ํ์ง์์๋ค. ๋ฐ์ดํฐ๊ฐ ๋์ด๊ฐ๊ณ ๋ฐ์์ ธ์ค๋ ๊ฒ๋ง ํ์ธํ๊ธฐ ์ํด ํ์ผ ์ด๋ฆ๋ง ์ถ๋ ฅํ๋๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ค.
ํ์ผ์ ๋ฐ์์ค AjaxFile Dto ํด๋์ค
public class AjaxFile {
List<MultipartFile> images;
public List<MultipartFile> getImages() {
return images;
}
public void setImages(List<MultipartFile> images) {
this.images = images;
}
}
ํ์ผ ์ ๋ก๋๋ฅผ ์ํด maven ์ถ๊ฐ pom.xml
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
servlet-context.xml
<!-- file Upload -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- ํ์ผ ์ต๋ 50MB -->
<beans:property name="maxUploadSize" value="52428800"/>
</beans:bean>
-Client
$('#btn5').on('click', function(){
var form = new FormData($('#frm')[0]);
$.ajax({
url: "file",
type: "POST",
data: form,
contentType: false,
processData: false,
success: function(data){
for(var i=0; i<data.length; i++){
$('#result').append(data[i] + '<br>')
}
},
error: function(){
alert("file err");
}
});
});
-Server
@RequestMapping(value="/file", method=RequestMethod.POST)
@ResponseBody
public Object file(AjaxFile file) {
List<MultipartFile> list = file.getImages();
ArrayList<String> fileNameList = new ArrayList<String>();
for(MultipartFile mf : list) {
fileNameList.add(mf.getOriginalFilename());
}
return fileNameList;
}
-View
<body>
<form id="frm" enctype="multipart/form-data">
<input multiple="multiple" type="file" id="images" name="images">
</form>
<button id="btn5">file</button>
<div id="result"></div>
</body>
ํ์์ ์๊ฐ์ผ๋ก ์ด์ ๋๋ง ์๊ณ ์๋ค๋ฉด, Ajax์ฒ๋ฆฌํ๋๋ฐ ํฌ๊ฒ ๋ฌธ์ ๊ฐ ์์๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ค.
AJAX์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ์์๋ดค๊ณ , DB ํน์ API๋ฅผ ์ฐ๋ํ์ฌ AJAX ์ค์ ํธ์ ์ฌ๋ฆด ๊ณํ์ด๋ค.
๋;
๋๊ธ