RESTful сервисы в AngularJS. Использование сервисов $http, $resource для REST вызовов
Пример использования RESTful сервисов в AngularJS. Использование сервисов $http, $resource для REST вызовов.
Обзор приложения Spring MVC + AngularJS + Bootstrap + HTML5
Используемые технологии и библиотеки
- Spring MVC 4.2.4.Release
- AngularJS 1.5.0
- IntelliJ IDEA 15.0.2
1. Описание задачи
Рассмотреть как применяются RESTful сервисы в AngularJS. Как применить сервисы $http и $resource для REST вызовов.
2. Структура проекта
Структура проекта не поменялась с предыдущей статьи. Рассматриваемая тема находится в представлении httpresource.jsp. Так же в статье будет использован RestPostsModel класс из пакета rest/model. Этот класс будет использован для преобразования JSON ответа сервера.
3. Описание $http и $resource
$http — это сервис, который используется для вызова REST сервисов. $http сервис это основа Angular для коммуникации с удаленным HTTP сервером через XMLHttpRequest объект или через JSONP. $http сервис это функция, которая принимает на вход только один аргумент — объект конфигурации, который используется для создания HTTP запроса и возврата ответа.
1 2 3 4 5 6 7 8 9 10 11 |
// Simple GET request example: $http({ method: 'GET', url: '/someUrl' }).then(function successCallback(response) { // this callback will be called asynchronously // when the response is available }, function errorCallback(response) { // called asynchronously if an error occurs // or server returns response with an error status. }); |
Объект ответа будет обладать следующими свойствами:
- data – {string|Object} – тело ответа, которое будет преобразовано с помощью преобразовывающих функций.
- status – {number} – код статуса HTTP ответа.
- headers – {function([headerName])} – Header getter функции.
- config – {Object} – конфигурационный объект, который используется для создания запроса.
- statusText – {string} – HTTP статус текст ответа.
$resource используется для create, read, update, delete операций (CRUD).
4. Применение $http, $resource
Полный код для AngularJS описан ниже. Далее для более легкого понимания он будет рассмотрен по частям.
1 2 3 4 5 6 7 8 9 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 |
<script> var app = angular.module('myApp', ['ngResource']); app.controller('JSONController', function($scope, $http) { $http.get('/rest/posts/13'). success(function(data, status, headers, config) { $scope.post = data; console.log(data); }). error(function($data, status, $headers, config) { alert("error getting data"); }) //test JSON as post var post = { userId: 'test', id : '1', title : 'test', body: 'test' }; //$http $http.post('/rest/savePost', post). success(function(data, status, headers, config) { $scope.post = data; console.log(data); }). error(function(data, status, headers, config) { alert("error post data"); }); }); //$resource //$resource configuration object is Posts used for CRUD app.factory("Posts", function($resource) { return $resource("/rest/delPosts/:id"); }); //$resource //get post id mapped to @RestTemplateController getRestPostsById app.controller("PostQueryByIdController", function($scope, Posts) { Posts.get({ id: 1 }, function(data) { $scope.posts = data; console.log(data); }); }); //$resource //delete a post mapped to @RestTemplateController deletePostByIDAngular app.controller("DeletePostByIdController", function($scope, Posts) { Posts.delete({ id: 4 }) }); </script> |
Здесь используется Spring MVC контроллер RestTemplateController, который описывается в Работа с JSON и XML (преобразование объектов) в Spring MVC. Формирование ответа и обработка запроса. Так же может быть интересна предыдущая часть, в которой немного рассматривается работа $http сервиса.
Сначала мы создаем модуль в зависимость которого добавляется модуль ngResource. Далее задается контроллер в котором описаны GET и POST методы. Эти запросы будут перехватываться Spring MVC контроллером с соответствующим @RequestMapping.
В модуле описан объект post, который соответствует по структуре java классу RestPostsModel.
1 2 3 4 5 6 7 |
//test JSON as post var post = { userId: 'test', id : '1', title : 'test', body: 'test' }; |
RestPostsModel:
1 2 3 4 5 6 7 8 9 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 |
package ru.javastudy.mvcHtml5Angular.mvc.rest.model; /** * Created for JavaStudy.ru on 28.02.2016. */ public class RestPostsModel { private String userId; private String id; private String title; private String body; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } } |
Рассмотрим описание контроллера JSONController по частям.
1 2 3 4 5 6 7 8 9 |
app.controller('JSONController', function($scope, $http) { $http.get('/rest/posts/13'). success(function(data, status, headers, config) { $scope.post = data; console.log(data); }). error(function($data, status, $headers, config) { alert("error getting data"); }); |
Создаем контроллер и передаем в функцию сервис $http. Он использует метод get() с указанием URL. Этот URL будет обработан Spring MVC контроллером и вернет ответ, который будет записан в объект post.
1 2 3 4 5 6 7 8 9 10 |
@RequestMapping(value = "/rest/posts/{param}", method = RequestMethod.GET) public RestPostsModel getRestPostsById(@PathVariable("param") String param) { System.out.println("RestTemplateController getRestPostsById is called"); ResponseEntity<RestPostsModel> response = restTemplate.getForEntity( EXTERNAL_REST_URL +"/posts/" + param, RestPostsModel.class ); return response.getBody(); } |
Далее рассматривается использование метода post.
1 2 3 4 5 6 7 8 9 10 |
//$http $http.post('/rest/savePost', post). success(function(data, status, headers, config) { $scope.post = data; console.log(data); }). error(function(data, status, headers, config) { alert("error post data"); }); }); |
Всё аналогично. Этот запрос обработает mvc контроллер с помощью метода savePost:
1 2 3 4 5 6 7 8 9 10 11 |
//JSON SAVES a post. Uses in angularjs/httpresource.jsp @RequestMapping(value = "/rest/savePost", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void savePost(@RequestBody RestPostsModel postJSON) { System.out.println("savePost postJSON.getUserId(): " + postJSON.getUserId()); System.out.println("savePost postJSON.getTitle(): " + postJSON.getTitle()); System.out.println("savePost postJSON.getId(): " + postJSON.getId()); System.out.println("savePost postJSON.getBody(): " + postJSON.getBody()); System.out.println("@RestTemplateControllerExample savePost is called"); } |
При конфигурации объекта $resource сразу буде возвращен URL, который вызовет метод удаления объекта post с id, который указывается с помощью параметра (в нашем случае id:1).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//$resource //$resource configuration object is Posts used for CRUD app.factory("Posts", function($resource) { return $resource("/rest/delPosts/:id"); }); //$resource //get post id mapped to @RestTemplateController getRestPostsById app.controller("PostQueryByIdController", function($scope, Posts) { Posts.get({ id: 1 }, function(data) { $scope.posts = data; console.log(data); }); }); |
Так же был создан второй контроллер, который использует HTTP метод delete.
1 2 3 4 5 |
//$resource //delete a post mapped to @RestTemplateController deletePostByIDAngular app.controller("DeletePostByIdController", function($scope, Posts) { Posts.delete({ id: 4 }) }); |
5. Запуск приложения
В представлении результаты будут выводиться с помощью следующего кода.
1 2 3 4 5 6 7 8 9 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 |
<h3>AngularJS routing</h3> <div ng-app="myApp"> <div ng-controller="JSONController"> <table class="table"> <tr> <td><b>userid</b></td> <td>{{ post.userId }}</td> </tr> <tr> <td><b>id</b></td> <td>{{ post.id }}</td> </tr> <tr> <td><b>title</b></td> <td>{{ post.title}}</td> </tr> <tr> <td><b>body</b></td> <td>{{ post.body }}</td> </tr> </table> <!-- change link to $http.get('/rest/posts/') in controller and get 100 posts! <table class="table" ng-repeat="p in post"> <tr><td><b>userid</b></td><td>{{ p.userId }}</td></tr> </table> --> <div ng-controller="PostQueryByIdController"></div> <div ng-controller="DeletePostByIdController"> </div> </div> </div> |
Как видите в конце вызываются два angular контроллера. В результате последовательного вызова их методов в IDE консоли мы увидим последовательность вызова Spring MVC методов.
1 2 3 4 5 6 7 8 |
savePost postJSON.getUserId(): test savePost postJSON.getTitle(): test savePost postJSON.getId(): 1 savePost postJSON.getBody(): test @RestTemplateControllerExample savePost is called RestTemplateController getRestPostsById is called @RestTemplateControllerExample deletePostByID is called @RestTemplateControllerExample deletePostByID is called |
На экране это выглядит так.
Исходные коды
MVC_AngularJS_Html5 full project — полный проект Spring MVC + AngularJS + Bootstrap + HTML5.