Сегодня я хочу продемонстрировать, как интегрировать AJAX в приложение Spring MVC. Я собираюсь использовать JQuery на стороне клиента для отправки запросов и получения ответов. Этот учебник будет основан на одном из моих предыдущих учебников о сервисах Spring MVC и REST. В этой статье вы узнаете, как сделать веб-приложение более интерактивным с помощью асинхронных запросов.
Препараты
Мне нужно изменить класс SmartphoneController, удалив методы, которые больше не требуются. Это первый шаг интеграции AJAX.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
//imports are omitted @Controller @RequestMapping (value= "/smartphones" ) public class SmartphoneController { @Autowired private SmartphoneService smartphoneService; @RequestMapping (value= "/create" , method=RequestMethod.GET) public ModelAndView createSmartphonePage() { ModelAndView mav = new ModelAndView( "phones/new-phone" ); mav.addObject( "sPhone" , new Smartphone()); return mav; } @RequestMapping (value= "/create" , method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public Smartphone createSmartphone( @RequestBody Smartphone smartphone) { return smartphoneService.create(smartphone); } @RequestMapping (value= "/edit/{id}" , method=RequestMethod.GET) public ModelAndView editSmartphonePage( @PathVariable int id) { ModelAndView mav = new ModelAndView( "phones/edit-phone" ); Smartphone smartphone = smartphoneService.get(id); mav.addObject( "sPhone" , smartphone); return mav; } @RequestMapping (value= "/edit/{id}" , method=RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public Smartphone editSmartphone( @PathVariable int id, @RequestBody Smartphone smartphone) { smartphone.setId(id); return smartphoneService.update(smartphone); } @RequestMapping (value= "/delete/{id}" , method=RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public Smartphone deleteSmartphone( @PathVariable int id) { return smartphoneService.delete(id); } @RequestMapping (value= "" , method=RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public List< Smartphone > allPhones() { return smartphoneService.getAll(); } @RequestMapping (value= "" , method=RequestMethod.GET) public ModelAndView allPhonesPage() { ModelAndView mav = new ModelAndView( "phones/all-phones" ); List< Smartphone > smartphones = new ArrayList< Smartphone >(); smartphones.addAll(allPhones()); mav.addObject( "smartphones" , smartphones); return mav; } } |
Вы можете сравнить новую версию SmartphoneController с более старой. Методы, которые обрабатывают запросы PUT, POST, DELETE и возвращают объекты ModelAndView, были удалены. Методы были удалены, потому что вызовы AJAX могут быть адресованы напрямую методам REST. Теперь контроллер содержит только два типа методов:
- Первый тип направляет пользователя на страницы, где могут выполняться операции CRUD.
- Второй тип выполняет операции CRUD (методы REST)
Сторона клиента
Использование AJAX подразумевает много кода на стороне клиента веб-приложения. В этом разделе я продемонстрирую основы, которые помогут вам понять, какие шаги необходимо предпринять для реализации вызовов AJAX. Рассмотрим случай с созданием нового смартфона в приложении.
Прежде всего мне нужно добавить библиотеку JQuery на страницу HTML:
1
|
<script src= "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script> |
У основной части HTML есть одно ценное обновление — расширение атрибута действия формы было изменено на .json
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<div id= "container" > <h1>Create new Smartphone</h1> <div> <p>Here you can create new Smartphone:</p> <div id= "sPhoneFromResponse" ></div> </div> <form:form id= "newSmartphoneForm" action= "${pageContext.request.contextPath}/smartphones/create.json" commandname= "sPhone" > <table> <tbody> <tr> <td>Producer:</td> <td> <form:select path= "producer" > <form:option value= "NOKIA" >Nokia</form:option> <form:option selected= "selected" value= "IPHONE" >iPhone</form:option> <form:option value= "HTC" >HTC</form:option> <form:option value= "SAMSUNG" >Samsung</form:option> </form:select> </td> </tr> <tr> <td>Model:</td> <td><form:input path= "model" ></form:input></td> </tr> <tr> <td>Price:</td> <td><form:input path= "price" ></form:input></td> </tr> <tr> <td><input value= "Create" type= "submit" ></td> <td></td> </tr> </tbody> </table> </form:form> <a href= "${pageContext.request.contextPath}/index.html" >Home page</a> </div> |
А теперь, дамы и господа, я хочу представить фрагмент кода JQuery для создания нового смартфона:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
$(document).ready(function() { $( '#newSmartphoneForm' ).submit(function(event) { var producer = $( '#producer' ).val(); var model = $( '#model' ).val(); var price = $( '#price' ).val(); var json = { "producer" : producer, "model" : model, "price" : price}; $.ajax({ url: $( "#newSmartphoneForm" ).attr( "action" ), data: JSON.stringify(json), type: "POST" , beforeSend: function(xhr) { xhr.setRequestHeader( "Accept" , "application/json" ); xhr.setRequestHeader( "Content-Type" , "application/json" ); }, success: function(smartphone) { var respContent = "" ; respContent += "<span class=" success ">Smartphone was created: [" ; respContent += smartphone.producer + " : " ; respContent += smartphone.model + " : " ; respContent += smartphone.price + "]</span>" ; $( "#sPhoneFromResponse" ).html(respContent); } }); event.preventDefault(); }); }); |
Я не собираюсь останавливаться на этом коде и объяснять его подробно, потому что вы можете прочитать об AJAX и JQuery на официальном сайте .
Краткое объяснение: когда кто-то хочет отправить форму с указанным идентификатором, все поля формы назначаются соответствующим переменным. После этого создается новый документ JSON на основе переменных поля формы. Затем выполняется вызов AJAX. Он направлен на URL, указанный в атрибуте действия тега form. JSON используется как данные, которые необходимо обработать. Тип запроса — POST (он может варьироваться в зависимости от операции, например, для обновления он будет иметь значение PUT). В функции beforeSend я явно указываю необходимые заголовки для формата JSON. В конце я формулирую ответ и вставляю его в DOM.
Вот и все, что связано с созданием смартфона. Обновление смартфона аналогичное, просто нужно изменить тип запроса.
Теперь посмотрим, как работать с запросами типа DELETE. Как и раньше, мне нужно изменить расширение URL на .json
1
|
<a href= "${pageContext.request.contextPath}/smartphones/delete/${sPhone.id}.json" >Delete</a> |
Код JQuery для операции DELETE будет немного отличаться по сравнению с POST и PUT.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
$(document).ready(function() { var deleteLink = $( "a:contains('Delete')" ); $(deleteLink).click(function(event) { $.ajax({ url: $(event.target).attr( "href" ), type: "DELETE" , beforeSend: function(xhr) { xhr.setRequestHeader( "Accept" , "application/json" ); xhr.setRequestHeader( "Content-Type" , "application/json" ); }, success: function(smartphone) { var respContent = "" ; var rowToDelete = $(event.target).closest( "tr" ); rowToDelete.remove(); respContent += "<span class=" success ">Smartphone was deleted: [" ; respContent += smartphone.producer + " : " ; respContent += smartphone.model + " : " ; respContent += smartphone.price + "]</span>" ; $( "#sPhoneFromResponse" ).html(respContent); } }); event.preventDefault(); }); }); |
Первым отличием является селектор для элемента. В случае с DELETE я хочу работать со ссылками, но не с формами. Тип вызова AJAX изменяется на значение DELETE. Нет никаких данных, которые отправляются с запросом. И в конце я удаляю строку со смартфоном, которую нужно удалить.
Резюме
Я надеюсь, что этот краткий обзор AJAX будет полезен для вас. Существует множество функций, которые можно реализовать с помощью AJAX в любом веб-приложении, поэтому не забывайте об этом удобном способе связи с сервером. Вы можете найти это приложение на GitHub .